Added map icon for warbands. Added /warband command.
parent
e54d6f0786
commit
f758ef7c31
@ -0,0 +1,151 @@
|
||||
package com.zivilon.cinder_loe.command;
|
||||
|
||||
import com.zivilon.cinder_loe.world.event.Warband;
|
||||
import com.zivilon.cinder_loe.world.event.WarbandFaction;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
|
||||
import lotr.common.world.map.LOTRWaypoint;
|
||||
|
||||
import com.zivilon.cinder_loe.character.CharacterRoleAPI;
|
||||
import com.zivilon.cinder_loe.util.Utilities;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class CommandWarband extends CommandBase {
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "warband";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandUsage(ICommandSender sender) {
|
||||
return "/warband <summon/reset> [faction_name] [waypoint] [x] [z]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRequiredPermissionLevel() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) {
|
||||
if(!validate_args(args)) {
|
||||
sender.addChatMessage(new ChatComponentText("Incorrect arguments. Usage: " + getCommandUsage(sender)));
|
||||
return;
|
||||
}
|
||||
|
||||
String action = args[0];
|
||||
System.out.println("Checking arg " + action);
|
||||
switch (action) {
|
||||
case "reset":
|
||||
reset_warband();
|
||||
sender.addChatMessage(new ChatComponentText("Warband timer has been reset. A new warband may now spawn."));
|
||||
return;
|
||||
case "list":
|
||||
list_warbands(sender);
|
||||
return;
|
||||
case "summon":
|
||||
summon_warband(sender, args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void summon_warband(ICommandSender sender, String[] args) {
|
||||
WarbandFaction faction = WarbandFaction.get_warband_by_name(args[1]);
|
||||
LOTRWaypoint waypoint = null;
|
||||
String waypoint_name = null;
|
||||
int x = 0;
|
||||
int z = 0;
|
||||
|
||||
if (args.length == 2) {
|
||||
if (!(sender instanceof EntityPlayer)) {
|
||||
System.out.println("Console must specify location to summon warband. Options:");
|
||||
System.out.println("/warband <summon> <faction_name> <waypoint>");
|
||||
System.out.println("/warband <summon> <faction_name> <x> <z>");
|
||||
return;
|
||||
}
|
||||
EntityPlayer player = (EntityPlayer)sender;
|
||||
x = (int)player.posX;
|
||||
z = (int)player.posZ;
|
||||
Warband.initialize_warband(faction, x, z);
|
||||
}
|
||||
|
||||
if (args.length == 3) {
|
||||
waypoint_name = args[2];
|
||||
waypoint = LOTRWaypoint.waypointForName(waypoint_name);
|
||||
if (waypoint == null) {
|
||||
sender.addChatMessage(new ChatComponentText("Invalid waypoint \"" + waypoint_name + "\""));
|
||||
}
|
||||
Warband.initialize_warband(faction, waypoint);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length == 4) {
|
||||
try {
|
||||
x = Integer.parseInt(args[2]);
|
||||
z = Integer.parseInt(args[3]);
|
||||
} catch (Exception e) {
|
||||
sender.addChatMessage(new ChatComponentText("Invalid coordinates provided"));
|
||||
return;
|
||||
}
|
||||
Warband.initialize_warband(faction, x, z);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length > 4) {
|
||||
try {
|
||||
x = Integer.parseInt(args[3]);
|
||||
z = Integer.parseInt(args[4]);
|
||||
} catch (Exception e) {
|
||||
sender.addChatMessage(new ChatComponentText("Invalid coordinates provided"));
|
||||
return;
|
||||
}
|
||||
waypoint_name = args[2];
|
||||
waypoint = LOTRWaypoint.waypointForName(waypoint_name);
|
||||
if (waypoint == null) {
|
||||
sender.addChatMessage(new ChatComponentText("Invalid waypoint \"" + waypoint_name + "\""));
|
||||
return;
|
||||
}
|
||||
Warband.initialize_warband(faction, waypoint, x, z);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean validate_args(String[] args) {
|
||||
System.out.println("Validating...");
|
||||
if (args.length < 1) return false;
|
||||
String action = "";
|
||||
System.out.println("Checking arg \"" + args[0] + "\"");
|
||||
if (args[0].equals("summon") || args[0].equals("reset") || args[0].equals("list")) {
|
||||
action = args[0];
|
||||
} else {
|
||||
System.out.println("Failed test 1");
|
||||
return false;
|
||||
}
|
||||
if (action.equals("summon")) {
|
||||
if (args.length < 2) {
|
||||
System.out.println("Failed test 2");
|
||||
return false;
|
||||
}
|
||||
WarbandFaction faction = WarbandFaction.get_warband_by_name(args[1]);
|
||||
if (faction == null) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void reset_warband() {
|
||||
// Set last warband to have happened 10 hours ago, thus allowing new warband
|
||||
Warband.last_warband_timestamp = System.currentTimeMillis() / 1000L - (60*60*10);
|
||||
}
|
||||
public static void list_warbands(ICommandSender sender) {
|
||||
sender.addChatMessage(new ChatComponentText("List of valid warbands:"));
|
||||
for (WarbandFaction faction : WarbandFaction.values()) {
|
||||
sender.addChatMessage(new ChatComponentText("- " + faction.name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.zivilon.cinder_loe.mixins;
|
||||
|
||||
import com.zivilon.cinder_loe.util.IEntityLivingBase;
|
||||
|
||||
import lotr.common.entity.npc.LOTREntityOrc;
|
||||
import lotr.common.entity.ai.LOTREntityAIOrcSkirmish;
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
import org.spongepowered.asm.mixin.injection.*;
|
||||
import org.spongepowered.asm.mixin.injection.callback.*;
|
||||
|
||||
@Mixin(LOTREntityAIOrcSkirmish.class)
|
||||
public class MixinLOTREntityAIOrcSkirmish {
|
||||
|
||||
@Overwrite(remap = false)
|
||||
private boolean canOrcSkirmish(EntityLivingBase entity) {
|
||||
if (entity instanceof LOTREntityOrc) {
|
||||
LOTREntityOrc orc = (LOTREntityOrc)entity;
|
||||
if (((IEntityLivingBase)orc).get_warband_uuid() != null) return false;
|
||||
return (!orc.isTrader() && !orc.hiredNPCInfo.isActive && orc.ridingEntity == null && orc.canOrcSkirmish());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,139 @@
|
||||
package com.zivilon.cinder_loe.mixins;
|
||||
|
||||
import com.zivilon.cinder_loe.world.event.Warband;
|
||||
import com.zivilon.cinder_loe.world.event.WarbandTracker;
|
||||
import com.zivilon.cinder_loe.world.event.WarbandLocationInfo;
|
||||
|
||||
import lotr.client.gui.LOTRGuiMap;
|
||||
import lotr.client.gui.LOTRGuiMenuBase;
|
||||
import lotr.client.LOTRClientProxy;
|
||||
import lotr.common.LOTRLevelData;
|
||||
import lotr.common.fac.LOTRFaction;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.StatCollector;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
import org.spongepowered.asm.mixin.injection.*;
|
||||
import org.spongepowered.asm.mixin.injection.callback.*;
|
||||
|
||||
|
||||
@Mixin(LOTRGuiMap.class)
|
||||
public abstract class MixinLOTRGuiMap extends LOTRGuiMenuBase {
|
||||
private static Map<UUID, WarbandLocationInfo> warband_locations = WarbandTracker.locations;
|
||||
private static ResourceLocation WARBAND_ICON = new ResourceLocation("cinderloe", "textures/gui/alignment.png");
|
||||
|
||||
@Shadow(remap = false)
|
||||
private boolean loadingConquestGrid;
|
||||
@Shadow(remap = false)
|
||||
private boolean hasOverlay;
|
||||
@Shadow(remap = false)
|
||||
private static int mapXMin;
|
||||
@Shadow(remap = false)
|
||||
private static int mapXMax;
|
||||
@Shadow(remap = false)
|
||||
private static int mapYMin;
|
||||
@Shadow(remap = false)
|
||||
private static int mapYMax;
|
||||
@Shadow(remap = false)
|
||||
private void drawFancyRect(int x1, int y1, int x2, int y2) {}
|
||||
@Shadow(remap = false)
|
||||
public float[] transformCoords(float x, float z) { return null;}
|
||||
|
||||
@Inject(method = "func_73863_a", at = @At("HEAD"), remap = false)
|
||||
public void inject_head(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) {
|
||||
System.out.println("[MixinLOTRGuiMap] Inject at HEAD");
|
||||
}
|
||||
@Inject(method = "func_73863_a", at = @At( value = "INVOKE", target = "renderPlayers(II)V", shift = At.Shift.AFTER), remap = false)
|
||||
public void inject_render_warbands(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) {
|
||||
System.out.println("[MixinLOTRGuiMap] Running wrapper");
|
||||
render_warbands(mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Dynamic
|
||||
private void render_warbands(int cursor_x, int cursor_y) {
|
||||
System.out.println("[MixinLOTRGuiMap] Rendering warband icon");
|
||||
String mouse_over_warband_name = null;
|
||||
double mouse_over_warband_x = 0.0D;
|
||||
double mouse_over_warband_y = 0.0D;
|
||||
double shortest_distance_to_cursor = Double.MAX_VALUE;
|
||||
int icon_width_half = 4;
|
||||
for (Map.Entry<UUID, WarbandLocationInfo> entry : warband_locations.entrySet()) {
|
||||
System.out.println("[MixinLOTRGuiMap] Iterated");
|
||||
WarbandLocationInfo info = entry.getValue();
|
||||
Warband warband = info.warband;
|
||||
String warband_name = warband.faction.warband_name;
|
||||
float[] pos = transformCoords((float)info.x, (float)info.z);
|
||||
int map_x = Math.round(pos[0]);
|
||||
int map_y = Math.round(pos[1]);
|
||||
|
||||
double distance_to_icon = render_warband_icon(warband, map_x, map_y, cursor_x, cursor_y);
|
||||
if (distance_to_icon <= (icon_width_half + 3)) {
|
||||
if (distance_to_icon <= shortest_distance_to_cursor) {
|
||||
mouse_over_warband_name = StatCollector.translateToLocal(warband_name);
|
||||
mouse_over_warband_x = map_x;
|
||||
mouse_over_warband_y = map_y;
|
||||
shortest_distance_to_cursor = distance_to_icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mouse_over_warband_name != null && !this.hasOverlay && !this.loadingConquestGrid) {
|
||||
int name_width = this.mc.fontRenderer.getStringWidth(mouse_over_warband_name);
|
||||
int name_height = this.mc.fontRenderer.FONT_HEIGHT;
|
||||
int namebox_x = (int)Math.round(mouse_over_warband_x);
|
||||
int namebox_y = (int)Math.round(mouse_over_warband_y);
|
||||
namebox_y += icon_width_half + 3;
|
||||
int border = 3;
|
||||
int namebox_width = name_width + border * 2;
|
||||
namebox_x -= namebox_width / 2;
|
||||
int namebox_height = name_height + border * 2;
|
||||
int map_border = 2;
|
||||
namebox_x = Math.max(namebox_x, mapXMin + map_border);
|
||||
namebox_x = Math.min(namebox_x, mapXMax - map_border - namebox_width);
|
||||
namebox_y = Math.max(namebox_y, mapYMin + map_border);
|
||||
namebox_y = Math.min(namebox_y, mapYMax - map_border - namebox_height);
|
||||
GL11.glTranslatef(0.0F, 0.0F, 300.0F);
|
||||
drawFancyRect(namebox_x, namebox_y, namebox_x + namebox_width, namebox_y + namebox_height);
|
||||
this.mc.fontRenderer.drawString(mouse_over_warband_name, namebox_x + border, namebox_y + border, 16777215);
|
||||
GL11.glTranslatef(0.0F, 0.0F, -300.0F);
|
||||
}
|
||||
}
|
||||
|
||||
@Dynamic
|
||||
private double render_warband_icon(Warband warband, double map_x, double map_y, int mouse_x, int mouse_y) {
|
||||
int icon_half = 4;
|
||||
int icon_border = icon_half + 1;
|
||||
|
||||
map_x = Math.max(mapXMin + icon_border, Math.min(mapXMax - icon_border - 1, map_x));
|
||||
map_y = Math.max(mapYMin + icon_border, Math.min(mapYMax - icon_border - 1, map_y));
|
||||
|
||||
// Determine ally/enemy icon
|
||||
LOTRFaction faction = warband.faction.faction;
|
||||
float alignment = LOTRLevelData.getData(mc.thePlayer).getAlignment(faction);
|
||||
boolean is_ally = alignment > 0.0F;
|
||||
|
||||
load_warband_icon(is_ally, (int) map_x, (int) map_y);
|
||||
|
||||
// Return mouse distance to icon
|
||||
double dx = map_x - mouse_x;
|
||||
double dy = map_y - mouse_y;
|
||||
return Math.hypot(dx, dy);
|
||||
}
|
||||
|
||||
|
||||
@Dynamic
|
||||
private void load_warband_icon(boolean ally, int x, int y) {
|
||||
System.out.println("[MixinLOTRGuiMap] Loading warband icon: " + (ally ? "ally" : "enemy"));
|
||||
mc.getTextureManager().bindTexture(LOTRClientProxy.alignmentTexture);
|
||||
GL11.glColor4f(1F, 1F, 1F, 1F);
|
||||
int variant = ally ? 16 : 0;
|
||||
drawTexturedModalRect(x - 8, y - 8, variant, 228, 16, 16);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.zivilon.cinder_loe.network;
|
||||
|
||||
import com.zivilon.cinder_loe.network.PacketWarbandLocations.Handler;
|
||||
import lotr.common.network.LOTRPacketHandler;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
|
||||
public class PacketRegistration {
|
||||
public static void register() {
|
||||
int id = 200;
|
||||
LOTRPacketHandler.networkWrapper.registerMessage(PacketWarbandLocations.Handler.class, PacketWarbandLocations.class, id++, Side.CLIENT);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,115 @@
|
||||
package com.zivilon.cinder_loe.network;
|
||||
|
||||
import com.zivilon.cinder_loe.world.event.Warband;
|
||||
import com.zivilon.cinder_loe.world.event.WarbandFaction;
|
||||
import com.zivilon.cinder_loe.world.event.WarbandLocationInfo;
|
||||
import com.zivilon.cinder_loe.world.event.WarbandTracker;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.network.simpleimpl.IMessage;
|
||||
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
|
||||
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import lotr.common.LOTRMod;
|
||||
import lotr.common.network.LOTRPacketHandler;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class PacketWarbandLocations implements IMessage {
|
||||
public List<WarbandLocationInfo> locations = WarbandTracker.get_all();
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
buf.writeShort(locations.size());
|
||||
for (WarbandLocationInfo loc : locations) {
|
||||
buf.writeLong(loc.warband.warband_uuid.getMostSignificantBits());
|
||||
buf.writeLong(loc.warband.warband_uuid.getLeastSignificantBits());
|
||||
buf.writeDouble(loc.x);
|
||||
buf.writeDouble(loc.z);
|
||||
PacketBuffer packet = new PacketBuffer(buf);
|
||||
write_string_to_buffer(packet, loc.warband.faction.name());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
locations.clear();
|
||||
int count = buf.readShort();
|
||||
for (int i = 0; i < count; i++) {
|
||||
long msb = buf.readLong();
|
||||
long lsb = buf.readLong();
|
||||
UUID uuid = new UUID(msb, lsb);
|
||||
double x = buf.readDouble();
|
||||
double z = buf.readDouble();
|
||||
|
||||
PacketBuffer packet = new PacketBuffer(buf);
|
||||
String faction_name = read_string_from_buffer(packet, Short.MAX_VALUE);
|
||||
|
||||
WarbandFaction faction = WarbandFaction.get_warband_by_name(faction_name);
|
||||
|
||||
Warband dummy = new Warband();
|
||||
dummy.warband_uuid = uuid;
|
||||
dummy.faction = faction;
|
||||
dummy.x = (int) x;
|
||||
dummy.z = (int) z;
|
||||
locations.add(new WarbandLocationInfo(dummy, x, z));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Handler implements IMessageHandler<PacketWarbandLocations, IMessage> {
|
||||
@Override
|
||||
public IMessage onMessage(PacketWarbandLocations message, MessageContext ctx) {
|
||||
if (ctx.side.isServer()) {
|
||||
System.out.println("[PacketWarbandLocations] WARNING: Client tried to update locations on server!");
|
||||
return null;
|
||||
}
|
||||
|
||||
WarbandTracker.clear_locations();
|
||||
for (WarbandLocationInfo info : message.locations) {
|
||||
WarbandTracker.add(info);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void send_warband_locations(World world) {
|
||||
for (int i = 0; i < world.playerEntities.size(); i++) {
|
||||
EntityPlayer entityplayer = (EntityPlayer)world.playerEntities.get(i);
|
||||
send_location(entityplayer, world);
|
||||
}
|
||||
}
|
||||
|
||||
public static void send_location(EntityPlayer player, World world) {
|
||||
PacketWarbandLocations locations = new PacketWarbandLocations();
|
||||
LOTRPacketHandler.networkWrapper.sendTo((IMessage)locations, (EntityPlayerMP)player);
|
||||
}
|
||||
public static void write_string_to_buffer(PacketBuffer buffer, String string) {
|
||||
try {
|
||||
buffer.writeStringToBuffer(string);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("[PacketWarbandLocations] WARNING: Failed to write warband faction", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String read_string_from_buffer(PacketBuffer buffer, int max_length) {
|
||||
try {
|
||||
return buffer.readStringFromBuffer(max_length);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("[PacketWarbandLocations] WARNING: Failed to read warband faction", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.zivilon.cinder_loe.world.event;
|
||||
|
||||
public class WarbandLocationInfo {
|
||||
public Warband warband;
|
||||
public double x;
|
||||
public double z;
|
||||
|
||||
public WarbandLocationInfo(Warband warband, double x, double z) {
|
||||
this.warband = warband;
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.zivilon.cinder_loe.world.event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class WarbandTracker {
|
||||
public static Map<UUID, WarbandLocationInfo> locations = new HashMap<>();
|
||||
|
||||
public static void clear_locations() {
|
||||
locations.clear();
|
||||
}
|
||||
|
||||
public static void add(Warband warband) {
|
||||
locations.put(warband.warband_uuid, new WarbandLocationInfo(warband, warband.x, warband.z));
|
||||
}
|
||||
public static void add(WarbandLocationInfo info) {
|
||||
locations.put(info.warband.warband_uuid, info);
|
||||
}
|
||||
|
||||
public static void remove(UUID uuid) {
|
||||
locations.remove(uuid);
|
||||
}
|
||||
|
||||
public static List<WarbandLocationInfo> get_all() {
|
||||
return new ArrayList<>(locations.values());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue