diff --git a/ngengine_public.jar b/ngengine_public.jar index 5834adb3..96bf44fb 100644 Binary files a/ngengine_public.jar and b/ngengine_public.jar differ diff --git a/scripts/commands/setspeed.py b/scripts/commands/setspeed.py new file mode 100644 index 00000000..c73266de --- /dev/null +++ b/scripts/commands/setspeed.py @@ -0,0 +1,9 @@ +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + actor.setSpeedMultiplierBase(float(commandString)) + return + \ No newline at end of file diff --git a/src/main/NGECore.java b/src/main/NGECore.java index 6a683ced..ba8370bf 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -22,6 +22,8 @@ package main; import java.io.IOException; +import java.sql.PreparedStatement; +import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import java.util.Vector; @@ -38,6 +40,7 @@ import services.ScriptService; import services.SimulationService; import services.TerrainService; import services.chat.ChatService; +import services.combat.CombatService; import services.command.CombatCommand; import services.command.CommandService; import services.gcw.GCWService; @@ -102,6 +105,7 @@ public class NGECore { public GuildService guildService; public GCWService gcwService; public TradeService tradeService; + public CombatService combatService; // Login Server public NetworkDispatch loginDispatch; @@ -130,7 +134,7 @@ public class NGECore { databaseConnection.connect(config.getString("DB.URL"), config.getString("DB.NAME"), config.getString("DB.USER"), config.getString("DB.PASS"), "postgresql"); databaseConnection2 = new DatabaseConnection(); - + setGalaxyStatus(1); creatureODB = new ObjectDatabase("creature", true, false, true); mailODB = new ObjectDatabase("mails", true, false, true); @@ -148,7 +152,7 @@ public class NGECore { chatService = new ChatService(this); attributeService = new AttributeService(this); suiService = new SUIService(this); - + combatService = new CombatService(this); // Ping Server try { PingServer pingServer = new PingServer(config.getInt("PING.PORT")); @@ -197,6 +201,8 @@ public class NGECore { didServerCrash = false; System.out.println("Started Server."); + setGalaxyStatus(2); + } @@ -249,6 +255,21 @@ public class NGECore { } + public void setGalaxyStatus(int statusId) { + + int galaxyId = config.getInt("GALAXY_ID"); + + try { + PreparedStatement ps = databaseConnection.preparedStatement("UPDATE \"connectionServers\" SET \"statusId\"=? WHERE \"galaxyId\"=?"); + ps.setInt(1, statusId); + ps.setInt(2, galaxyId); + ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + + } + /* * ---------- Getter methods for NGECore ---------- */ diff --git a/src/protocol/swg/ObjControllerMessage.java b/src/protocol/swg/ObjControllerMessage.java index 7792009c..979a9b5e 100644 --- a/src/protocol/swg/ObjControllerMessage.java +++ b/src/protocol/swg/ObjControllerMessage.java @@ -41,6 +41,7 @@ public class ObjControllerMessage extends SWGMessage { public static final int DATA_TRANSFORM = 0x0071; public static final int SPACIAL_CHAT = 0x00F4; public static final int COMMAND_ENQUEUE = 0x0116; + public static final int COMMAND_ENQUEUE_REMOVE = 0x0117; public static final int USE_OBJECT = 0x0126; public static final int PLAYER_EMOTE = 0x012E; public static final int DATA_TRANSFORM_WITH_PARENT = 0x00F1; @@ -49,6 +50,7 @@ public class ObjControllerMessage extends SWGMessage { public static final int POSTURE = 0x0131; public static final int SIT_ON_OBJECT = 0x013B; public static final int OBJECT_MENU_RESPONSE = 0x0147; + public static final int SHOW_FLY_TEXT = 0x01BD; public ObjControllerMessage() { diff --git a/src/protocol/swg/objectControllerObjects/CommandEnqueueRemove.java b/src/protocol/swg/objectControllerObjects/CommandEnqueueRemove.java new file mode 100644 index 00000000..23a28342 --- /dev/null +++ b/src/protocol/swg/objectControllerObjects/CommandEnqueueRemove.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg.objectControllerObjects; + +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +import protocol.swg.ObjControllerMessage; + +public class CommandEnqueueRemove extends ObjControllerObject { + + private long objectId; + private int actionCounter; + + public CommandEnqueueRemove(long objectId, int actionCounter) { + this.objectId = objectId; + this.actionCounter = actionCounter; + } + + @Override + public void deserialize(IoBuffer data) { + // TODO Auto-generated method stub + + } + + @Override + public IoBuffer serialize() { + + IoBuffer result = IoBuffer.allocate(32).order(ByteOrder.LITTLE_ENDIAN); + + result.putInt(ObjControllerMessage.COMMAND_ENQUEUE_REMOVE); + result.putLong(objectId); + result.putInt(0); + result.putInt(actionCounter); + result.putLong(0); + result.putInt(0); + + return result.flip(); + + } + +} diff --git a/src/protocol/swg/objectControllerObjects/ShowFlyText.java b/src/protocol/swg/objectControllerObjects/ShowFlyText.java new file mode 100644 index 00000000..083d97b2 --- /dev/null +++ b/src/protocol/swg/objectControllerObjects/ShowFlyText.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg.objectControllerObjects; + +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +import protocol.swg.ObjControllerMessage; + +public class ShowFlyText extends ObjControllerObject { + + private long recieverId; + private long objectId; + private String stfFile; + private String stfString; + private float scale; + private float color; + + public ShowFlyText(long recieverId, long objectId, String stfFile, String stfString, float scale, float color) { + this.recieverId = recieverId; + this.objectId = objectId; + this.stfFile = stfFile; + this.stfString = stfString; + this.scale = scale; + this.color = color; + } + + @Override + public void deserialize(IoBuffer data) { + // TODO Auto-generated method stub + + } + + @Override + public IoBuffer serialize() { + + IoBuffer result = IoBuffer.allocate(47 + stfFile.length() + stfString.length()).order(ByteOrder.LITTLE_ENDIAN); + result.setAutoExpand(true); + + result.putInt(ObjControllerMessage.SHOW_FLY_TEXT); + result.putLong(recieverId); + result.putInt(0); + result.putLong(objectId); + + result.put(getAsciiString(stfFile)); + result.putInt(0); + result.put(getAsciiString(stfString)); + result.putInt(0); + result.putFloat(scale); + result.putFloat(color); // color + result.putShort((short) 0); + result.put((byte) 0); + + return result.flip(); + + } + +} diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index ff32f1ee..d1a47a43 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -342,6 +342,16 @@ public class CreatureObject extends TangibleObject implements IPersistent { public List getSkillMods() { return skillMods; } + + public SkillMod getSkillMod(String name) { + synchronized(objectMutex) { + for(SkillMod skillMod : skillMods) { + if(skillMod.getSkillModString().equals(name)) + return skillMod; + } + } + return null; + } public short getSkillModsUpdateCounter() { synchronized(objectMutex) { diff --git a/src/resources/objects/weapon/WeaponObject.java b/src/resources/objects/weapon/WeaponObject.java index 3fa62289..bbbf6409 100644 --- a/src/resources/objects/weapon/WeaponObject.java +++ b/src/resources/objects/weapon/WeaponObject.java @@ -212,4 +212,26 @@ public class WeaponObject extends SWGObject { this.maxRange = maxRange; } + public boolean isMelee() { + + int weaponType = getWeaponType(); + + if(weaponType == 4 || weaponType == 5 || weaponType == 6 || weaponType == 7 || weaponType == 9 || weaponType == 10 || weaponType == 11) + return true; + + return false; + + } + + public boolean isRanged() { + + int weaponType = getWeaponType(); + + if(weaponType == 0 || weaponType == 1 || weaponType == 2 || weaponType == 3) + return true; + + return false; + + } + } diff --git a/src/services/CharacterService.java b/src/services/CharacterService.java index 727976f9..087573d4 100644 --- a/src/services/CharacterService.java +++ b/src/services/CharacterService.java @@ -35,6 +35,8 @@ import org.apache.mina.core.session.IoSession; import engine.clients.Client; import engine.resources.common.CRC; +import engine.resources.container.CreatureContainerPermissions; +import engine.resources.container.CreaturePermissions; import engine.resources.database.DatabaseConnection; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; @@ -205,6 +207,7 @@ public class CharacterService implements INetworkDispatch { String sharedRaceTemplate = raceTemplate.replace("player/", "player/shared_"); CreatureObject object = (CreatureObject) core.objectService.createObject(sharedRaceTemplate, core.terrainService.getPlanetList().get(0)); + object.setContainerPermissions(CreaturePermissions.CREATURE_PERMISSIONS); object.setCustomization(clientCreateCharacter.getCustomizationData()); object.setCustomName(clientCreateCharacter.getName()); object.setHeight(clientCreateCharacter.getScale()); @@ -227,10 +230,16 @@ public class CharacterService implements INetworkDispatch { } TangibleObject inventory = (TangibleObject) core.objectService.createObject("object/tangible/inventory/shared_character_inventory.iff", object.getPlanet()); + inventory.setContainerPermissions(CreatureContainerPermissions.CREATURE_CONTAINER_PERMISSIONS); TangibleObject appInventory = (TangibleObject) core.objectService.createObject("object/tangible/inventory/shared_appearance_inventory.iff", object.getPlanet()); + appInventory.setContainerPermissions(CreaturePermissions.CREATURE_PERMISSIONS); TangibleObject datapad = (TangibleObject) core.objectService.createObject("object/tangible/datapad/shared_character_datapad.iff", object.getPlanet()); + datapad.setContainerPermissions(CreatureContainerPermissions.CREATURE_CONTAINER_PERMISSIONS); TangibleObject bank = (TangibleObject) core.objectService.createObject("object/tangible/bank/shared_character_bank.iff", object.getPlanet()); + bank.setContainerPermissions(CreatureContainerPermissions.CREATURE_CONTAINER_PERMISSIONS); TangibleObject missionBag = (TangibleObject) core.objectService.createObject("object/tangible/mission_bag/shared_mission_bag.iff", object.getPlanet()); + missionBag.setContainerPermissions(CreatureContainerPermissions.CREATURE_CONTAINER_PERMISSIONS); + object.add(inventory); object.add(appInventory); object.add(datapad); diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index eed8daa0..e665d258 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -125,6 +125,7 @@ public class SimulationService implements INetworkDispatch { core.commandService.registerCommand("setcurrentskilltitle"); core.commandService.registerCommand("tip"); core.commandService.registerCommand("faction"); + core.commandService.registerCommand("setspeed"); } public void add(SWGObject object, int x, int y) { diff --git a/src/services/combat/CombatService.java b/src/services/combat/CombatService.java index e8b4349d..1806d769 100644 --- a/src/services/combat/CombatService.java +++ b/src/services/combat/CombatService.java @@ -22,6 +22,7 @@ package services.combat; import java.util.Map; +import java.util.Random; import resources.objects.creature.CreatureObject; import resources.objects.tangible.TangibleObject; @@ -53,14 +54,147 @@ public class CombatService implements INetworkDispatch { } - public void doCombat(CreatureObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command) { + public void doCombat(CreatureObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command, int actionCounter) { - if(!attemptCombat(attacker, target)) - return; if(!applySpecialCost(attacker, weapon, command)) return; + if(!attemptCombat(attacker, target)) + return; + + if(command.getAttackType() == 1) + doSingleTargetCombat(attacker, target, weapon, command, actionCounter); + else if(command.getAttackType() == 0 || command.getAttackType() == 2 || command.getAttackType() == 3) + doAreaCombat(attacker, target, weapon, command, actionCounter); + + } + + private void doAreaCombat(CreatureObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command, int actionCounter) { + if(target instanceof CreatureObject) { + doAreaCombat(attacker, (CreatureObject) target, weapon, command, actionCounter); + return; + } + } + + private void doSingleTargetCombat(CreatureObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command, int actionCounter) { + if(target instanceof CreatureObject) { + doSingleTargetCombat(attacker, (CreatureObject) target, weapon, command, actionCounter); + return; + } + + float damage = calculateDamage(attacker, target, weapon, command); + } + + private void doAreaCombat(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command, int actionCounter) { + + } + + private void doSingleTargetCombat(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command, int actionCounter) { + + float damage = calculateDamage(attacker, target, weapon, command); + + byte hitType = getHitType(attacker, target, weapon, command); + + switch(hitType) { + + case HitType.MISS: + damage = 0; + break; + + case HitType.DODGE: + damage = 0; + break; + + case HitType.PARRY: + damage = 0; + break; + + case HitType.CRITICAL: + damage *= 1.5f; + break; + + } + byte mitigationType = -1; + if(hitType == HitType.CRITICAL || hitType == HitType.HIT || hitType == HitType.STRIKETHROUGH) { + mitigationType = doMitigationRolls(attacker, target, weapon, command, hitType); + + if(mitigationType == HitType.GLANCE) { + damage *= 0.4f; + } else if(mitigationType == HitType.EVASION) { + float evasionValue = (attacker.getSkillMod("combat_evasion_value").getBase() / 4) / 100; + + damage *= (1 - evasionValue); + + } + + } + damage *= (1 - getArmorReduction(attacker, target, weapon, command, hitType)); + if(mitigationType == HitType.BLOCK) { + + float blockValue = (attacker.getSkillMod("strength_modified").getBase() * attacker.getSkillMod("combat_block_value").getBase()) / 2 + 25; + damage -= blockValue; + + } + + applyDamage(attacker, target, (int) damage); + + } + + + + private float getArmorReduction(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command, byte hitType) { + + int elementalType = 1; + + if(command.getPercentFromWeapon() > 0) { + + // TODO: elemental mitigation and damage + + if(weapon.getStringAttribute("cat_wpn_damage.wpn_damage_type").equals("@obj_attr_n:armor_eff_kinetic")) + elementalType = ElementalType.KINETIC; + else if(weapon.getStringAttribute("cat_wpn_damage.wpn_damage_type").equals("@obj_attr_n:armor_eff_energy")) + elementalType = ElementalType.ENERGY; + + } else { + + elementalType = command.getElementalType(); + + } + + int baseArmor = 0; + + switch(elementalType) { + + case ElementalType.KINETIC: + baseArmor = target.getSkillMod("kinetic").getBase(); + case ElementalType.ENERGY: + baseArmor = target.getSkillMod("energy").getBase(); + case ElementalType.HEAT: + baseArmor = target.getSkillMod("heat").getBase(); + case ElementalType.COLD: + baseArmor = target.getSkillMod("cold").getBase(); + case ElementalType.ACID: + baseArmor = target.getSkillMod("acid").getBase(); + case ElementalType.ELECTRICITY: + baseArmor = target.getSkillMod("electricity").getBase(); + + } + + float mitigation = (float) (90 * (1 - Math.exp(-0.000125 * baseArmor)) + baseArmor / 9000); + + if(hitType == HitType.STRIKETHROUGH) { + + float stMaxValue = attacker.getSkillMod("combat_strikethrough_value").getBase() / 2; + float stMinValue = stMaxValue / 2; + + float stValue = new Random().nextInt((int) (stMaxValue - stMinValue + 1)) + stMinValue; + stValue /= 100; + mitigation *= stValue; + } + + return mitigation / 100; + } private boolean attemptCombat(CreatureObject attacker, TangibleObject target) { @@ -106,5 +240,235 @@ public class CombatService implements INetworkDispatch { return true; } + + private float calculateDamage(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command) { + + float rawDamage = command.getAddedDamage(); + + if(command.getPercentFromWeapon() > 0 && weapon != attacker.getSlottedObject("default_weapon")) { + + float weaponMinDmg = weapon.getIntAttribute("cat_wpn_damage.wpn_damage_min"); + float weaponMaxDmg = weapon.getIntAttribute("cat_wpn_damage.wpn_damage_max"); + + float weaponDmg = new Random().nextInt((int) (weaponMaxDmg - weaponMinDmg + 1)) + weaponMinDmg; + weaponDmg *= command.getPercentFromWeapon(); + rawDamage += weaponDmg; + + if(weapon.isMelee() && attacker.getSkillMod("strength_modified") != null) { + + if(attacker.getSkillMod("strength_modified").getBase() > 0) { + rawDamage += ((attacker.getSkillMod("strength_modified").getBase() / 100) * 33); + } + + } + + } else if(command.getPercentFromWeapon() > 0) { + + float weaponMinDmg = 50; + float weaponMaxDmg = 100; + + float weaponDmg = new Random().nextInt((int) (weaponMaxDmg - weaponMinDmg + 1)) + weaponMinDmg; + weaponDmg *= command.getPercentFromWeapon(); + rawDamage += weaponDmg; + + if(weapon.isMelee() && attacker.getSkillMod("strength_modified") != null) { + + if(attacker.getSkillMod("strength_modified").getBase() > 0) { + rawDamage += ((attacker.getSkillMod("strength_modified").getBase() / 100) * 33); + } + + } + + } + + if(target.getSkillMod("damage_decrease_percentage") != null) { + rawDamage *= (target.getSkillMod("damage_decrease_percentage").getBase() / 100); + } + + return rawDamage; + + } + + + private float calculateDamage(CreatureObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command) { + + float rawDamage = command.getAddedDamage(); + + if(command.getPercentFromWeapon() > 0 && weapon != attacker.getSlottedObject("default_weapon")) { + + float weaponMinDmg = weapon.getIntAttribute("cat_wpn_damage.wpn_damage_min"); + float weaponMaxDmg = weapon.getIntAttribute("cat_wpn_damage.wpn_damage_max"); + + float weaponDmg = new Random().nextInt((int) (weaponMaxDmg - weaponMinDmg + 1)) + weaponMinDmg; + weaponDmg *= command.getPercentFromWeapon(); + rawDamage += weaponDmg; + + if(weapon.isMelee() && attacker.getSkillMod("strength_modified") != null) { + + if(attacker.getSkillMod("strength_modified").getBase() > 0) { + rawDamage += ((attacker.getSkillMod("strength_modified").getBase() / 100) * 33); + } + + } + + } else if(command.getPercentFromWeapon() > 0) { + + float weaponMinDmg = 50; + float weaponMaxDmg = 100; + + float weaponDmg = new Random().nextInt((int) (weaponMaxDmg - weaponMinDmg + 1)) + weaponMinDmg; + weaponDmg *= command.getPercentFromWeapon(); + rawDamage += weaponDmg; + + if(weapon.isMelee() && attacker.getSkillMod("strength_modified") != null) { + + if(attacker.getSkillMod("strength_modified").getBase() > 0) { + rawDamage += ((attacker.getSkillMod("strength_modified").getBase() / 100) * 33); + } + + } + + } + + return rawDamage; + + } + + public byte getHitType(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command) { + + Random rand = new Random(); + float r; + + // negation rolls(parry, miss and dodge) can only roll on single target attacks, strikethrough also only rolls on single target attacks + if(command.getAttackType() == 1) { + + if(weapon.isRanged()) { + float missChance = 0.5f; + if(attacker.getSkillMod("strength_modified").getBase() > 0) { + float missNegation = (float) ((attacker.getSkillMod("strength_modified").getBase() / 100) * 0.1); + if(missNegation > 0.4f) + missNegation = 0.4f; + missChance -= missNegation; + } + r = rand.nextFloat(); + if(r <= missChance) + return HitType.MISS; + } + float dodgeChance = target.getSkillMod("display_only_dodge").getBase() / 10000; + + r = rand.nextFloat(); + if(r <= dodgeChance) + return HitType.DODGE; + + + WeaponObject weapon2 = (WeaponObject) core.objectService.getObject(((CreatureObject) target).getWeaponId()); + if(weapon2 != null && weapon2.isMelee()) { + + float parryChance = target.getSkillMod("display_only_parry").getBase() / 10000; + + r = rand.nextFloat(); + if(r <= parryChance) + return HitType.PARRY; + + } + + float stChance = attacker.getSkillMod("display_only_strikethrough").getBase() / 10000; + + r = rand.nextFloat(); + if(r <= stChance) + return HitType.STRIKETHROUGH; + + } + + float critChance = attacker.getSkillMod("display_only_critical").getBase() / 10000; + + r = rand.nextFloat(); + if(r <= critChance) + return HitType.CRITICAL; + + // TODO: Punishing blow once AI is implemented + + return HitType.HIT; + + } + + public byte doMitigationRolls(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command, byte hitType) { + + Random rand = new Random(); + float r; + + float blockChance = target.getSkillMod("display_only_block").getBase() / 10000; + + r = rand.nextFloat(); + if(r <= blockChance) + return HitType.BLOCK; + + if(command.getAttackType() == 0 || command.getAttackType() == 2 || command.getAttackType() == 3) { + + float evasionChance = target.getSkillMod("display_only_evasion").getBase() / 10000; + + r = rand.nextFloat(); + if(r <= evasionChance) + return HitType.EVASION; + + } + + if(hitType == HitType.HIT) { + + float glanceChance = target.getSkillMod("display_only_glancing_blow").getBase() / 10000; + + r = rand.nextFloat(); + if(r <= glanceChance) + return HitType.GLANCE; + + } + + + return -1; + + } + + public void applyDamage(CreatureObject attacker, CreatureObject target, int damage) { + + if(target.getHealth() - damage <= 0) { + target.setHealth(1); + target.setPosture((byte) 13); + if(target.getSlottedObject("ghost") != null) + attacker.sendSystemMessage("You incapacitate " + target.getCustomName() + ".", (byte) 0); + return; + } + target.setHealth(target.getHealth() - damage); + + } + + + + public enum HitType{; + + public static final byte MISS = 0; + public static final byte DODGE = 1; + public static final byte PARRY = 2; + public static final byte STRIKETHROUGH = 3; + public static final byte CRITICAL = 4; + public static final byte PUNISHING = 5; + public static final byte HIT = 6; + public static final byte BLOCK = 7; + public static final byte EVASION = 8; + public static final byte GLANCE = 9; + + } + + public enum ElementalType {; + + public static final int KINETIC = 1; + public static final int ENERGY = 2; + public static final int BLAST = 4; + public static final int STUN = 8; + public static final int HEAT = 32; + public static final int COLD = 64; + public static final int ACID = 128; + public static final int ELECTRICITY = 256; + + } } diff --git a/src/services/command/CommandService.java b/src/services/command/CommandService.java index dcbee5b0..5ae2a041 100644 --- a/src/services/command/CommandService.java +++ b/src/services/command/CommandService.java @@ -37,7 +37,10 @@ import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; import resources.common.*; +import protocol.swg.ObjControllerMessage; import protocol.swg.objectControllerObjects.CommandEnqueue; +import protocol.swg.objectControllerObjects.CommandEnqueueRemove; +import protocol.swg.objectControllerObjects.ShowFlyText; import resources.objects.creature.CreatureObject; import resources.objects.tangible.TangibleObject; @@ -90,7 +93,7 @@ public class CommandService implements INetworkDispatch { SWGObject target = core.objectService.getObject(commandEnqueue.getTargetID()); if(command instanceof CombatCommand) { - processCombatCommand(actor, target, (CombatCommand) command); + processCombatCommand(actor, target, (CombatCommand) command, commandEnqueue.getActionCounter()); return; } @@ -134,17 +137,19 @@ public class CommandService implements INetworkDispatch { } - private void processCombatCommand(CreatureObject attacker, SWGObject target, CombatCommand command) { + private void processCombatCommand(CreatureObject attacker, SWGObject target, CombatCommand command, int actionCounter) { + + boolean success = true; if(target == null || !(target instanceof TangibleObject) || target == attacker) - return; + success = false; if(attacker.getPosture() == 13 || attacker.getPosture() == 14) - return; + success = false; if(target instanceof CreatureObject) { if(((CreatureObject) target).getPosture() == 13 || ((CreatureObject) target).getPosture() == 14) - return; + success = false; } WeaponObject weapon; @@ -165,16 +170,29 @@ public class CommandService implements INetworkDispatch { Point3D defenderPos = attacker.getWorldPosition(); if(attackerPos.getDistance(defenderPos) > maxRange && maxRange != 0) - return; + success = false; if(command.getMinRange() > 0) { if(attackerPos.getDistance(defenderPos) < command.getMinRange()) - return; + success = false; } - if(!core.simulationService.checkLineOfSight(attacker, target)) - return; + if(!core.simulationService.checkLineOfSight(attacker, target)) { + + ShowFlyText los = new ShowFlyText(attacker.getObjectID(), attacker.getObjectID(), "combat_effects", "cant_see", (float) 1.5, (float) 429664.031250); + ObjControllerMessage objController = new ObjControllerMessage(0x1B, los); + attacker.getClient().getSession().write(objController.serialize()); + success = false; + + } + if(!success) { + CommandEnqueueRemove commandRemove = new CommandEnqueueRemove(attacker.getObjectId(), actionCounter); + ObjControllerMessage objController = new ObjControllerMessage(0x0B, commandRemove); + attacker.getClient().getSession().write(objController.serialize()); + } else { + core.combatService.doCombat(attacker, (TangibleObject) target, weapon, command, actionCounter); + } } diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index fd77e6ee..83259806 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -355,15 +355,6 @@ public class ObjectService implements INetworkDispatch { client.setParent(creature); objectList.add(creature); - creature.viewChildren(creature, true, true, new Traverser() { - - @Override - public void process(SWGObject object) { - //System.out.println(object.getTemplate()); - objectList.add(object); - } - - }); creature.viewChildren(creature, true, true, new Traverser() { @@ -374,7 +365,17 @@ public class ObjectService implements INetworkDispatch { object.getContainerInfo(object.getTemplate()); } + }); + creature.viewChildren(creature, true, true, new Traverser() { + + @Override + public void process(SWGObject object) { + //System.out.println(object.getTemplate()); + objectList.add(object); + } + }); + if(creature.getParentId() != 0) { SWGObject parent = getObject(creature.getParentId()); parent._add(creature); diff --git a/src/services/trade/TradeService.java b/src/services/trade/TradeService.java index c7a0b770..e1a7526e 100644 --- a/src/services/trade/TradeService.java +++ b/src/services/trade/TradeService.java @@ -205,6 +205,7 @@ public class TradeService implements INetworkDispatch{ System.out.println("Trading item: " + objectToTrade.getCustomName() + " detail: " + objectToTrade.getDetailFilename()); System.out.println("tradingObjectTable: " + tradingObjectsTable.toString()); + tradee.makeAware(objectToTrade); AddItemMessage tradeeResponse = new AddItemMessage(); tradeeResponse.setTradeObjectID(tradeItemID); tradee.getClient().getSession().write(tradeeResponse.serialize());