import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
-import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
import com.seodisparate.TurnBasedMinecraft.common.Battle;
import com.seodisparate.TurnBasedMinecraft.common.Combatant;
+import com.seodisparate.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleDecision;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketHandler;
+import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
public void turnEnd()
{
- TurnBasedMinecraftMod.currentBattle.setState(Battle.State.DECISION);
+ if(TurnBasedMinecraftMod.currentBattle != null)
+ {
+ TurnBasedMinecraftMod.currentBattle.setState(Battle.State.DECISION);
+ }
timeRemaining.set((int)TurnBasedMinecraftMod.BattleDecisionTime.getSeconds());
setState(MenuState.MAIN_MENU);
}
{
case MAIN_MENU:
info = "What will you do?";
- buttonList.add(new GuiButton(ButtonAction.ATTACK.getValue(), width*2/7 - 40, height - 120, 80, 20, "Attack"));
- buttonList.add(new GuiButton(ButtonAction.DEFEND.getValue(), width*3/7 - 40, height - 120, 80, 20, "Defend"));
- buttonList.add(new GuiButton(ButtonAction.ITEM.getValue(), width*4/7 - 40, height - 120, 80, 20, "Item"));
- buttonList.add(new GuiButton(ButtonAction.FLEE.getValue(), width*5/7 - 40, height - 120, 80, 20, "Flee"));
+ buttonList.add(new GuiButton(ButtonAction.ATTACK.getValue(), width*2/7 - 30, height - 120, 60, 20, "Attack"));
+ buttonList.add(new GuiButton(ButtonAction.DEFEND.getValue(), width*3/7 - 30, height - 120, 60, 20, "Defend"));
+ buttonList.add(new GuiButton(ButtonAction.ITEM.getValue(), width*4/7 - 30, height - 120, 60, 20, "Item"));
+ buttonList.add(new GuiButton(ButtonAction.FLEE.getValue(), width*5/7 - 30, height - 120, 60, 20, "Flee"));
break;
case ATTACK_TARGET:
info = "Who will you attack?";
- int y = 50;
+ int y = 30;
for(Map.Entry<Integer, Combatant> e : TurnBasedMinecraftMod.currentBattle.getSideAEntrySet())
{
if(e.getValue().entity != null)
{
- buttonList.add(new EntitySelectionButton(ButtonAction.ATTACK_TARGET.getValue(), width/4 - 100, y, e.getValue().entity.getName(), e.getKey()));
+ buttonList.add(new EntitySelectionButton(ButtonAction.ATTACK_TARGET.getValue(), width/4 - 60, y, 120, 20, e.getValue().entity.getName(), e.getKey()));
}
else
{
- buttonList.add(new EntitySelectionButton(ButtonAction.ATTACK_TARGET.getValue(), width/4 - 100, y, "Unknown", e.getKey()));
+ buttonList.add(new EntitySelectionButton(ButtonAction.ATTACK_TARGET.getValue(), width/4 - 60, y, 120, 20, "Unknown", e.getKey()));
}
y += 20;
}
- y = 50;
+ y = 30;
for(Map.Entry<Integer, Combatant> e : TurnBasedMinecraftMod.currentBattle.getSideBEntrySet())
{
if(e.getValue().entity != null)
{
- buttonList.add(new EntitySelectionButton(ButtonAction.ATTACK_TARGET.getValue(), width*3/4 - 100, y, e.getValue().entity.getName(), e.getKey()));
+ buttonList.add(new EntitySelectionButton(ButtonAction.ATTACK_TARGET.getValue(), width*3/4 - 60, y, 120, 20, e.getValue().entity.getName(), e.getKey()));
}
else
{
- buttonList.add(new EntitySelectionButton(ButtonAction.ATTACK_TARGET.getValue(), width*3/4 - 100, y, "Unknown", e.getKey()));
+ buttonList.add(new EntitySelectionButton(ButtonAction.ATTACK_TARGET.getValue(), width*3/4 - 60, y, 120, 20, "Unknown", e.getKey()));
}
y += 20;
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks)
{
+ if(TurnBasedMinecraftMod.currentBattle == null)
+ {
+ drawHoveringText("Waiting...", width / 2 - 50, height / 2);
+ return;
+ }
if(TurnBasedMinecraftMod.currentBattle.getState() == Battle.State.DECISION && timeRemaining.get() > 0)
{
long nextInstant = System.nanoTime();
super.drawScreen(mouseX, mouseY, partialTicks);
- drawHoveringText(info, width / 2 - 50, height - 50);
+ String timeRemainingString = "Time remaining: ";
+ int timeRemainingInt = timeRemaining.get();
+ if(timeRemainingInt > 8)
+ {
+ timeRemainingString += "\u00A7a";
+ }
+ else if(timeRemainingInt > 4)
+ {
+ timeRemainingString += "\u00A7e";
+ }
+ else
+ {
+ timeRemainingString += "\u00A7c";
+ }
+ timeRemainingString += Integer.toString(timeRemainingInt);
+ int stringWidth = Minecraft.getMinecraft().fontRenderer.getStringWidth(timeRemainingString);
+ Minecraft.getMinecraft().fontRenderer.drawString(timeRemainingString, width/2 - stringWidth/2, 5, 0xFFFFFFFF);
+ stringWidth = Minecraft.getMinecraft().fontRenderer.getStringWidth(info);
+ Minecraft.getMinecraft().fontRenderer.drawString(info, width/2 - stringWidth/2, 20, 0xFFFFFFFF);
}
@Override
if(button instanceof ItemSelectionButton)
{
PacketHandler.INSTANCE.sendToServer(new PacketBattleDecision(TurnBasedMinecraftMod.currentBattle.getId(), Battle.Decision.SWITCH_ITEM, ((ItemSelectionButton)button).itemStackID));
+ if(((ItemSelectionButton)button).itemStackID >= 0 && ((ItemSelectionButton)button).itemStackID < 9)
+ {
+ Minecraft.getMinecraft().player.inventory.currentItem = ((ItemSelectionButton)button).itemStackID;
+ }
setState(MenuState.WAITING);
}
else
--- /dev/null
+package com.seodisparate.TurnBasedMinecraft.common;
+
+import net.minecraftforge.event.entity.living.LivingAttackEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class AttackEventHandler
+{
+ @SubscribeEvent
+ public void entityAttacked(LivingAttackEvent event)
+ {
+ if(event.getEntity().world.isRemote)
+ {
+ TurnBasedMinecraftMod.logger.debug("isRemote");
+ return;
+ }
+ else if(TurnBasedMinecraftMod.battleManager == null)
+ {
+ TurnBasedMinecraftMod.battleManager = new BattleManager(TurnBasedMinecraftMod.logger);
+ }
+
+ if(!(event.getSource().getTrueSource() == null || event.getSource().getTrueSource().equals(TurnBasedMinecraftMod.attackingEntity)) && TurnBasedMinecraftMod.battleManager.checkAttack(event))
+ {
+ TurnBasedMinecraftMod.logger.debug("Canceled LivingAttackEvent between " + TurnBasedMinecraftMod.attackingEntity + " and " + event.getEntity());
+ event.setCanceled(true);
+ }
+ else
+ {
+ TurnBasedMinecraftMod.logger.debug("Did not cancel attack");
+ }
+ if(TurnBasedMinecraftMod.attackingDamage < (int) event.getAmount())
+ {
+ TurnBasedMinecraftMod.attackingDamage = (int) event.getAmount();
+ }
+ }
+}
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
-import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleInfo;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleMessage;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketHandler;
+import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
{
// attack
// TODO damage via bow and arrow
+ // have player look at attack target
+ final Entity nextEntity = next.entity;
+ final Entity targetEntity = target.entity;
+ Minecraft.getMinecraft().addScheduledTask(() -> {
+ ((EntityPlayerMP)nextEntity).connection.setPlayerLocation(nextEntity.posX, nextEntity.posY, nextEntity.posZ, Utility.yawDirection(nextEntity.posX, nextEntity.posZ, targetEntity.posX, targetEntity.posZ), Utility.pitchDirection(nextEntity.posX, nextEntity.posY, nextEntity.posZ, targetEntity.posX, targetEntity.posY, targetEntity.posZ));
+ });
TurnBasedMinecraftMod.attackingEntity = next.entity;
+ TurnBasedMinecraftMod.attackingDamage = 0;
((EntityPlayer)next.entity).attackTargetEntityWithCurrentItem(target.entity);
TurnBasedMinecraftMod.attackingEntity = null;
sendMessageToAllPlayers(PacketBattleMessage.MessageType.ATTACK, next.entity.getEntityId(), target.entity.getEntityId(), TurnBasedMinecraftMod.attackingDamage);
c.decision = Decision.UNDECIDED;
}
state = State.DECISION;
+ undecidedCount.set(players.size());
healthCheck();
sendMessageToAllPlayers(PacketBattleMessage.MessageType.TURN_END, 0, 0, 0);
break;
import java.util.Hashtable;
import java.util.Map;
-import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
+import org.apache.logging.log4j.Logger;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
private int IDCounter = 0;
protected Map<Integer, Battle> battleMap;
private Thread updaterThread;
+ private Logger logger;
- public BattleManager()
+ public BattleManager(Logger logger)
{
+ this.logger = logger;
battleMap = new Hashtable<Integer, Battle>();
updaterThread = new Thread(new BattleUpdater(this));
updaterThread.start();
{
return false;
}
+
+ // check if ignore battle in config
+ EntityInfo entityInfo = TurnBasedMinecraftMod.config.getMatchingEntityInfo(event.getEntity());
+ if(entityInfo != null && (TurnBasedMinecraftMod.config.isIgnoreBattleType(entityInfo.category) || entityInfo.ignoreBattle))
+ {
+ // attacked entity ignores battle
+ for(Battle b : battleMap.values())
+ {
+ if(b.hasCombatant(event.getSource().getTrueSource().getEntityId()))
+ {
+ logger.debug("Attack Canceled: attacked ignores battle but attacker in battle");
+ return true;
+ }
+ }
+ logger.debug("Attack Not Canceled: attacked ignores battle");
+ return false;
+ }
+ entityInfo = TurnBasedMinecraftMod.config.getMatchingEntityInfo(event.getSource().getTrueSource());
+ if(entityInfo != null && (TurnBasedMinecraftMod.config.isIgnoreBattleType(entityInfo.category) || entityInfo.ignoreBattle))
+ {
+ // attacker entity ignores battle
+ for(Battle b : battleMap.values())
+ {
+ if(b.hasCombatant(event.getEntity().getEntityId()))
+ {
+ logger.debug("Attack Canceled: attacker ignores battle but attacked in battle");
+ return true;
+ }
+ }
+ logger.debug("Attack Not Canceled: attacker ignores battle");
+ return false;
+ }
+
// check if one is in battle
Entity inBattle = null;
Entity notInBattle = null;
if(inBattle != null)
{
// both combatants are in battle
+ logger.debug("Attack Canceled: both are in battle");
return true;
}
else
if(inBattle != null)
{
// both combatants are in battle
+ logger.debug("Attack Canceled: both are in battle");
return true;
}
else
sideA.add(event.getEntity());
sideB.add(event.getSource().getTrueSource());
createBattle(sideA, sideB);
+ logger.debug("Attack Not Canceled: new battle created");
+ }
+ else
+ {
+ logger.debug("Attack Not Canceled: neither are in battle or players");
}
return false;
}
battle.addCombatantToSideA(notInBattle);
}
+ logger.debug("Attack Canceled: one is in battle");
return true;
}
import java.util.Comparator;
-import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
-
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import org.apache.logging.log4j.Logger;
-import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
import com.seodisparate.TurnBasedMinecraft.common.EntityInfo.Category;
public class Config
return null;
}
EntityInfo matching = entityInfoMap.get(entity.getClass().getName());
- if(matching.classType.isInstance(entity))
+ if(matching != null && matching.classType.isInstance(entity))
{
for(Class c : matching.conflictingTypes)
{
return configVersion;
}
+
+ public boolean isIgnoreBattleType(Category type)
+ {
+ return ignoreBattleTypes.contains(type);
+ }
}
-package com.seodisparate.TurnBasedMinecraft;
+package com.seodisparate.TurnBasedMinecraft.common;
import java.time.Duration;
import org.apache.logging.log4j.Logger;
import com.seodisparate.TurnBasedMinecraft.client.BattleGui;
-import com.seodisparate.TurnBasedMinecraft.common.Battle;
-import com.seodisparate.TurnBasedMinecraft.common.BattleManager;
-import com.seodisparate.TurnBasedMinecraft.common.Config;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleDecision;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleInfo;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleMessage;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketHandler;
import net.minecraft.entity.Entity;
+import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.living.LivingAttackEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
private static int CONFIG_FILE_VERSION = 0;
- private static Logger logger;
- private static BattleManager battleManager;
+ protected static Logger logger;
+ protected static BattleManager battleManager;
private static int packetHandlerID = 0;
- public static Entity attackingEntity;
- public static int attackingDamage = 0;
- public static Config config;
+ protected static Entity attackingEntity;
+ protected static int attackingDamage = 0;
+ protected static Config config;
public static Battle currentBattle = null;
public static BattleGui currentBattleGui = null;
public void init(FMLInitializationEvent event)
{
currentBattle = null;
- if(event.getSide() == Side.SERVER)
- {
- battleManager = new BattleManager();
- }
- else
- {
- battleManager = null;
- }
+ battleManager = null;
+ config = new Config(logger);
// register packets
PacketHandler.INSTANCE.registerMessage(
packetHandlerID++,
Side.CLIENT);
logger.debug("INIT");
+
+ // register event handler(s)
+ MinecraftForge.EVENT_BUS.register(new AttackEventHandler());
}
@EventHandler
public void postInit(FMLPostInitializationEvent event)
{
- if(battleManager != null)
- {
- config = new Config(logger);
- }
logger.debug("POSTINIT");
}
-
- @SubscribeEvent
- public void entityAttacked(LivingAttackEvent event)
- {
- if(battleManager == null || event.getEntity().world.isRemote)
- {
- return;
- }
- if(!event.getSource().getTrueSource().equals(attackingEntity) && battleManager.checkAttack(event))
- {
- logger.debug("Canceled LivingAttackEvent between " + attackingEntity + " and " + event.getEntity());
- event.setCanceled(true);
- }
- attackingDamage = (int) event.getAmount();
- }
public static BattleManager getBattleManager()
{
--- /dev/null
+package com.seodisparate.TurnBasedMinecraft.common;
+
+public class Utility
+{
+ public static float yawDirection(double posX, double posZ, double targetX, double targetZ)
+ {
+ double radians = Math.atan2(targetZ - posZ, targetX - posX);
+ radians = (radians - Math.PI / 2.0);
+ if(radians < 0.0)
+ {
+ radians += Math.PI * 2.0;
+ }
+ return (float)(radians * 180.0 / Math.PI);
+ }
+
+ public static float pitchDirection(double posX, double posY, double posZ, double targetX, double targetY, double targetZ)
+ {
+ double diffX = targetX - posX;
+ double diffY = targetY - posY;
+ double diffZ = targetZ - posZ;
+ double distance = Math.sqrt(diffX * diffX + diffZ * diffZ);
+ if(Math.abs(diffY) < 0.1)
+ {
+ return 0;
+ }
+ else
+ {
+ return (float)(-Math.atan(diffY / distance) * 180.0 / Math.PI);
+ }
+ }
+}
package com.seodisparate.TurnBasedMinecraft.common.networking;
-import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
import com.seodisparate.TurnBasedMinecraft.common.Battle;
+import com.seodisparate.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import com.seodisparate.TurnBasedMinecraft.common.Battle.Decision;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.Collection;
-import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
+import com.seodisparate.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import java.util.HashMap;
import java.util.Map;
-import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
import com.seodisparate.TurnBasedMinecraft.client.BattleGui;
import com.seodisparate.TurnBasedMinecraft.common.Battle;
+import com.seodisparate.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
}
break;
case TURN_END:
- Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(
+ if(TurnBasedMinecraftMod.currentBattle != null)
+ {
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(
"The turn ended!"));
+ }
if(TurnBasedMinecraftMod.currentBattleGui != null)
{
TurnBasedMinecraftMod.currentBattleGui.turnEnd();
package com.seodisparate.TurnBasedMinecraft.common.networking;
-import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
import com.seodisparate.TurnBasedMinecraft.common.Battle;
+import com.seodisparate.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import io.netty.buffer.ByteBuf;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
package com.seodisparate.TurnBasedMinecraft.common.networking;
-import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
+import com.seodisparate.TurnBasedMinecraft.common.TurnBasedMinecraftMod;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;