From 4fe9270a69eeb4ca6ad9ea8e6856706645961154 Mon Sep 17 00:00:00 2001 From: CharonInferar Date: Tue, 22 Jul 2014 23:46:17 +0200 Subject: [PATCH] Added invasion NPCs, debugged AI lockups and more - Added barrier and tower plus the according buffs - Added defender NPCs - Fixed enemy NPCs not showing hostile after faction change - Added ally function implementation to rebel and imperial scripts - AI does not lock up in a state anymore - AI seeks better position if LOS is blocked - AI resumes previous states better now --- scripts/buffs/barricade_defender.py | 18 + .../gcw_general_resistance_stack_rebel.py | 18 + scripts/commands/pvp.py | 15 +- scripts/commands/setgodmode.py | 11 + scripts/faction/imperial.py | 2 + scripts/faction/rebel.py | 2 + .../faction/imperial/imp_invasion_at_at.py | 6 +- .../faction/imperial/imp_invasion_at_st.py | 7 +- .../faction/rebel/gcw_city_rebel_soldier.py | 45 + .../rebel/rebel_invasion_hailfire_droid.py | 2 +- src/main/NGECore.java | 3 +- .../creature/CreatureMessageBuilder.java | 4 +- .../objects/creature/CreatureObject.java | 4 +- .../InstallationMessageBuilder.java | 22 + .../installation/InstallationObject.java | 17 + .../objects/tangible/TangibleObject.java | 17 +- src/services/DevService.java | 7 +- src/services/SimulationService.java | 197 +++- src/services/ai/AIActor.java | 109 ++- src/services/ai/AIService.java | 12 + src/services/ai/TurretAIActor.java | 33 +- src/services/ai/states/AIState.java | 272 +++++- src/services/ai/states/AttackState.java | 89 +- src/services/ai/states/DeathState.java | 1 + src/services/ai/states/PatrolState.java | 42 +- src/services/ai/states/RepositionState.java | 90 ++ src/services/ai/states/RetreatState.java | 64 +- src/services/ai/states/TurretAIState.java | 7 - src/services/ai/states/TurretAttackState.java | 49 +- src/services/ai/states/TurretIdleState.java | 10 +- src/services/combat/CombatService.java | 62 +- src/services/gcw/FactionService.java | 61 +- src/services/gcw/GCWPylon.java | 81 +- src/services/gcw/GCWSpawner.java | 502 +++++++++++ src/services/gcw/InvasionService.java | 845 +++++++++++++++--- src/services/object/ObjectService.java | 7 + src/services/spawn/SpawnService.java | 3 + src/tools/DevLog.java | 100 ++- 38 files changed, 2544 insertions(+), 292 deletions(-) create mode 100644 scripts/buffs/barricade_defender.py create mode 100644 scripts/buffs/gcw_general_resistance_stack_rebel.py create mode 100644 scripts/mobiles/generic/faction/rebel/gcw_city_rebel_soldier.py create mode 100644 src/services/ai/states/RepositionState.java create mode 100644 src/services/gcw/GCWSpawner.java diff --git a/scripts/buffs/barricade_defender.py b/scripts/buffs/barricade_defender.py new file mode 100644 index 00000000..9acc5d3c --- /dev/null +++ b/scripts/buffs/barricade_defender.py @@ -0,0 +1,18 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'expertise_dodge', 35) + core.skillModService.addSkillMod(actor, 'display_only_evasion', 5000) + core.skillModService.addSkillMod(actor, 'combat_evasion_value', 50) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'expertise_dodge', 35) + core.skillModService.deductSkillMod(actor, 'display_only_evasion', 5000) + core.skillModService.deductSkillMod(actor, 'combat_evasion_value', 50) + return + \ No newline at end of file diff --git a/scripts/buffs/gcw_general_resistance_stack_rebel.py b/scripts/buffs/gcw_general_resistance_stack_rebel.py new file mode 100644 index 00000000..9acc5d3c --- /dev/null +++ b/scripts/buffs/gcw_general_resistance_stack_rebel.py @@ -0,0 +1,18 @@ +import sys + +def setup(core, actor, buff): + + return + +def add(core, actor, buff): + core.skillModService.addSkillMod(actor, 'expertise_dodge', 35) + core.skillModService.addSkillMod(actor, 'display_only_evasion', 5000) + core.skillModService.addSkillMod(actor, 'combat_evasion_value', 50) + return + +def remove(core, actor, buff): + core.skillModService.deductSkillMod(actor, 'expertise_dodge', 35) + core.skillModService.deductSkillMod(actor, 'display_only_evasion', 5000) + core.skillModService.deductSkillMod(actor, 'combat_evasion_value', 50) + return + \ No newline at end of file diff --git a/scripts/commands/pvp.py b/scripts/commands/pvp.py index 34f6c5ff..8fd3f42a 100644 --- a/scripts/commands/pvp.py +++ b/scripts/commands/pvp.py @@ -10,7 +10,7 @@ def setup(): def run(core, actor, target, commandString): faction = actor.getFaction() factionStatus = actor.getFactionStatus() - + if actor.getPvpStatus(PvpStatus.GoingOvert) or actor.getPvpStatus(PvpStatus.GoingCovert): actor.sendSystemMessage('@faction_recruiter:pvp_status_changing', 0) return @@ -18,9 +18,10 @@ def run(core, actor, target, commandString): actor.sendSystemMessage('@gcw:pvp_advanced_region_cannot_go_covert', 0) return - if commandString != '' and commandString != faction: + if commandString != '' and commandString != faction and len(faction)!=0: if commandString == 'rebel' or commandString == 'imperial' or commandString == 'neutral': - if faction != 'neutral': + + if faction != 'neutral' and len(faction)!=0: actor.sendSystemMessage('@faction_recruiter:sui_resig_complete_in_5', 0) if actor.getFactionStatus() == FactionStatus.SpecialForces: @@ -37,7 +38,7 @@ def run(core, actor, target, commandString): if commandString == 'neutral' or commandString == 'resign': time.sleep(1) - actor.setFaction('') + actor.setFaction('') # ??? actor.sendSystemMessage('@faction_recruiter:resign_complete', 0) return @@ -45,6 +46,11 @@ def run(core, actor, target, commandString): actor.setFaction(commandString) return + #This can be removed if player is required to see the recruiter first + if faction == '': + actor.setFaction(commandString) + faction = commandString + if faction == 'neutral' or faction == '': actor.sendSystemMessage('@faction_recruiter:not_aligned', 0) return @@ -57,6 +63,7 @@ def run(core, actor, target, commandString): actor.setPvpStatus(PvpStatus.GoingCovert, False) actor.sendSystemMessage('@faction_recruiter:covert_complete', 0) actor.updatePvpStatus() + core.factionService.updatePVPFromNearbyNPCs(actor, actor.getClient()) return if factionStatus == FactionStatus.Combatant: diff --git a/scripts/commands/setgodmode.py b/scripts/commands/setgodmode.py index b34f4cdb..43c3876e 100644 --- a/scripts/commands/setgodmode.py +++ b/scripts/commands/setgodmode.py @@ -179,7 +179,18 @@ def run(core, actor, target, commandString): actor.setPosture(0) actor.setSpeedMultiplierBase(1) actor.setTurnRadius(1) + + elif command == 'checkai': + latargetID = long(actor.getIntendedTarget()) + latarget = core.objectService.getObject(latargetID) + actor.sendSystemMessage('Checking AI handling for unit ' + latarget.getCustomName(), 0) + core.aiService.setCheckAI(latarget) + elif command == 'showbitmask': + latargetID = long(actor.getIntendedTarget()) + latarget = core.objectService.getObject(latargetID) + actor.sendSystemMessage('Optionsbitmask for unit ' + latarget.getCustomName() + ' is %s' % latarget.getOptionsBitmask(), 0) + elif command == 'unknownAbilityPacket' and arg1: packet = UnknownAbilityPacket(arg1) actor.getClient().getSession().write(packet.serialize()) diff --git a/scripts/faction/imperial.py b/scripts/faction/imperial.py index b5bc8cc0..f7b1232c 100644 --- a/scripts/faction/imperial.py +++ b/scripts/faction/imperial.py @@ -1,6 +1,8 @@ import sys def isAlly(ally): + if ally == 'imperial': + return 1 return 0 def isEnemy(enemy): diff --git a/scripts/faction/rebel.py b/scripts/faction/rebel.py index 0d685a6a..f435ab8c 100644 --- a/scripts/faction/rebel.py +++ b/scripts/faction/rebel.py @@ -1,6 +1,8 @@ import sys def isAlly(ally): + if ally == 'rebel': + return 1 return 0 def isEnemy(enemy): diff --git a/scripts/mobiles/generic/faction/imperial/imp_invasion_at_at.py b/scripts/mobiles/generic/faction/imperial/imp_invasion_at_at.py index b675fa5d..99e1234c 100644 --- a/scripts/mobiles/generic/faction/imperial/imp_invasion_at_at.py +++ b/scripts/mobiles/generic/faction/imperial/imp_invasion_at_at.py @@ -11,9 +11,9 @@ from java.util import Vector def addTemplate(core): mobileTemplate = MobileTemplate() - mobileTemplate.setCreatureName('eow_gcw_city_at_st_2') + mobileTemplate.setCreatureName('at_at') mobileTemplate.setLevel(90) - mobileTemplate.setDifficulty(Difficulty.ELITE) + mobileTemplate.setDifficulty(Difficulty.BOSS) mobileTemplate.setMinSpawnDistance(4) mobileTemplate.setMaxSpawnDistance(8) @@ -26,7 +26,7 @@ def addTemplate(core): mobileTemplate.setFactionStatus(FactionStatus.Combatant) templates = Vector() - templates.add('object/mobile/vehicle/shared_walker_at_st.iff') + templates.add('object/mobile/shared_atat.iff') mobileTemplate.setTemplates(templates) weaponTemplates = Vector() diff --git a/scripts/mobiles/generic/faction/imperial/imp_invasion_at_st.py b/scripts/mobiles/generic/faction/imperial/imp_invasion_at_st.py index bda2a6a1..3f407eba 100644 --- a/scripts/mobiles/generic/faction/imperial/imp_invasion_at_st.py +++ b/scripts/mobiles/generic/faction/imperial/imp_invasion_at_st.py @@ -24,13 +24,14 @@ def addTemplate(core): mobileTemplate.setStalker(False) mobileTemplate.setFaction("imperial") mobileTemplate.setFactionStatus(FactionStatus.Combatant) + mobileTemplate.setOptionsBitmask(Options.ATTACKABLE) templates = Vector() - templates.add('object/mobile/vehicle/shared_walker_at_st.iff') + templates.add('object/mobile/shared_atst.iff') mobileTemplate.setTemplates(templates) - weaponTemplates = Vector() - weapontemplate = WeaponTemplate('object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates = Vector() # object/weapon/ranged/turret/shared_turret_heat.iff object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff + weapontemplate = WeaponTemplate('object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff', WeaponType.RIFLE, 2.0, 55, 'energy') weaponTemplates.add(weapontemplate) mobileTemplate.setWeaponTemplateVector(weaponTemplates) diff --git a/scripts/mobiles/generic/faction/rebel/gcw_city_rebel_soldier.py b/scripts/mobiles/generic/faction/rebel/gcw_city_rebel_soldier.py new file mode 100644 index 00000000..c6c75763 --- /dev/null +++ b/scripts/mobiles/generic/faction/rebel/gcw_city_rebel_soldier.py @@ -0,0 +1,45 @@ +import sys +from services.spawn import MobileTemplate +from services.spawn import WeaponTemplate +from resources.datatables import WeaponType +from resources.datatables import Difficulty +from resources.datatables import Options +from resources.datatables import FactionStatus +from java.util import Vector + +def addTemplate(core): + mobileTemplate = MobileTemplate() + + mobileTemplate.setCreatureName('cheerleader_rebel_commando_hard') + mobileTemplate.setLevel(90) + mobileTemplate.setDifficulty(Difficulty.ELITE) + + mobileTemplate.setMinSpawnDistance(4) + mobileTemplate.setMaxSpawnDistance(8) + mobileTemplate.setDeathblow(True) + mobileTemplate.setSocialGroup("rebel") + mobileTemplate.setAssistRange(0) + mobileTemplate.setStalker(True) + mobileTemplate.setFaction("rebel") + mobileTemplate.setFactionStatus(FactionStatus.Combatant) + + templates = Vector() + templates.add('object/mobile/shared_dressed_rebel_commando_human_female_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_human_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_moncal_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_rodian_male_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_twilek_female_01.iff') + templates.add('object/mobile/shared_dressed_rebel_commando_zabrak_female_01.iff') + mobileTemplate.setTemplates(templates) + + weaponTemplates = Vector() + weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e5.iff', WeaponType.CARBINE, 1.0, 15, 'energy') + weaponTemplates.add(weapontemplate) + mobileTemplate.setWeaponTemplateVector(weaponTemplates) + + attacks = Vector() + mobileTemplate.setDefaultAttack('rangedShot') + mobileTemplate.setAttacks(attacks) + + core.spawnService.addMobileTemplate('gcw_city_rebel_soldier', mobileTemplate) + return \ No newline at end of file diff --git a/scripts/mobiles/generic/faction/rebel/rebel_invasion_hailfire_droid.py b/scripts/mobiles/generic/faction/rebel/rebel_invasion_hailfire_droid.py index 098d612d..bd8164a4 100644 --- a/scripts/mobiles/generic/faction/rebel/rebel_invasion_hailfire_droid.py +++ b/scripts/mobiles/generic/faction/rebel/rebel_invasion_hailfire_droid.py @@ -13,7 +13,7 @@ def addTemplate(core): mobileTemplate.setCreatureName('eow_gcw_city_at_st_2') mobileTemplate.setLevel(90) - mobileTemplate.setDifficulty(Difficulty.ELITE) + mobileTemplate.setDifficulty(Difficulty.BOSS) mobileTemplate.setMinSpawnDistance(4) mobileTemplate.setMaxSpawnDistance(8) diff --git a/src/main/NGECore.java b/src/main/NGECore.java index 788e826e..d02566ab 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -274,7 +274,8 @@ public class NGECore { options.setFilePath("options.cfg"); boolean optionsConfigLoaded = options.loadConfigFile(); - if (optionsConfigLoaded && options.getInt("CLEAN.ODB.FOLDERS") > 0 || getExcludedDevelopers().contains(System.getProperty("user.name"))){ + //if (optionsConfigLoaded && options.getInt("CLEAN.ODB.FOLDERS") > 0 || getExcludedDevelopers().contains(System.getProperty("user.name"))){ + if (optionsConfigLoaded && options.getInt("CLEAN.ODB.FOLDERS") > 0){ File baseFolder = new File("./odb"); if (baseFolder.isDirectory()) { diff --git a/src/resources/objects/creature/CreatureMessageBuilder.java b/src/resources/objects/creature/CreatureMessageBuilder.java index 33367160..37334e12 100644 --- a/src/resources/objects/creature/CreatureMessageBuilder.java +++ b/src/resources/objects/creature/CreatureMessageBuilder.java @@ -307,7 +307,7 @@ public class CreatureMessageBuilder extends TangibleMessageBuilder { SWGObject obj = NGECore.getInstance().objectService.getObject(objId); if(obj == null) { - System.err.println("Cant find obj for obj id in equip list!!!"); + System.err.println("Cant find obj for obj id in equip list!!! (Normal Message for AI wipes)"); continue; } @@ -425,7 +425,7 @@ public class CreatureMessageBuilder extends TangibleMessageBuilder { SWGObject obj = NGECore.getInstance().objectService.getObject(objId); if(obj == null) { - System.err.println("Cant find obj for obj id in equip list!!!"); + System.err.println("Cant find obj for obj id in equip list!!! (Normal Message for AI wipes)"); continue; } diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index e65109d7..b3a41960 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -1143,7 +1143,9 @@ public class CreatureObject extends TangibleObject implements Serializable { } //destination.getSession().write(messageBuilder.buildBaseline8()); //destination.getSession().write(messageBuilder.buildBaseline9()); - + + + if(destination != getClient()) { UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID(), NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), this), getFaction()); destination.getSession().write(upvpm.serialize()); diff --git a/src/resources/objects/installation/InstallationMessageBuilder.java b/src/resources/objects/installation/InstallationMessageBuilder.java index d2b1f80c..2510a7c9 100644 --- a/src/resources/objects/installation/InstallationMessageBuilder.java +++ b/src/resources/objects/installation/InstallationMessageBuilder.java @@ -27,6 +27,7 @@ import java.util.Map; import org.apache.mina.core.buffer.IoBuffer; import engine.resources.objects.Builder; +import resources.objects.harvester.HarvesterObject; import resources.objects.tangible.TangibleMessageBuilder; public class InstallationMessageBuilder extends TangibleMessageBuilder{ @@ -215,6 +216,27 @@ public class InstallationMessageBuilder extends TangibleMessageBuilder{ // 0010: 4E 49 07 12 00 00 00 02 00 09 00 00 00 00 00 05 NI.............. // 0020: 00 8A D3 79 16 00 00 0F 00 ...y..... + public IoBuffer buildCustomNameDelta(InstallationObject installation, String customName) { + IoBuffer buffer = IoBuffer.allocate(10).order(ByteOrder.LITTLE_ENDIAN); + buffer.setAutoExpand(true); + int sizeP = 8; + sizeP += 2*customName.length(); + buffer.putShort((short)5); + buffer.putInt(0x12862153); + buffer.putLong(installation.getObjectID()); + buffer.putInt(0x54414E4F); + buffer.put((byte)3); + buffer.putInt(sizeP); + buffer.putShort((short)1); + buffer.putShort((short)2); + buffer.put(getUnicodeString(customName)); + int size = buffer.position(); + buffer.flip(); + tools.CharonPacketUtils.printAnalysis(IoBuffer.allocate(size).put(buffer.array(), 0, size).flip()); + return IoBuffer.allocate(size).put(buffer.array(), 0, size).flip(); + } + + @Override public void buildBaseline3(Map baselineBuilders, Map deltaBuilders) { super.buildBaseline3(deltaBuilders, deltaBuilders); diff --git a/src/resources/objects/installation/InstallationObject.java b/src/resources/objects/installation/InstallationObject.java index b9cc98d6..12389bda 100644 --- a/src/resources/objects/installation/InstallationObject.java +++ b/src/resources/objects/installation/InstallationObject.java @@ -24,6 +24,10 @@ package resources.objects.installation; import java.io.Serializable; import java.util.Vector; +import main.NGECore; +import protocol.swg.UpdatePVPStatusMessage; +import protocol.swg.UpdatePostureMessage; + import com.sleepycat.persist.model.Entity; import engine.clients.Client; @@ -31,6 +35,7 @@ import engine.resources.scene.Planet; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; import resources.objects.ObjectMessageBuilder; +import resources.objects.creature.CreatureObject; import resources.objects.tangible.TangibleObject; @Entity(version=0) @@ -47,6 +52,18 @@ public class InstallationObject extends TangibleObject implements Serializable { @Override public void sendBaselines(Client destination) { + if(destination == null || destination.getSession() == null) { + //System.out.println("NULL session"); + return; + } + +// destination.getSession().write(messageBuilder.buildBaseline3(this)); +// destination.getSession().write(messageBuilder.buildBaseline6(this)); + + if(destination != getClient()) { + UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID(), NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), this), getFaction()); + destination.getSession().write(upvpm.serialize()); + } } @Override diff --git a/src/resources/objects/tangible/TangibleObject.java b/src/resources/objects/tangible/TangibleObject.java index 256f4071..f49dca44 100644 --- a/src/resources/objects/tangible/TangibleObject.java +++ b/src/resources/objects/tangible/TangibleObject.java @@ -48,6 +48,7 @@ import resources.objects.ObjectMessageBuilder; import resources.objects.SWGList; import resources.objects.SWGSet; import resources.objects.creature.CreatureObject; +import resources.objects.installation.InstallationObject; import tools.DevLog; import engine.clientdata.ClientFileManager; import engine.clientdata.visitors.IDManagerVisitor; @@ -344,10 +345,12 @@ public class TangibleObject extends SWGObject implements Serializable { } public void removeDefender(TangibleObject defender) { - defendersList.remove(defender); - - if (defendersList.isEmpty() && isInCombat()) { - setInCombat(false); + synchronized(objectMutex) { + defendersList.remove(defender); + + if (defendersList.isEmpty() && isInCombat()) { + setInCombat(false); + } } } @@ -390,8 +393,10 @@ public class TangibleObject extends SWGObject implements Serializable { if (observer.getParent() != null) { observer.getSession().write(new UpdatePVPStatusMessage(this.getObjectID(), NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) observer.getParent(), this), getFaction()).serialize()); - if(getClient() != null) + if(getClient() != null){ getClient().getSession().write(new UpdatePVPStatusMessage(observer.getParent().getObjectID(), NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) this, (CreatureObject) observer.getParent()), getFaction()).serialize()); + System.out.println("SENT TO CLIENT!"); + } } } @@ -409,10 +414,12 @@ public class TangibleObject extends SWGObject implements Serializable { if (((CreatureObject)this).isPlayer()){ // Here a specific CREO delta must be sent to update the faction info in character sheet and symbol in name // If anyone knows which that would be, please replace it here! + sendBaselines(this.getClient()); } } + } public boolean isAttackableBy(CreatureObject attacker) { diff --git a/src/services/DevService.java b/src/services/DevService.java index 224308a7..01d457a8 100644 --- a/src/services/DevService.java +++ b/src/services/DevService.java @@ -231,8 +231,11 @@ public class DevService implements INetworkDispatch { return; case 6: // Locations -890,4, -2994 475,6,-3019 - core.simulationService.transferToPlanet(player, core.terrainService.getPlanetByName("talus"), new Point3D(475,6,-3019), player.getOrientation(), null); - core.invasionService.testPylons(); + //core.simulationService.transferToPlanet(player, core.terrainService.getPlanetByName("talus"), new Point3D(475,6,-3019), player.getOrientation(), null); + core.simulationService.transferToPlanet(player, core.terrainService.getPlanetByName("talus"), new Point3D(618, 4, -2963), player.getOrientation(), null); + //core.simulationService.transferToPlanet(player, core.terrainService.getPlanetByName("talus"), new Point3D(-930,9, -2994), player.getOrientation(), null); + + //core.invasionService.testPylons(); return; // Character diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index 4991566c..7dfc05b2 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -289,23 +289,77 @@ public class SimulationService implements INetworkDispatch { return foundCreatures; } - public Vector getAllNearNonSameFactionNPCs(int distance, SWGObject value ){ + public Vector getAllNearNonSameFactionNPCs(int distance, SWGObject center ){ Vector foundCreatures = new Vector(); - core.simulationService.get(value.getPlanet(), value.getWorldPosition().x, value.getWorldPosition().z, distance).stream().forEach((objecta) -> { - - if (value instanceof CreatureObject){ - CreatureObject npc = (CreatureObject) value; - if (objecta instanceof CreatureObject && objecta!=npc && ((CreatureObject) objecta).getFaction().equals(npc.getFaction())) - foundCreatures.add((CreatureObject)objecta); + core.simulationService.get(center.getPlanet(), center.getWorldPosition().x, center.getWorldPosition().z, distance).stream().forEach((objecta) -> { + if (center.getObjectID()!=objecta.getObjectID()){ + String centerfaction = ""; + if (center instanceof CreatureObject) + centerfaction = ((CreatureObject)center).getFaction(); + if (center instanceof InstallationObject) + centerfaction = ((InstallationObject)center).getFaction(); + if (center instanceof TangibleObject) + centerfaction = ((TangibleObject)center).getFaction(); + + if (centerfaction.length()>0 && objecta instanceof CreatureObject){ + if (objecta.getObjectID()!=center.getObjectID() && NGECore.getInstance().factionService.isFactionEnemy((CreatureObject) objecta,(TangibleObject) center)) + foundCreatures.add((CreatureObject)objecta); + } } - - if (value instanceof InstallationObject){ - InstallationObject ins = (InstallationObject) value; - if (objecta instanceof CreatureObject && objecta!=ins && ((CreatureObject) objecta).getFaction().equals(ins.getFaction())) - foundCreatures.add((CreatureObject)objecta); + }); + return foundCreatures; + } + + public Vector getAllNearNonSameFactionPlayers(int distance, SWGObject center ){ + Vector foundCreatures = new Vector(); + core.simulationService.get(center.getPlanet(), center.getWorldPosition().x, center.getWorldPosition().z, distance).stream().forEach((objecta) -> { + if (center.getObjectID()!=objecta.getObjectID()){ + String centerfaction = ""; + if (center instanceof CreatureObject) + centerfaction = ((CreatureObject)center).getFaction(); + if (center instanceof InstallationObject) + centerfaction = ((InstallationObject)center).getFaction(); + if (center instanceof TangibleObject) + centerfaction = ((TangibleObject)center).getFaction(); + + if (centerfaction.length()>0 && objecta instanceof CreatureObject){ + if (((CreatureObject)objecta).isPlayer() && objecta.getObjectID()!=center.getObjectID() && NGECore.getInstance().factionService.isFactionEnemy((CreatureObject) objecta,(TangibleObject) center)) + foundCreatures.add((CreatureObject)objecta); + } } - } - ); + }); + return foundCreatures; + } + + public Vector getAllNearSameFactionNPCs(int distance, SWGObject center ){ + Vector foundCreatures = new Vector(); + core.simulationService.get(center.getPlanet(), center.getWorldPosition().x, center.getWorldPosition().z, distance).stream().forEach((objecta) -> { + + String centerfaction = ""; + if (center instanceof CreatureObject) + centerfaction = ((CreatureObject)center).getFaction(); + if (center instanceof InstallationObject) + centerfaction = ((InstallationObject)center).getFaction(); + if (center instanceof TangibleObject) + centerfaction = ((TangibleObject)center).getFaction(); + + if (centerfaction.length()>0 && objecta instanceof CreatureObject){ + if (objecta.getObjectID()!=center.getObjectID() && NGECore.getInstance().factionService.isFactionAlly((TangibleObject) objecta,(TangibleObject) center)) + foundCreatures.add((CreatureObject)objecta); + } + }); + return foundCreatures; + } + + public Vector getAllNearSameFactionPlayers(int distance, Point3D centerPos, Planet planet, String factionName){ + Vector foundCreatures = new Vector(); + core.simulationService.get(planet, centerPos.x, centerPos.z, distance).stream().forEach((objecta) -> { + + if (factionName.length()>0 && objecta instanceof CreatureObject){ + if (((CreatureObject)objecta).isPlayer() && NGECore.getInstance().factionService.isFactionAlly(((CreatureObject) objecta).getFaction(),factionName)) + foundCreatures.add((CreatureObject)objecta); + } + }); return foundCreatures; } @@ -319,23 +373,25 @@ public class SimulationService implements INetworkDispatch { return foundTANOs; } - public Vector getAllNearNonSameFactionTANOs(int distance, SWGObject value ){ + public Vector getAllNearNonSameFactionTANOs(int distance, SWGObject center ){ Vector foundTANOs = new Vector(); - core.simulationService.get(value.getPlanet(), value.getWorldPosition().x, value.getWorldPosition().z, distance).stream().forEach((objecta) -> { - - if (value instanceof CreatureObject){ - CreatureObject npc = (CreatureObject) value; - if (objecta instanceof CreatureObject && objecta!=npc && ((CreatureObject) objecta).getFaction().equals(npc.getFaction())) + core.simulationService.get(center.getPlanet(), center.getWorldPosition().x, center.getWorldPosition().z, distance).stream().forEach((objecta) -> { + + //if (objecta.getTemplate().contains("shared_adv_turret_dish_sm_heat")){ + String centerfaction = ""; + if (center instanceof CreatureObject) + centerfaction = ((CreatureObject)center).getFaction(); + if (center instanceof InstallationObject) + centerfaction = ((InstallationObject)center).getFaction(); + if (center instanceof TangibleObject) + centerfaction = ((TangibleObject)center).getFaction(); + + if (centerfaction.length()>0 && objecta instanceof TangibleObject && !(objecta instanceof CreatureObject)){ + if (objecta.getObjectID()!=center.getObjectID() && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject) objecta,(TangibleObject) center)) foundTANOs.add((TangibleObject)objecta); - } - - if (value instanceof InstallationObject){ - InstallationObject ins = (InstallationObject) value; - if (objecta instanceof CreatureObject && objecta!=ins && ((CreatureObject) objecta).getFaction().equals(ins.getFaction())) - foundTANOs.add((TangibleObject)objecta); - } - } - ); + } + + }); return foundTANOs; } @@ -756,6 +812,15 @@ public class SimulationService implements INetworkDispatch { add(object, newPosition.x, newPosition.z); } + if (object.getPlanet().getName().equals("talus") && object.getTemplate().contains("stormtrooper")){ +// float xx = object.getWorldPosition().x - newPosition.x; +// float zz = object.getWorldPosition().z - newPosition.z; +// float diff = (float) Math.sqrt(xx*xx+zz*zz); +// System.out.println(" ((CreatureObject)object).getSpeedMultiplierBase());: " + ((CreatureObject)object).getSpeedMultiplierBase()); +// System.out.println(" ((CreatureObject)object).getSpeedMultiplierMod());: " + ((CreatureObject)object).getSpeedMultiplierMod()); +// + } + UpdateTransformMessage utm = new UpdateTransformMessage(object.getObjectID(), (short) (newPosition.x * 4 + 0.5), (short) (newPosition.y * 4 + 0.5), (short) (newPosition.z * 4 + 0.5), movementCounter + 1, getSpecialDirection(newOrientation), speed); List newAwareObjects = get(object.getPlanet(), newPosition.x, newPosition.z, 512); @@ -1278,6 +1343,80 @@ public class SimulationService implements INetworkDispatch { return true; } + + public boolean checkLineOfSight2(SWGObject obj1, Point3D obj2) { + long startTime = System.nanoTime(); + + float heightOrigin = 1.f; + float heightDirection = 1.f; + + if(obj1 instanceof CreatureObject) + heightOrigin = getHeightOrigin((CreatureObject) obj1); + + Point3D position1 = obj1.getWorldPosition(); + Point3D position2 = obj2; + + Point3D origin = new Point3D(position1.x, position1.y + heightOrigin, position1.z); + Point3D end = new Point3D(position2.x, position2.y + heightDirection, position2.z); + float distance = position1.getDistance2D(position2); + + List inRangeObjects = get(obj1.getPlanet(), position1.x, position1.z, (int) (distance + 10)); + + for(SWGObject object : inRangeObjects) { + + if(object == obj1) + continue; + + if(object.getTemplateData() != null && object.getTemplateData().getAttribute("collisionActionBlockFlags") != null) { + int bit = (Integer) object.getTemplateData().getAttribute("collisionActionBlockFlags") & 255; + if(bit == (Integer) object.getTemplateData().getAttribute("collisionActionBlockFlags")) + continue; + } + + Ray ray = convertRayToModelSpace(origin, end, object); + + MeshVisitor visitor = object.getMeshVisitor(); + + if(visitor == null) + continue; + + List tris = visitor.getTriangles(); + + if(tris.isEmpty()) + continue; + + for(Mesh3DTriangle tri : tris) { + + if(ray.intersectsTriangle(tri, distance) != null) { + //System.out.println("Collision took: " + (System.nanoTime() - startTime) + " ns (collided)"); + // System.out.println("Collided with " + object.getTemplate() + " X: " + object.getPosition().x + " Y: " + object.getPosition().y + " Z: " + object.getPosition().z); + return false; + } + + } + + } + + List segments = new ArrayList(); + Line3D.splitIntoSegments(new Vec3D(position1.x, position1.y + 1, position1.z), new Vec3D(position2.x, position2.y + 1, position2.z), (float) 1, segments, true); + + for(Vec3D segment : segments) { + float y = segment.y; + + int height = (int) core.terrainService.getHeight(obj1.getPlanetId(), segment.x, segment.z); // round down to int + + if(height > y) { + //System.out.println("Collision took: " + (System.nanoTime() - startTime) + " ns (terrain collision)"); + return false; + } + } + //System.out.println("Collision took: " + (System.nanoTime() - startTime) + " ns (did not collide)"); + + return true; + + } + + public boolean checkLineOfSight(SWGObject obj1, SWGObject obj2) { long startTime = System.nanoTime(); if(obj1.getPlanet() != obj2.getPlanet()) diff --git a/src/services/ai/AIActor.java b/src/services/ai/AIActor.java index cc39d5e0..99d1f4e5 100644 --- a/src/services/ai/AIActor.java +++ b/src/services/ai/AIActor.java @@ -87,8 +87,15 @@ public class AIActor { private ScheduledFuture recoveryFuture; private ScheduledFuture despawnFuture; private boolean patrolLoop = true; // default + private TangibleObject lastTarget = null; + private Point3D repositionLocation; + private long repositionStartTime = 0L; + private long actorID = 0L; + private static long autoActorID = 0L; + private boolean actorAlive = true; public AIActor(CreatureObject creature, Point3D spawnPosition, ScheduledExecutorService scheduler) { + actorID = autoActorID++; this.creature = creature; this.spawnPosition = spawnPosition; setLastPositionBeforeStateChange(spawnPosition); // just to make sure it's initialized @@ -117,12 +124,12 @@ public class AIActor { if(creature == null || creature.getObservers().isEmpty() || creature.isInCombat() || isStalking) return; if (creature.getAttachment("tamed")!=null){ - DevLog.debugout("Charon", "Pet AI", "aggroCheckTask tamed==1"); + DevLog.debugoutai(this, "Charon", "Pet AI", "aggroCheckTask tamed==1"); return; } if (creature.getCustomName().contains("baby")) - DevLog.debugout("Charon", "Pet AI", "baby aggroCheckTask should not be here " +creature.getAttachment("tamed")); + DevLog.debugoutai(this, "Charon", "Pet AI", "baby aggroCheckTask should not be here " +creature.getAttachment("tamed")); creature.getObservers().stream().map(Client::getParent).filter(obj -> obj.inRange(creature.getWorldPosition(), 15)).forEach((obj) -> { if(new Random().nextFloat() <= 0.5 || creature.isInCombat() || isStalking) { @@ -177,9 +184,9 @@ public class AIActor { } if (addedObject.getPosture() != 13 && addedObject.getPosture() != 14 && ! addedObject.getOption(Options.INVULNERABLE)){ addDefender(addedObject); - DevLog.debugout("Charon", "faction creature ", "added " + creature.getFaction()); - DevLog.debugout("Charon", "faction obj", "added " + ((TangibleObject)obj).getFaction()); - DevLog.debugout("Charon", "factionCheckTask", "added " + obj.getCustomName()); + DevLog.debugoutai(this,"Charon", "faction creature ", "added " + creature.getFaction()); + DevLog.debugoutai(this,"Charon", "faction obj", "added " + ((TangibleObject)obj).getFaction()); + DevLog.debugoutai(this,"Charon", "factionCheckTask", "added " + obj.getCustomName()); } } @@ -202,9 +209,9 @@ public class AIActor { } if (addedObject.getPosture() != 13 && addedObject.getPosture() != 14 & ! addedObject.getOption(Options.INVULNERABLE)){ addDefender(addedObject); - DevLog.debugout("Charon", "faction creature ", "added " + creature.getFaction()); - DevLog.debugout("Charon", "faction obj", "added " + ((TangibleObject)obj).getFaction()); - DevLog.debugout("Charon", "factionCheckTask", "added " + obj.getCustomName()); + DevLog.debugoutai(this,"Charon", "faction creature ", "added " + creature.getFaction()); + DevLog.debugoutai(this,"Charon", "faction obj", "added " + ((TangibleObject)obj).getFaction()); + DevLog.debugoutai(this,"Charon", "factionCheckTask", "added " + obj.getCustomName()); } } } @@ -212,23 +219,23 @@ public class AIActor { NGECore.getInstance().simulationService.getAllNearNonSameFactionTANOs(15, creature).forEach((obj) -> { if(new Random().nextFloat() <= 0.5 || creature.isInCombat()) { - DevLog.debugout("Charon", "TANO1 CHECK", creature.getTemplate() + " spotted near " + obj.getTemplate()); + DevLog.debugoutai(this,"Charon", "TANO1 CHECK", creature.getTemplate() + " spotted near " + obj.getTemplate()); // DevLog.debugout("Charon", "TANO CHECK faction obj", "added " + ((TangibleObject)obj).getFaction()); // DevLog.debugout("Charon", "TANO CHECK factionCheckTask", "added " + obj.getCustomName()); // DevLog.debugout("Charon", "TANO CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)); if (obj instanceof TangibleObject && !(obj instanceof CreatureObject) && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)){ TangibleObject addedObject = (TangibleObject) obj; addDefender(addedObject); - DevLog.debugout("Charon", "TANO1 faction ", creature.getTemplate() + "added " + creature.getFaction()); - DevLog.debugout("Charon", "TANO1 faction obj", "added " + ((TangibleObject)obj).getFaction()); - DevLog.debugout("Charon", "TANO1 factionCheckTask", "added " + obj.getCustomName()); + DevLog.debugoutai(this,"Charon", "TANO1 faction ", creature.getTemplate() + "added " + creature.getFaction()); + DevLog.debugoutai(this,"Charon", "TANO1 faction obj", "added " + ((TangibleObject)obj).getFaction()); + DevLog.debugoutai(this,"Charon", "TANO1 factionCheckTask", "added " + obj.getCustomName()); } } }); } catch (Exception e) { e.printStackTrace(); } - }, 0, 5000, TimeUnit.MILLISECONDS); + }, 0, 3000, TimeUnit.MILLISECONDS); } } @@ -261,7 +268,7 @@ public class AIActor { creature.addDefender(defender); if(followObject == null) setFollowObject(defender); - System.out.println("getFollowObject "+ getFollowObject().getTemplate()); + DevLog.debugoutai(this,"Charon", "AI addDefender", "getFollowObject " + getFollowObject().getTemplate()); setCurrentState(new AttackState()); if(!isAssisting) { NGECore.getInstance().simulationService.get(creature.getPlanet(), creature.getWorldPosition().x, creature.getWorldPosition().z, 38).stream().filter((obj) -> @@ -308,6 +315,7 @@ public class AIActor { if(this.currentState != null) doStateAction(this.currentState.onExit(this)); this.currentState = currentState; + DevLog.debugoutai(this,"Charon", "AI Actor setCurrentState", "setCurrentState " + currentState.getClass().getName()); doStateAction(currentState.onEnter(this)); } catch (Exception e) { e.printStackTrace(); @@ -339,23 +347,35 @@ public class AIActor { } public void scheduleMovement() { + // Catch current state BEFORE waiting 500ms for execution, + // as the state could have changed in that time resulting in + // undesired additional movement loops + AIState caughtAIState = currentState; + if (!actorAlive) + return; movementFuture = scheduler.schedule(() -> { try { if (creature==null){ destroyActor(); return; } - doStateAction(currentState.move(AIActor.this)); + if (caughtAIState.getClass().equals(currentState.getClass())) + doStateAction(caughtAIState.move(AIActor.this)); } catch (Exception e) { + System.out.println("Exception in scheduleMovement"); e.printStackTrace(); } }, 500, TimeUnit.MILLISECONDS); } public void scheduleRecovery() { + AIState caughtAIState = currentState; + if (!actorAlive) + return; recoveryFuture = scheduler.schedule(() -> { try { - doStateAction(currentState.recover(AIActor.this)); + if (caughtAIState.getClass().equals(currentState.getClass())) + doStateAction(caughtAIState.recover(AIActor.this)); } catch (Exception e) { e.printStackTrace(); } @@ -373,6 +393,13 @@ public class AIActor { damageMap.put(attacker, damageMap.get(attacker) + event.damage); else damageMap.put(attacker, event.damage); + + // Put AI into combat state if it is not yet and damaged + if (!creature.isInCombat()){ + creature.setInCombat(true); + if (this.getHighestDamageDealer()!=null) + addDefender(this.getHighestDamageDealer()); + } } public Map getDamageMap() { @@ -494,6 +521,13 @@ public class AIActor { public void destroyActor(){ creature.getEventBus().unsubscribe(this); + if (creature!=null){ + if (despawnFuture!=null){ + despawnFuture.cancel(true); + despawnFuture = null; + } + } + // Make sure to kill all AI helper threads if (aggroCheckTask!=null) aggroCheckTask.cancel(true); @@ -508,11 +542,7 @@ public class AIActor { if (movementFuture!=null){ recoveryFuture.cancel(true); recoveryFuture = null; - } - if (despawnFuture!=null){ - despawnFuture.cancel(true); - despawnFuture = null; - } + } } public void cancelAggro(){ @@ -659,5 +689,40 @@ public class AIActor { public void setPatrolLoop(boolean patrolLoop) { this.patrolLoop = patrolLoop; } - + + public TangibleObject getLastTarget() { + return lastTarget; + } + + public void setLastTarget(TangibleObject lastTarget) { + this.lastTarget = lastTarget; + } + + public Point3D getRepositionLocation() { + return repositionLocation; + } + + public void setRepositionLocation(Point3D repositionLocation) { + this.repositionLocation = repositionLocation; + } + + public long getRepositionStartTime() { + return repositionStartTime; + } + + public void setRepositionStartTime(long repositionStartTime) { + this.repositionStartTime = repositionStartTime; + } + + public long getActorID() { + return actorID; + } + + public boolean isActorAlive() { + return actorAlive; + } + + public void setActorAlive(boolean actorAlive) { + this.actorAlive = actorAlive; + } } diff --git a/src/services/ai/AIService.java b/src/services/ai/AIService.java index c5b15137..69749a51 100644 --- a/src/services/ai/AIService.java +++ b/src/services/ai/AIService.java @@ -33,6 +33,7 @@ import resources.datatables.GcwType; import resources.objects.creature.CreatureObject; import resources.objects.group.GroupObject; import resources.objects.player.PlayerObject; +import resources.objects.tangible.TangibleObject; import services.ai.states.AIState; import services.ai.states.IdleState; import services.ai.states.LoiterState; @@ -45,6 +46,7 @@ public class AIService { private Vector aiActors = new Vector(); private NGECore core; + private TangibleObject checkerAI = null; public AIService(NGECore core) { this.core = core; @@ -187,6 +189,8 @@ public class AIService { AIState intendedPrimaryAIState = new PatrolState(); actor.setIntendedPrimaryAIState(intendedPrimaryAIState); actor.setCurrentState(intendedPrimaryAIState); + actor.setCurrentState(intendedPrimaryAIState); + actor.setCurrentState(intendedPrimaryAIState); } public void setPatrol(CreatureObject creature, boolean active){ @@ -218,6 +222,14 @@ public class AIService { actor.setCurrentState(intendedPrimaryAIState); } + public void setCheckAI(TangibleObject checker){ + checkerAI = checker; + } + + public TangibleObject getCheckAI(){ + return this.checkerAI; + } + public void logAI(String logMsg){ if (checkDeveloperIdentity()){ System.err.println("AI-LOG: " + logMsg); diff --git a/src/services/ai/TurretAIActor.java b/src/services/ai/TurretAIActor.java index 6d204ff9..57b04866 100644 --- a/src/services/ai/TurretAIActor.java +++ b/src/services/ai/TurretAIActor.java @@ -41,6 +41,7 @@ import resources.objects.installation.InstallationObject; import resources.objects.tangible.TangibleObject; import services.ai.states.TurretAIState; import services.ai.states.TurretAIState.StateResult; +import services.ai.states.AIState; import services.ai.states.TurretAttackState; import services.ai.states.TurretIdleState; import services.combat.CombatEvents.DamageTaken; @@ -98,12 +99,12 @@ public class TurretAIActor { if(creature == null || creature.getObservers().isEmpty() || creature.isInCombat() || isStalking) return; if (creature.getAttachment("tamed")!=null){ - DevLog.debugout("Charon", "Pet AI", "aggroCheckTask tamed==1"); + DevLog.debugoutai(this, "Charon", "Pet AI", "aggroCheckTask tamed==1"); return; } if (creature.getCustomName().contains("baby")) - DevLog.debugout("Charon", "Pet AI", "baby aggroCheckTask should not be here " +creature.getAttachment("tamed")); + DevLog.debugoutai(this, "Charon", "Pet AI", "baby aggroCheckTask should not be here " +creature.getAttachment("tamed")); creature.getObservers().stream().map(Client::getParent).filter(obj -> obj.inRange(creature.getWorldPosition(), 60)).forEach((obj) -> { if(new Random().nextFloat() <= 0.5 || creature.isInCombat() || isStalking) { @@ -132,11 +133,11 @@ public class TurretAIActor { } catch (Exception e) { e.printStackTrace(); } - }, 0, 5000, TimeUnit.MILLISECONDS); + }, 0, 2000, TimeUnit.MILLISECONDS); } if(creature.getFaction().length()>0 || !creature.getOption(Options.AGGRESSIVE)) { factionCheckTask = scheduler.scheduleAtFixedRate(() -> { - System.out.println("Turret faction thread"); + //System.out.println("Turret faction thread"); try { if(creature == null || creature.getFactionStatus()!=FactionStatus.Combatant || creature.getObservers().isEmpty() || creature.isInCombat()) @@ -167,7 +168,7 @@ public class TurretAIActor { } }); - NGECore.getInstance().simulationService.getAllNearNPCs(60, creature).forEach((obj) -> { + NGECore.getInstance().simulationService.getAllNearNonSameFactionNPCs(60, creature).forEach((obj) -> { if(new Random().nextFloat() <= 0.5 || creature.isInCombat()) { // DevLog.debugout("Charon", "TURRET CHECK faction creature ", "added " + creature.getFaction()); // DevLog.debugout("Charon", "TURRET CHECK faction obj", "added " + ((TangibleObject)obj).getFaction()); @@ -191,25 +192,25 @@ public class TurretAIActor { } }); - NGECore.getInstance().simulationService.getAllNearTANOs(60, creature).forEach((obj) -> { + NGECore.getInstance().simulationService.getAllNearNonSameFactionTANOs(60, creature).forEach((obj) -> { if(new Random().nextFloat() <= 0.5 || creature.isInCombat()) { - DevLog.debugout("Charon", "TANO CHECK faction creature ", "added " + creature.getFaction()); - DevLog.debugout("Charon", "TANO CHECK faction obj", "added " + ((TangibleObject)obj).getFaction()); - DevLog.debugout("Charon", "TANO CHECK factionCheckTask", "added " + obj.getCustomName()); - DevLog.debugout("Charon", "TANO CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)); +// DevLog.debugout("Charon", "TANO CHECK faction creature ", "added " + creature.getFaction()); +// DevLog.debugout("Charon", "TANO CHECK faction obj", "added " + ((TangibleObject)obj).getFaction()); +// DevLog.debugout("Charon", "TANO CHECK factionCheckTask", "added " + obj.getCustomName()); +// DevLog.debugout("Charon", "TANO CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)); if (obj instanceof TangibleObject && !(obj instanceof CreatureObject) && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)){ TangibleObject addedObject = (TangibleObject) obj; addDefender(addedObject); - DevLog.debugout("Charon", "TANO faction creature ", "added " + creature.getFaction()); - DevLog.debugout("Charon", "TANO faction obj", "added " + ((TangibleObject)obj).getFaction()); - DevLog.debugout("Charon", "TANO factionCheckTask", "added " + obj.getCustomName()); + DevLog.debugoutai(this, "Charon", "TANO faction creature ", "added " + creature.getFaction()); + DevLog.debugoutai(this, "Charon", "TANO faction obj", "added " + ((TangibleObject)obj).getFaction()); + DevLog.debugoutai(this, "Charon", "TANO factionCheckTask", "added " + obj.getCustomName()); } } }); } catch (Exception e) { e.printStackTrace(); } - }, 0, 5000, TimeUnit.MILLISECONDS); + }, 0, 1000, TimeUnit.MILLISECONDS); } } @@ -319,9 +320,11 @@ public class TurretAIActor { } public void scheduleRecovery() { + TurretAIState caughtAIState = currentState; recoveryFuture = scheduler.schedule(() -> { try { - doStateAction(currentState.recover(TurretAIActor.this)); + if (caughtAIState.getClass().equals(currentState.getClass())) + doStateAction(currentState.recover(TurretAIActor.this)); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/services/ai/states/AIState.java b/src/services/ai/states/AIState.java index f5f74585..5ba3ca2b 100644 --- a/src/services/ai/states/AIState.java +++ b/src/services/ai/states/AIState.java @@ -33,6 +33,7 @@ import resources.objects.creature.CreatureObject; import resources.objects.tangible.TangibleObject; import resources.objects.weapon.WeaponObject; import services.ai.AIActor; +import tools.DevLog; public abstract class AIState { @@ -41,6 +42,11 @@ public abstract class AIState { public abstract byte move(AIActor actor) throws Exception; public abstract byte recover(AIActor actor) throws Exception; + public static long lastExecutionTime = 0L; + public static long stateID = 0L; + public static long autoStateID = 0L; + + public enum StateResult {; // default error state result @@ -61,6 +67,162 @@ public abstract class AIState { public boolean findNewPosition(AIActor actor, float speed, float stopDistance, Point3D newPosition) { + speed *= 0.5; // 2 updates per second + CreatureObject creature = actor.getCreature(); + if (!actor.isActorAlive()) + return false; // Suppress any further movement when actor is destroyed to prevent reappearing + NGECore core = NGECore.getInstance(); + Point3D currentPosition = creature.getPosition(); + Point3D targetPosition = null; + float maxDistance = stopDistance; + boolean finished = false; + float dx, dz, newX = 0, newY = 0, newZ = 0; + Vector movementPoints = actor.getMovementPoints(); + Vector patrolPoints = actor.getPatrolPoints(); + CellObject cell = null; + //while(!finished && movementPoints.size() != 0) { + + if ((!(actor.getCurrentState() instanceof FollowState)) && movementPoints.size() == 0 && patrolPoints.size() == 0) { + DevLog.debugoutai(actor, "Charon", "AI State findnewpos", "Breakout1"); + return false; + } + + if (movementPoints.size() != 0){ + try{ + targetPosition = movementPoints.firstElement(); + } catch (NoSuchElementException e) { + targetPosition = currentPosition; + } + } + + if (actor.getCurrentState().getClass().equals(PatrolState.class)){ + targetPosition = patrolPoints.get(actor.getPatrolPointIndex()); + } + + if (actor.getCurrentState().getClass().equals(FollowState.class)){ + targetPosition = actor.getFollowObject().getWorldPosition(); + } + + Vector path = core.aiService.findPath(creature.getPlanetId(), currentPosition, targetPosition); + + if (targetPosition==null){ + DevLog.debugoutai(actor, "Charon", "AI State findnewpos", "Breakout2"); + return false; + } + float distanceToTarget = targetPosition.getWorldPosition().getDistance(creature.getWorldPosition()); + + if(distanceToTarget > stopDistance) { + maxDistance = Math.min(speed, distanceToTarget - stopDistance); + } else { + /* + DevLog.debugoutai(actor, "Charon", "AI State findnewpos", "Breakout3"); + if (actor.getCurrentState().getClass().equals(RetreatState.class)){ + if(actor.getIntendedPrimaryAIState().equals(PatrolState.class)){ + actor.setCurrentState(new PatrolState()); + } + if(actor.getIntendedPrimaryAIState().equals(FollowState.class)){ + actor.setCurrentState(new FollowState()); + } + if(actor.getIntendedPrimaryAIState().equals(LoiterState.class)){ + actor.setCurrentState(new LoiterState()); + } + } + */ + return false; + } + + Point3D oldPosition = null; + float pathDistance = 0; + + + + for(int i = 1; i < path.size() && !finished; i++) { + + Point3D currentPathPosition = path.get(i); + cell = currentPathPosition.getCell(); + + if(oldPosition == null) + oldPosition = path.get(0); + Point3D oldWorldPos = oldPosition.getWorldPosition(); + + pathDistance += oldWorldPos.getDistance(currentPathPosition.getWorldPosition()); + if(pathDistance >= maxDistance || i == path.size() - 1 || currentPathPosition.getCell() != creature.getContainer()) { + + finished = true; + + if(movementPoints.size() != 0 && currentPosition.getWorldPosition().getDistance(currentPathPosition.getWorldPosition()) <= stopDistance && cell == creature.getContainer()) { + if(i == path.size() - 1 && movementPoints.size()>0) + movementPoints.remove(0); + finished = false; + } else { + + if(cell == null) + oldPosition = oldPosition.getWorldPosition(); + else { + if(oldPosition.getCell() == null) + oldPosition = core.simulationService.convertPointToModelSpace(oldPosition, cell.getContainer()); + } + + if(pathDistance > maxDistance) { + + float distance = oldWorldPos.getDistance(currentPathPosition.getWorldPosition()); + float travelDistance = distance - (pathDistance - maxDistance); + // temp fix for melee npcs + travelDistance *= 1.3; + if(travelDistance <= 0) { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + } else { + + if(distance > 0) { + dx = currentPathPosition.x - oldPosition.x; + dz = currentPathPosition.z - oldPosition.z; + float deltaDist = (float) Math.sqrt((dx * dx) + (dz * dz)); + + + newX = (float) (oldPosition.x + (speed * (dx / deltaDist))); + newZ = (float) (oldPosition.z + (speed * (dz / deltaDist))); + +// if (creature.getPlanet().getName().equals("talus") && creature.getTemplate().contains("stormtrooper")){ +// float magnitude = (float)Math.sqrt(newX*newX + newZ*newZ); +// System.out.println("magnitude: " + magnitude); +// } + + } else { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + } + + } + + if(cell == null) { + float height = core.terrainService.getHeight(creature.getPlanetId(), newX, newZ); + newY = height; + } else { + newY = currentPathPosition.y; + } + } + } + + } else { + newX = currentPathPosition.x; + newZ = currentPathPosition.z; + newY = core.terrainService.getHeight(creature.getPlanetId(), newX, newZ); + } + oldPosition = currentPathPosition; + } + //} + newPosition.x = newX; + newPosition.y = newY; + newPosition.z = newZ; + newPosition.setCell(cell); + + return true; + } + + + public boolean findNewLOSPosition(AIActor actor, float speed, float stopDistance, Point3D newPosition) { + speed *= 0.5; // 2 updates per second CreatureObject creature = actor.getCreature(); NGECore core = NGECore.getInstance(); @@ -96,6 +258,41 @@ public abstract class AIState { Vector path = core.aiService.findPath(creature.getPlanetId(), currentPosition, targetPosition); + if (targetPosition==null) + return false; + if (actor.getFollowObject()==null) + return false; + + int attempts = 0; + float LOSdistance = targetPosition.getWorldPosition().getDistance(actor.getFollowObject().getWorldPosition()); + Point3D LOSorigin = actor.getFollowObject().getWorldPosition(); + float deltaX = actor.getFollowObject().getWorldPosition().x-targetPosition.getWorldPosition().x; + float deltaZ = actor.getFollowObject().getWorldPosition().z-targetPosition.getWorldPosition().z; + float originAngle = (float) (Math.atan2(deltaX,deltaZ)); + int sign = 0; + while (!core.simulationService.checkLineOfSight(actor.getFollowObject(),targetPosition) && attempts<160){ + + float angle = 0; + if (sign==0){ + angle = originAngle + attempts; + sign = 1; + } else { + angle = originAngle - attempts; + sign = 0; + } + if (actor.getFollowObject() instanceof CreatureObject){ + if (((CreatureObject)actor.getFollowObject()).isPlayer()){ + System.out.println("CORRECTING LOS"); + } + } + + + targetPosition = new Point3D((float) (LOSorigin.x + LOSdistance * Math.cos(angle)), 0, (float) (LOSorigin.z + LOSdistance * Math.sin(angle))); + attempts++; + } + + + float distanceToTarget = targetPosition.getWorldPosition().getDistance(creature.getWorldPosition()); if(distanceToTarget > stopDistance) { @@ -441,7 +638,9 @@ public abstract class AIState { maxDistance = 1; Point3D newPosition = new Point3D(); - boolean foundNewPos = findNewPosition(actor, speed, maxDistance, newPosition); + + boolean foundNewPos = false; + foundNewPos = findNewPosition(actor, speed, maxDistance, newPosition); if(!foundNewPos || (newPosition.x == 0 && newPosition.z == 0)) return; @@ -456,19 +655,74 @@ public abstract class AIState { quaternion.w *= -1; } + core.simulationService.moveObject(creature, newPosition, quaternion, creature.getMovementCounter(), speed, newPosition.getCell()); + } + + public void doReposition(AIActor actor){ + + NGECore core = NGECore.getInstance(); + + CreatureObject creature = actor.getCreature(); + if(creature.getPosture() == 14 || creature.getPosture() == 13) { + actor.setFollowObject(null); + return; + } + TangibleObject target = actor.getLastTarget(); + float speed = (float) creature.getRunSpeed(); + float maxDistance = 6; + if(creature.getWeaponId() != 0) { + WeaponObject weapon = (WeaponObject) core.objectService.getObject(creature.getWeaponId()); + if(weapon != null) + maxDistance = weapon.getMaxRange() - 1; + } else if(creature.getSlottedObject("default_weapon") != null) { + WeaponObject weapon = (WeaponObject) creature.getSlottedObject("default_weapon"); + if(weapon != null) + maxDistance = weapon.getMaxRange() - 1; + } + Point3D currentPosition = creature.getWorldPosition(); + + if(target != null && !core.simulationService.checkLineOfSight(creature, target)) + maxDistance = 1; + + Point3D newPosition = actor.getRepositionLocation(); + + if(newPosition.x == 0 && newPosition.z == 0) + return; + + Point3D newWorldPos = newPosition.getWorldPosition(); + float direction = (float) Math.atan2(newWorldPos.x - currentPosition.x, newWorldPos.z - currentPosition.z); + if(direction < 0) + direction = (float) (2 * Math.PI + direction); + Quaternion quaternion = new Quaternion((float) Math.cos(direction / 2), 0, (float) Math.sin(direction / 2), 0); + if (quaternion.y < 0.0f && quaternion.w > 0.0f) { + quaternion.y *= -1; + quaternion.w *= -1; + } + core.simulationService.moveObject(creature, newPosition, quaternion, creature.getMovementCounter(), speed, newPosition.getCell()); } public void doPatrol(AIActor actor) { //NGECore.getInstance().aiService.logAI("AI STATE doPatrol"); + NGECore core = NGECore.getInstance(); CreatureObject creature = actor.getCreature(); +// if (creature.getPlanet().getName().equals("talus") && creature.getTemplate().contains("stormtrooper")){ +// System.out.println("actor " + actor.getActorID() + " stateID " + stateID + " creatureID"+ creature.getObjectID()+ " TIMEDIFF: " + (System.currentTimeMillis()-lastExecutionTime)); +// lastExecutionTime = System.currentTimeMillis(); +// } if(creature.getPosture() == 14 || creature.getPosture() == 13) { actor.setFollowObject(null); return; } + + if (creature.isInCombat()){ + return; + } + + TangibleObject target = actor.getFollowObject(); float speed = (float) creature.getWalkSpeed(); float maxDistance = 6; @@ -488,22 +742,32 @@ public abstract class AIState { // Manage Patrol points maxDistance = 1; + if (actor.getPatrolPoints().size()==0) + return; Point3D currentDestination = actor.getPatrolPoints().get(actor.getPatrolPointIndex()); - //System.out.println("currentPosition.getDistance2D(currentDestination)<1) " + currentPosition.getDistance2D(currentDestination)); + //System.out.println("currentPosition.getDistance2D(currentDestination) " + currentPosition.getDistance2D(currentDestination)); if (currentPosition.getDistance2D(currentDestination)<2){ if (actor.getPatrolPointIndex() 128 || NGECore.getInstance().terrainService.isWater(creature.getPlanetId(), actor.getFollowObject().getWorldPosition())) { + Point3D checkPosition = actor.getSpawnPosition().getWorldPosition(); // IdleState default + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + checkPosition = creature.getWorldPosition(); + if (actor.getIntendedPrimaryAIState().getClass().equals(FollowState.class)) + checkPosition = creature.getWorldPosition(); + + if(checkPosition.getDistance(creature.getWorldPosition()) > 128 || NGECore.getInstance().terrainService.isWater(creature.getPlanetId(), actor.getFollowObject().getWorldPosition())) { actor.removeDefender(actor.getFollowObject()); //actor.scheduleMovement(); - return StateResult.UNFINISHED; + //return StateResult.UNFINISHED; + return StateResult.FINISHED; } float maxDistance = 0; if(creature.getWeaponId() != 0) { @@ -80,19 +94,20 @@ public class AttackState extends AIState { maxDistance = weapon.getMaxRange() - 1; } try{ - if(actor.getFollowObject().getWorldPosition().getDistance(creature.getWorldPosition()) > maxDistance) + if(actor.getFollowObject().getWorldPosition().getDistance(creature.getWorldPosition()) > maxDistance){ actor.setNextPosition(actor.getFollowObject().getPosition()); - else { + // find los pos + } else { //recover(actor); actor.faceObject(actor.getFollowObject()); actor.scheduleMovement(); return StateResult.UNFINISHED; } } catch (Exception e){ - DevLog.debugout("Charon", "AI Attack State Exception move method", "actor " + actor); - DevLog.debugout("Charon", "AI Attack State Exception move method", "actor.getFollowObject() " + actor.getFollowObject()); - DevLog.debugout("Charon", "AI Attack State Exception move method", "actor.getFollowObject().getWorldPosition() " + actor.getFollowObject().getWorldPosition()); - DevLog.debugout("Charon", "AI Attack State Exception move method", "creature.getWorldPosition() " + creature.getWorldPosition()); + DevLog.debugoutai(actor, "Charon", "AI Attack State Exception move method", "actor " + actor); + DevLog.debugoutai(actor, "Charon", "AI Attack State Exception move method", "actor.getFollowObject() " + actor.getFollowObject()); + DevLog.debugoutai(actor, "Charon", "AI Attack State Exception move method", "actor.getFollowObject().getWorldPosition() " + actor.getFollowObject().getWorldPosition()); + DevLog.debugoutai(actor, "Charon", "AI Attack State Exception move method", "creature.getWorldPosition() " + creature.getWorldPosition()); } } @@ -106,7 +121,7 @@ public class AttackState extends AIState { @Override public byte recover(AIActor actor) { CreatureObject creature = actor.getCreature(); - DevLog.debugout("Charon", "AI Attack Recover State", creature.getTemplate()); + DevLog.debugoutai(actor, "Charon", "AI Attack Recover State", creature.getTemplate()); float maxDistance = 0; WeaponObject weapon = null; if(creature.getWeaponId() != 0) { @@ -121,31 +136,51 @@ public class AttackState extends AIState { if(weapon == null) return StateResult.FINISHED; if(actor.getTimeSinceLastAttack() < weapon.getAttackSpeed() * 1000) { - //actor.scheduleRecovery(); + actor.scheduleRecovery(); return StateResult.UNFINISHED; } NGECore core = NGECore.getInstance(); if(creature.getPosture() == 14) return StateResult.DEAD; - if(!creature.isInCombat() || creature.getDefendersList().size() == 0 || actor.getFollowObject() == null) - { - creature.setLookAtTarget(0); - creature.setIntendedTarget(0); - actor.setFollowObject(null); - actor.setCurrentState(new RetreatState()); - return StateResult.FINISHED; - } + + TangibleObject target = actor.getFollowObject(); if(target != actor.getHighestDamageDealer() && actor.getHighestDamageDealer() != null) { actor.setFollowObject(actor.getHighestDamageDealer()); target = actor.getFollowObject(); } if(target == null) { - DevLog.debugout("Charon", "AI Attack State", "null target"); + DevLog.debugoutai(actor, "Charon", "AI Attack State", "null target"); actor.scheduleRecovery(); return StateResult.UNFINISHED; } + // If AI has no LOS to target, reposition it + if (!core.simulationService.checkLineOfSight(target,creature)){ + actor.setLastTarget(target); + actor.setCurrentState(new RepositionState()); + return StateResult.FINISHED; + } + + + if(!creature.isInCombat() || creature.getDefendersList().size() == 0 || actor.getFollowObject() == null) + { + +// System.out.println("creature.isInCombat() " + creature.isInCombat()); +// System.out.println("creature.getDefendersList().size() " + creature.getDefendersList().size()); +// System.out.println("actor.getFollowObject() " + actor.getFollowObject()); + creature.setLookAtTarget(0); + creature.setIntendedTarget(0); + actor.setFollowObject(null); + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + actor.setCurrentState(new RetreatState()); // Should be Patrol state + else { + actor.setCurrentState(new RetreatState()); // Should be Patrol state + } + return StateResult.FINISHED; + } + + if (target instanceof CreatureObject){ CreatureObject targetCreature = (CreatureObject) target; if(targetCreature.getPosture() == 13 || targetCreature.getPosture() == 14 || targetCreature.isInStealth()) { @@ -161,7 +196,11 @@ public class AttackState extends AIState { actor.setFollowObject(null); actor.removeDefender(target); - actor.setCurrentState(new RetreatState()); + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + actor.setCurrentState(new RetreatState()); // Should be Patrol state + else { + actor.setCurrentState(new RetreatState()); // Should be Patrol state + } return StateResult.FINISHED; } if(targetCreature.getWorldPosition().getDistance(creature.getWorldPosition()) > 128 || targetCreature.getPosture() == 13 || targetCreature.getPosture() == 14) { @@ -186,12 +225,14 @@ public class AttackState extends AIState { creature.setLookAtTarget(target.getObjectId()); creature.setIntendedTarget(target.getObjectId()); - if(attacks.size() == 0) { + if (attacks==null) { + //if(attacks.size() == 0) { core.commandService.callCommand(creature, actor.getMobileTemplate().getDefaultAttack(), target, ""); } else { Random rand = new Random(); if(rand.nextFloat() <= 0.33f) { - core.commandService.callCommand(creature, attacks.get(rand.nextInt(attacks.size())), target, ""); + if(attacks.size() > 0) + core.commandService.callCommand(creature, attacks.get(rand.nextInt(attacks.size())), target, ""); } else { core.commandService.callCommand(creature, actor.getMobileTemplate().getDefaultAttack(), target, ""); } diff --git a/src/services/ai/states/DeathState.java b/src/services/ai/states/DeathState.java index 30461315..9992feb2 100644 --- a/src/services/ai/states/DeathState.java +++ b/src/services/ai/states/DeathState.java @@ -33,6 +33,7 @@ public class DeathState extends AIState { public byte onEnter(AIActor actor) { NGECore.getInstance().aiService.awardExperience(actor); NGECore.getInstance().aiService.awardGcw(actor); + actor.setActorAlive(false); actor.getCreature().setAttachment("radial_filename", "npc/corpse"); //NGECore.getInstance().scriptService.callScript("scripts/radial/npc/corpse", "", "createRadial", NGECore.getInstance(), actor.getCreature().getKiller(), actor.getCreature(), new Vector()); actor.scheduleDespawn(); diff --git a/src/services/ai/states/PatrolState.java b/src/services/ai/states/PatrolState.java index 2a571391..ee32da39 100644 --- a/src/services/ai/states/PatrolState.java +++ b/src/services/ai/states/PatrolState.java @@ -24,13 +24,21 @@ package services.ai.states; import main.NGECore; import resources.objects.creature.CreatureObject; import services.ai.AIActor; +import services.ai.states.AIState.StateResult; +import tools.DevLog; public class PatrolState extends AIState { - + + private boolean locked = false; + + public PatrolState(){ + stateID = autoStateID++; + } + @Override public byte onEnter(AIActor actor) { - // TODO Auto-generated method stub - NGECore.getInstance().aiService.logAI("PATROL ENTERED!"); + + DevLog.debugoutai(actor, "Charon", "AI PatrolState", "PATROL ENTERED!"); CreatureObject creature = actor.getCreature(); if(creature.getPosture() == 14) return StateResult.DEAD; @@ -41,27 +49,37 @@ public class PatrolState extends AIState { @Override public byte onExit(AIActor actor) { - // TODO Auto-generated method stub - NGECore.getInstance().aiService.logAI("EXITING PATROL STATE"); + DevLog.debugoutai(actor, "Charon", "AI PatrolState", "EXITING PATROL STATE!"); actor.setLastPositionBeforeStateChange(actor.getCreature().getWorldPosition()); - return 0; + locked = true; + return StateResult.FINISHED; } @Override public byte move(AIActor actor) { - // TODO Auto-generated method stub - //System.out.println("move in patrolState"); + DevLog.debugoutai(actor, "Charon", "AI PatrolState", "PATROL MOVE!"); + if (locked){ + System.out.println("PatrolState locked!"); + return StateResult.FINISHED; + } + CreatureObject creature = actor.getCreature(); + if(creature.isInCombat()){ + System.out.println("PatrolState locking!"); + locked = true; + return StateResult.FINISHED; + } doPatrol(actor); -// if (actor.getCreature().getPlanet().getName().equals("dathomir")) -// NGECore.getInstance().aiService.logAI("WalkingSpeed " + actor.getCreature().getWalkSpeed()); actor.scheduleMovement(); return StateResult.UNFINISHED; } @Override public byte recover(AIActor actor) { - // TODO Auto-generated method stub - return 0; + if (actor.getFollowObject()!=null) + System.out.println("recover follow object is not null"); + if (actor.getFollowObject()!=null) + System.out.println("recover follow object is not null"); + return StateResult.UNFINISHED; } } diff --git a/src/services/ai/states/RepositionState.java b/src/services/ai/states/RepositionState.java new file mode 100644 index 00000000..c987ed52 --- /dev/null +++ b/src/services/ai/states/RepositionState.java @@ -0,0 +1,90 @@ +package services.ai.states; + +import main.NGECore; +import engine.resources.scene.Point3D; +import resources.objects.creature.CreatureObject; +import resources.objects.tangible.TangibleObject; +import services.ai.AIActor; +import tools.DevLog; + +/** + * @author Charon + */ + +public class RepositionState extends AIState{ + @Override + public byte onEnter(AIActor actor) { + DevLog.debugoutai(actor, "Charon", "AI RepositionState", "onEnter"); + CreatureObject creature = actor.getCreature(); + Point3D creaturePosition = creature.getWorldPosition(); + + TangibleObject target = actor.getLastTarget(); +// Point3D LOSorigin = targetPosition; +// float deltaX = LOSorigin.x-creaturePosition.x; +// float deltaZ = LOSorigin.z-creaturePosition.z; +// float originAngle = (float) (Math.atan2(deltaX,deltaZ)); + Point3D scanPosition = creaturePosition; + TangibleObject tempObject = new TangibleObject(); // LOS overload for pos and creature does not work correctly + tempObject.setPosition(scanPosition); + boolean breakout = false; + while (!NGECore.getInstance().simulationService.checkLineOfSight2(target,scanPosition) && !breakout){ + // Quick, light-weight way to get the AI into a firing LOS position + // ToDo: Check if the Quadnode at the LOS position contains a structure + // Required: Add according method to Quadtree.java + for (int x=2;x<50 && (!NGECore.getInstance().simulationService.checkLineOfSight2(target,scanPosition));x=x+2){ + scanPosition = new Point3D(creaturePosition.x+x,creaturePosition.y,creaturePosition.z); + } + for (int x=2;x>-50 && (!NGECore.getInstance().simulationService.checkLineOfSight2(target,scanPosition));x=x-2){ + scanPosition = new Point3D(creaturePosition.x+x,creaturePosition.y,creaturePosition.z); + } + for (int z=2;z<50 && (!NGECore.getInstance().simulationService.checkLineOfSight2(target,scanPosition));z=z+2){ + scanPosition = new Point3D(creaturePosition.x,creaturePosition.y,creaturePosition.z+z); + } + for (int z=2;z>-50 && (!NGECore.getInstance().simulationService.checkLineOfSight2(target,scanPosition));z=z-2){ + scanPosition = new Point3D(creaturePosition.x,creaturePosition.y,creaturePosition.z+z); + } +// if (!NGECore.getInstance().simulationService.checkLineOfSight2(target,scanPosition)) +// breakout=true; +// else +// System.out.println("LOS found"); +// + breakout=true; + } + actor.setRepositionLocation(scanPosition); + actor.setRepositionStartTime(System.currentTimeMillis()); + + return 0; + } + + @Override + public byte onExit(AIActor actor) { + // TODO Auto-generated method stub + DevLog.debugoutai(actor, "Charon", "AI RepositionState", "exit"); + return 0; + } + + @Override + public byte move(AIActor actor) { + DevLog.debugoutai(actor, "Charon", "AI RepositionState", "move"); + + Point3D newPosition = actor.getRepositionLocation(); + TangibleObject target = actor.getLastTarget(); + if (target==null) + return StateResult.FINISHED; + + if (newPosition.getDistance2D(target.getWorldPosition())<0.5 || System.currentTimeMillis()>actor.getRepositionStartTime()+5000){ + actor.addDefender(target); + return StateResult.FINISHED; + } + + doReposition(actor); + actor.scheduleMovement(); + return StateResult.UNFINISHED; + } + + @Override + public byte recover(AIActor actor) { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/src/services/ai/states/RetreatState.java b/src/services/ai/states/RetreatState.java index b94684fe..f2515724 100644 --- a/src/services/ai/states/RetreatState.java +++ b/src/services/ai/states/RetreatState.java @@ -25,9 +25,13 @@ import main.NGECore; import engine.resources.scene.Point3D; import resources.objects.creature.CreatureObject; import services.ai.AIActor; +import tools.DevLog; public class RetreatState extends AIState { - + + private long retreatStartTime = 0L; + private Point3D retreatStartPos = null; + @Override public byte onEnter(AIActor actor) { /*synchronized(actor.getDamageMap()) { @@ -35,8 +39,11 @@ public class RetreatState extends AIState { actor.removeDefender(defender); } }*/ - NGECore.getInstance().aiService.logAI("RetreatState ENTER "); - + DevLog.debugoutai(actor, "Charon", "AI RetreatState", "RetreatState ENTER!"); + CreatureObject creature = actor.getCreature(); + if (creature.getPosture()==13 || creature.getPosture()==14) + return StateResult.FINISHED; + creature.setInCombat(false); if (actor.getCreature().getOwnerId()>0){ CreatureObject owner = (CreatureObject) NGECore.getInstance().objectService.getObject(actor.getCreature().getOwnerId()); actor.setFollowObject(owner); @@ -44,6 +51,9 @@ public class RetreatState extends AIState { return StateResult.FINISHED; } else actor.setFollowObject(null); + + retreatStartTime = System.currentTimeMillis(); + retreatStartPos = creature.getWorldPosition(); actor.scheduleMovement(); return StateResult.UNFINISHED; } @@ -52,16 +62,20 @@ public class RetreatState extends AIState { public byte onExit(AIActor actor) { // TODO Auto-generated method stub //actor.setCurrentState(actor.getIntendedPrimaryAIState()); + DevLog.debugoutai(actor, "Charon", "AI RetreatState", "RetreatState EXIT!"); return StateResult.FINISHED; } @Override public byte move(AIActor actor) { - + DevLog.debugoutai(actor, "Charon", "AI RetreatState", "RetreatState MOVE!"); Point3D retreatPosition = actor.getSpawnPosition(); if (actor.getIntendedPrimaryAIState() instanceof PatrolState) retreatPosition = actor.getLastPositionBeforeStateChange(); + CreatureObject creature = actor.getCreature(); + if (creature.getPosture()==13 || creature.getPosture()==14) + return StateResult.FINISHED; actor.setNextPosition(retreatPosition); actor.getMovementPoints().clear(); actor.getMovementPoints().add(retreatPosition); @@ -71,19 +85,49 @@ public class RetreatState extends AIState { return StateResult.FOLLOW; if(actor.getCreature().getWorldPosition().getDistance(retreatPosition) > 5) { - //NGECore.getInstance().aiService.logAI("RetreatState ENTER move if case dist " + actor.getCreature().getWorldPosition().getDistance(retreatPosition)); actor.scheduleMovement(); } else { - //NGECore.getInstance().aiService.logAI("RetreatState ENTER move else case"); + if (actor.getIntendedPrimaryAIState().getClass().equals(IdleState.class)) - return StateResult.IDLE; + actor.setCurrentState(new IdleState()); if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) - return StateResult.PATROL; + actor.setCurrentState(new PatrolState()); if (actor.getIntendedPrimaryAIState().getClass().equals(LoiterState.class)) - return StateResult.LOITER; + actor.setCurrentState(new LoiterState()); if (actor.getIntendedPrimaryAIState().getClass().equals(FollowState.class)) - return StateResult.FOLLOW; + actor.setCurrentState(new FollowState()); + + return StateResult.FINISHED; } + + if(System.currentTimeMillis()> retreatStartTime + 5000 && creature.getWorldPosition().getDistance2D(retreatStartPos)<1.5){ + // Actor is locked in retreat state, get back to intended state + if (actor.getIntendedPrimaryAIState().getClass().equals(IdleState.class)) + actor.setCurrentState(new IdleState()); + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + actor.setCurrentState(new PatrolState()); + if (actor.getIntendedPrimaryAIState().getClass().equals(LoiterState.class)) + actor.setCurrentState(new LoiterState()); + if (actor.getIntendedPrimaryAIState().getClass().equals(FollowState.class)) + actor.setCurrentState(new FollowState()); + + return StateResult.FINISHED; + } + + if(System.currentTimeMillis()> retreatStartTime + 40000){ + // Actor is locked in retreat state, get back to intended state after 40s, no matter what + if (actor.getIntendedPrimaryAIState().getClass().equals(IdleState.class)) + actor.setCurrentState(new IdleState()); + if (actor.getIntendedPrimaryAIState().getClass().equals(PatrolState.class)) + actor.setCurrentState(new PatrolState()); + if (actor.getIntendedPrimaryAIState().getClass().equals(LoiterState.class)) + actor.setCurrentState(new LoiterState()); + if (actor.getIntendedPrimaryAIState().getClass().equals(FollowState.class)) + actor.setCurrentState(new FollowState()); + + return StateResult.FINISHED; + } + return StateResult.UNFINISHED; } diff --git a/src/services/ai/states/TurretAIState.java b/src/services/ai/states/TurretAIState.java index 4ec05cd3..7d99664c 100644 --- a/src/services/ai/states/TurretAIState.java +++ b/src/services/ai/states/TurretAIState.java @@ -83,13 +83,6 @@ public abstract class TurretAIState { } } - if (actor.getCurrentState().getClass().equals(PatrolState.class)){ - targetPosition = patrolPoints.get(actor.getPatrolPointIndex()); - } - - if (actor.getCurrentState().getClass().equals(FollowState.class)){ - targetPosition = actor.getFollowObject().getWorldPosition(); - } Vector path = core.aiService.findPath(creature.getPlanetId(), currentPosition, targetPosition); diff --git a/src/services/ai/states/TurretAttackState.java b/src/services/ai/states/TurretAttackState.java index 7f04794d..530ed365 100644 --- a/src/services/ai/states/TurretAttackState.java +++ b/src/services/ai/states/TurretAttackState.java @@ -30,21 +30,24 @@ import resources.objects.tangible.TangibleObject; import resources.objects.weapon.WeaponObject; import services.ai.AIActor; import services.ai.TurretAIActor; +import services.ai.states.AIState.StateResult; import tools.DevLog; public class TurretAttackState extends TurretAIState { @Override public byte onEnter(TurretAIActor actor) { -// DevLog.debugout("Charon", "Turret AI Attack State", "onEnter"); + DevLog.debugoutai(actor, "Charon", "Turret AI Attack State", "onEnter"); TangibleObject creature = actor.getCreature(); // DevLog.debugout("Charon", "Turret AI Attack State", "onEnter creature.getConditionDamage() " + creature.getConditionDamage()); // DevLog.debugout("Charon", "Turret AI Attack State", "onEnter creature.getMaximumCondition() " + creature.getMaximumCondition()); - if(creature.getConditionDamage()>=creature.getMaximumCondition()) - return StateResult.DEAD; - + if(creature.getConditionDamage()>=creature.getMaximumCondition()){ + return StateResult.DEAD; + } + if(!creature.isInCombat() || creature.getDefendersList().size() == 0 || actor.getFollowObject() == null) + return StateResult.FINISHED; // DevLog.debugout("Charon", "Turret AI Attack State", "onEnter creature.getDefendersList().size() " + creature.getDefendersList().size()); // DevLog.debugout("Charon", "Turret AI Attack State", "onEnter actor.getFollowObject() " + actor.getFollowObject()); @@ -58,7 +61,10 @@ public class TurretAttackState extends TurretAIState { @Override public byte onExit(TurretAIActor actor) { // TODO Auto-generated method stub - + DevLog.debugoutai(actor, "Charon", "Turret AI Attack State", "onExit"); + + TangibleObject creature = actor.getCreature(); + creature.setInCombat(false); // actor.getCreature().setLookAtTarget(0); // actor.getCreature().setIntendedTarget(0); actor.setFollowObject(null); @@ -75,7 +81,11 @@ public class TurretAttackState extends TurretAIState { @Override public byte recover(TurretAIActor actor) { + DevLog.debugoutai(actor, "Charon", "TurretAI Attack State", "recover "); TangibleObject creature = actor.getCreature(); + if (creature==null) + return StateResult.FINISHED; + float maxDistance = 0; WeaponObject weapon = null; //weapon = (WeaponObject) creature.getSlottedObject("default_weapon"); @@ -89,12 +99,20 @@ public class TurretAttackState extends TurretAIState { maxDistance = weapon.getMaxRange() - 1; + + // Here is place for turret cooldown if(actor.getTimeSinceLastAttack() < weapon.getAttackSpeed() * 1000) { - //actor.scheduleRecovery(); + actor.scheduleRecovery(); return StateResult.UNFINISHED; } NGECore core = NGECore.getInstance(); - if(creature.getConditionDamage()>creature.getMaximumCondition()) + + if (core.aiService.getCheckAI()!=null){ + if (core.aiService.getCheckAI().getObjectID()==creature.getObjectID()) + System.out.println("creature.getConditionDamage() " + creature.getConditionDamage() + " creature.getMaximumCondition() " + creature.getMaximumCondition()); + } + + if(creature.getConditionDamage()>=creature.getMaximumCondition()) return StateResult.DEAD; if(!creature.isInCombat() || creature.getDefendersList().size() == 0 || actor.getFollowObject() == null) @@ -112,7 +130,7 @@ public class TurretAttackState extends TurretAIState { target = actor.getFollowObject(); } if(target == null) { - DevLog.debugout("Charon", "AI Attack State", "null target"); + DevLog.debugoutai(actor, "Charon", "AI Attack State", "null target"); actor.scheduleRecovery(); return StateResult.UNFINISHED; } @@ -135,10 +153,12 @@ public class TurretAttackState extends TurretAIState { actor.setCurrentState(new TurretIdleState()); return StateResult.FINISHED; } - if(targetCreature.getWorldPosition().getDistance(creature.getWorldPosition()) > 128 || targetCreature.getPosture() == 13 || targetCreature.getPosture() == 14) { + if(targetCreature.getWorldPosition().getDistance(creature.getWorldPosition()) > maxDistance || targetCreature.getPosture() == 13 || targetCreature.getPosture() == 14) { actor.removeDefender(target); - actor.scheduleRecovery(); - return StateResult.UNFINISHED; +// actor.scheduleRecovery(); +// return StateResult.UNFINISHED; + + return StateResult.FINISHED; } } @@ -146,8 +166,11 @@ public class TurretAttackState extends TurretAIState { // DevLog.debugout("Charon", "AI Attack State", "prior to attacks maxDistance " + maxDistance); if(target.getWorldPosition().getDistance(creature.getWorldPosition()) > maxDistance) { - actor.scheduleRecovery(); - return StateResult.UNFINISHED; + actor.removeDefender(target); +// actor.scheduleRecovery(); +// return StateResult.UNFINISHED; + + return StateResult.FINISHED; } //actor.faceObject(target); core.commandService.callCommand(creature, "rangedShot", target, ""); diff --git a/src/services/ai/states/TurretIdleState.java b/src/services/ai/states/TurretIdleState.java index 84594f2f..b4fe24c2 100644 --- a/src/services/ai/states/TurretIdleState.java +++ b/src/services/ai/states/TurretIdleState.java @@ -22,19 +22,25 @@ package services.ai.states; import services.ai.TurretAIActor; +import services.ai.states.AIState.StateResult; +import tools.DevLog; public class TurretIdleState extends TurretAIState { @Override public byte onEnter(TurretAIActor actor) { // TODO Auto-generated method stub - return 0; + DevLog.debugoutai(actor,"Charon", "Turret AI Idle State", "onEnter"); + //return 0; + return StateResult.UNFINISHED; } @Override public byte onExit(TurretAIActor actor) { // TODO Auto-generated method stub - return 0; + DevLog.debugoutai(actor,"Charon", "Turret AI Idle State", "onExit"); + //return 0; + return StateResult.FINISHED; } @Override diff --git a/src/services/combat/CombatService.java b/src/services/combat/CombatService.java index 4281407c..79a827fe 100644 --- a/src/services/combat/CombatService.java +++ b/src/services/combat/CombatService.java @@ -61,6 +61,7 @@ import resources.objects.tangible.TangibleObject; import resources.objects.waypoint.WaypointObject; import resources.objects.weapon.WeaponObject; import services.ai.AIActor; +import services.ai.TurretAIActor; import services.combat.CombatEvents.DamageTaken; import services.command.CombatCommand; import services.sui.SUIService.MessageBoxType; @@ -488,9 +489,16 @@ public class CombatService implements INetworkDispatch { AIActor petActor = (AIActor) targetCreature.getCalledPet().getAttachment("AI"); if (petActor!=null){ petActor.addDefender(attacker); - DevLog.debugout("Charon", "Pet AI", "applyDamage addDefender"); + DevLog.debugoutai(petActor, "Charon", "Pet AI", "applyDamage addDefender"); } } + + if (!targetCreature.isInCombat()){ + //targetCreature.setInCombat(true); + AIActor targetActor = (AIActor) targetCreature.getAttachment("AI"); + targetActor.addDefender(attacker); + DevLog.debugoutai(targetActor, "Charon", "CombatService AI", "applyDamage addDefender 2"); + } } DamageTaken event = events.new DamageTaken(); @@ -517,6 +525,13 @@ public class CombatService implements INetworkDispatch { DevLog.debugout("Charon", "Pet AI", "applyDamage addDefender"); } } + + if (!targetCreature.isInCombat()){ + //targetCreature.setInCombat(true); + AIActor targetActor = (AIActor) targetCreature.getAttachment("AI"); + targetActor.addDefender(attacker); + DevLog.debugout("Charon", "CombatService AI", "applyDamage addDefender 2"); + } } DamageTaken event = events.new DamageTaken(); @@ -540,13 +555,18 @@ public class CombatService implements INetworkDispatch { - - AIActor aiActor = (AIActor)attacker.getAttachment("AI"); - if (aiActor.getMobileTemplate().isDeathblow()){ - deathblowPlayerFromInstallation(attacker, target); + if (attacker.getAttachment("AI") instanceof AIActor){ + AIActor aiActor = (AIActor)attacker.getAttachment("AI"); + if (aiActor.getMobileTemplate().isDeathblow()){ + deathblowPlayerFromInstallation(attacker, target); + return; + } + } + if (attacker.getAttachment("AI") instanceof TurretAIActor){ + deathblowPlayerFromInstallation(attacker, target); // turrets always db return; + } - synchronized(target.getMutex()) { if (core.mountService.isMounted(target)) { @@ -606,6 +626,20 @@ public class CombatService implements INetworkDispatch { DevLog.debugout("Charon", "Pet AI", "applyDamage addDefender"); } } + + if (!targetCreature.isInCombat()){ + //targetCreature.setInCombat(true); + if (targetCreature.getAttachment("AI") instanceof AIActor){ + AIActor targetActor = (AIActor) targetCreature.getAttachment("AI"); + targetActor.addDefender(attacker); + DevLog.debugoutai(targetActor, "Charon", "CombatService AI", "applyDamage addDefender 2"); + } + if (targetCreature.getAttachment("AI") instanceof TurretAIActor){ + TurretAIActor targetActor = (TurretAIActor) targetCreature.getAttachment("AI"); + targetActor.addDefender(attacker); + DevLog.debugoutai(targetActor, "Charon", "CombatService AI", "applyDamage addDefender 2"); + } + } } @@ -758,8 +792,14 @@ public class CombatService implements INetworkDispatch { private void sendCombatPackets(CreatureObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command, int actionCounter, float damage, int armorAbsorbed, int hitType) { - String animationStr = command.getRandomAnimation(weapon); + String animationStr = command.getRandomAnimation(weapon); // choosing turretShot as default attack, results in a zero length string + if (weapon.getTemplate().contains("atst_ranged")) + animationStr="fire_1_single_light"; CombatAction combatAction = new CombatAction(CRC.StringtoCRC(animationStr), attacker.getObjectID(), weapon.getObjectID(), target.getObjectID(), command.getCommandCRC()); + +// int turret_fire = 0xD334C0B8; // 0xA7595B4E +// CombatAction combatAction = new CombatAction(turret_fire, attacker.getObjectID(), weapon.getObjectID(), target.getObjectID(), command.getCommandCRC()); +// ObjControllerMessage objController = new ObjControllerMessage(0x1B, combatAction); attacker.notifyObserversInRange(objController, true, 125); CombatSpam combatSpam = new CombatSpam(attacker.getObjectID(), target.getObjectID(), weapon.getObjectID(), (int) damage, armorAbsorbed, hitType); @@ -1266,9 +1306,15 @@ public class CombatService implements INetworkDispatch { AIActor petActor = (AIActor) targetCreature.getCalledPet().getAttachment("AI"); if (petActor!=null){ petActor.addDefender(attacker); - DevLog.debugout("Charon", "Pet AI", "applyDamage addDefender"); + //DevLog.debugout("Charon", "Pet AI", "applyDamage addDefender"); } } + + if (!targetCreature.isInCombat()){ + AIActor targetActor = (AIActor) targetCreature.getAttachment("AI"); + targetActor.addDefender(attacker); + //DevLog.debugout("Charon", "CombatService AI", "applyDamage addDefender 2"); + } } diff --git a/src/services/gcw/FactionService.java b/src/services/gcw/FactionService.java index df74bf0c..5f1e3854 100644 --- a/src/services/gcw/FactionService.java +++ b/src/services/gcw/FactionService.java @@ -21,6 +21,7 @@ ******************************************************************************/ package services.gcw; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; @@ -37,6 +38,7 @@ import org.python.core.Py; import org.python.core.PyObject; import protocol.swg.FactionResponseMessage; +import protocol.swg.UpdatePVPStatusMessage; import resources.common.FileUtilities; import resources.common.Opcodes; import resources.datatables.DisplayType; @@ -44,6 +46,7 @@ import resources.datatables.FactionStatus; import resources.datatables.Options; import resources.datatables.PvpStatus; import resources.objects.creature.CreatureObject; +import resources.objects.installation.InstallationObject; import resources.objects.mission.MissionObject; import resources.objects.player.PlayerObject; import resources.objects.tangible.TangibleObject; @@ -52,6 +55,7 @@ import engine.clientdata.StfTable; import engine.clientdata.visitors.DatatableVisitor; import engine.clients.Client; import engine.resources.common.CRC; +import engine.resources.objects.SWGObject; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; @@ -169,6 +173,7 @@ public class FactionService implements INetworkDispatch { * Will be useful for NPC AI, so they know who to help and who to be indifferent to. */ public boolean isFactionAlly(TangibleObject object, TangibleObject target) { + if (object == null || target == null) { return false; } @@ -180,10 +185,10 @@ public class FactionService implements INetworkDispatch { return false; } + if (FileUtilities.doesFileExist("scripts/faction/" + objectFaction + ".py")) { - PyObject method = core.scriptService.getMethod("scripts/faction/", objectFaction, "isAlly"); - - if (method != null && method.isCallable()) { + PyObject method = core.scriptService.getMethod("scripts/faction/", objectFaction, "isAlly"); + if (method != null && method.isCallable()) { return ((method.__call__(Py.java2py(targetFaction)).asInt() == 1) ? true : false); } } @@ -191,6 +196,29 @@ public class FactionService implements INetworkDispatch { return false; } + public boolean isFactionAlly(String objectFaction, String targetFaction) { + + if (objectFaction == null || targetFaction == null) { + return false; + } + + if (!isFaction(objectFaction) || !isFaction(targetFaction)) { + return false; + } + + + if (FileUtilities.doesFileExist("scripts/faction/" + objectFaction + ".py")) { + PyObject method = core.scriptService.getMethod("scripts/faction/", objectFaction, "isAlly"); + if (method != null && method.isCallable()) { + return ((method.__call__(Py.java2py(targetFaction)).asInt() == 1) ? true : false); + } + } + + return false; + } + + + /* * Returns true if target is an enemy of object * @@ -355,6 +383,7 @@ public class FactionService implements INetworkDispatch { } } + return pvpBitmask; } @@ -525,6 +554,32 @@ public class FactionService implements INetworkDispatch { return factionMap; } + // This is to make nearby NPCs transmit updatepvp, + // so the player sees the faction change represented in the clientside NPC representation + public void updatePVPFromNearbyNPCs(CreatureObject creature, Client destination){ + List awareObjects = core.simulationService.get(creature.getPlanet(), creature.getWorldPosition().x, creature.getWorldPosition().z, 512); + for(int i = 0; i < awareObjects.size(); i++) { + SWGObject obj = awareObjects.get(i); + if(obj != creature && obj.getContainer() != creature && obj.isInQuadtree()) { + if (obj instanceof CreatureObject){ + CreatureObject creo = (CreatureObject) obj; + UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(creo.getObjectID()); + upvpm.setFaction(CRC.StringtoCRC(creo.getFaction())); + upvpm.setStatus(NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), creo)); + destination.getSession().write(upvpm.serialize()); + } + if (obj instanceof InstallationObject){ + InstallationObject inso = (InstallationObject) obj; + UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(inso.getObjectID()); + upvpm.setFaction(CRC.StringtoCRC(inso.getFaction())); + upvpm.setStatus(NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), inso)); + //System.out.println("MakeAwareNearbyNPCs " + NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), inso)); + destination.getSession().write(upvpm.serialize()); + } + } + } + } + @Override public void insertOpcodes(Map swgOpcodes, Map objControllerOpcodes) { diff --git a/src/services/gcw/GCWPylon.java b/src/services/gcw/GCWPylon.java index c2de51de..c0cf0012 100644 --- a/src/services/gcw/GCWPylon.java +++ b/src/services/gcw/GCWPylon.java @@ -48,7 +48,7 @@ public class GCWPylon extends TangibleObject{ private String[] soldierTemplates = new String[]{""}; private String[] rebelSoldierTemplates1 = new String[]{""}; private String[] rebelSoldierTemplates2 = new String[]{""}; - private String[] rebelSoldierTemplates3 = new String[]{""}; + private String[] rebelSoldierTemplates3 = new String[]{"gcw_city_rebel_soldier"}; private String[] imperialSoldierTemplates1 = new String[]{""}; private String[] imperialSoldierTemplates2 = new String[]{""}; private String[] imperialSoldierTemplates3 = new String[]{"elite_imperial_stormtrooper_90"}; @@ -87,6 +87,7 @@ public class GCWPylon extends TangibleObject{ private String imperialTowerTemplate = "object/tangible/destructible/shared_gcw_imperial_tower.iff"; private Vector patrolRoute = new Vector(); + private CreatureObject lastDefender = null; private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); @@ -114,7 +115,19 @@ public class GCWPylon extends TangibleObject{ System.err.println("Exception in SoldierPatrolPylon->scheduleAtFixedRate->spawnSoldier() " + e.getMessage()); } } - }, 5, 30, TimeUnit.SECONDS); + }, 5, 60, TimeUnit.SECONDS); + } + + if (pylonType==PylonType.SoldierDefense){ + scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + spawnSoldierDefender(); + } catch (Exception e) { + System.err.println("Exception in SoldierDefensePylon->scheduleAtFixedRate->spawnSoldier() " + e.getMessage()); + } + } + }, 5, 90, TimeUnit.SECONDS); } if (pylonType==PylonType.VehiclePatrol){ @@ -126,7 +139,19 @@ public class GCWPylon extends TangibleObject{ System.err.println("Exception in SoldierPatrolPylon->scheduleAtFixedRate->spawnVehicle() " + e.getMessage()); } } - }, 5, 80, TimeUnit.SECONDS); + }, 5, 120, TimeUnit.SECONDS); + } + + if (pylonType==PylonType.SoldierPatrol){ + scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + spawnSoldier(); + } catch (Exception e) { + System.err.println("Exception in SoldierPatrolPylon->scheduleAtFixedRate->spawnSoldier() " + e.getMessage()); + } + } + }, 5, 60, TimeUnit.SECONDS); } } @@ -169,6 +194,35 @@ public class GCWPylon extends TangibleObject{ NGECore.getInstance().aiService.setPatrol(soldier, patrolRoute); NGECore.getInstance().aiService.setPatrolLoop(soldier,false); + NGECore.getInstance().invasionService.registerInvader(soldier); + totalSpawnedUnits++; + } + } + + public void spawnSoldierDefender(){ + + if (NGECore.getInstance().invasionService.getInvasionPhase()==2){ + if (pylonFaction==Factions.Rebel){ + switch (spawnLevel) { + case 1: soldierTemplates = rebelSoldierTemplates1; + case 2: soldierTemplates = rebelSoldierTemplates2; + case 3: soldierTemplates = rebelSoldierTemplates3; + } + } + if (pylonFaction==Factions.Imperial){ + switch (spawnLevel) { + case 1: soldierTemplates = imperialSoldierTemplates1; + case 2: soldierTemplates = imperialSoldierTemplates2; + case 3: soldierTemplates = imperialSoldierTemplates3; + } + } + if (lastDefender!=null) + if (lastDefender.getPosture()!=13 && lastDefender.getPosture()!=13) + return; + String soldierTemplate = soldierTemplates[new Random().nextInt(soldierTemplates.length)]; + lastDefender = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(soldierTemplate, this.getPlanet().getName(), 0L, this.getPosition().x, this.getPosition().y, this.getPosition().z, this.getOrientation().w, this.getOrientation().x, this.getOrientation().y,this.getOrientation().z,-1); + + NGECore.getInstance().invasionService.registerDefender(lastDefender); totalSpawnedUnits++; } } @@ -195,6 +249,7 @@ public class GCWPylon extends TangibleObject{ NGECore.getInstance().aiService.setPatrol(vehicle, get_Dearic_Route_1()); NGECore.getInstance().aiService.setPatrolLoop(vehicle,false); + NGECore.getInstance().invasionService.registerInvader(vehicle); totalSpawnedUnits++; } } @@ -352,9 +407,11 @@ public class GCWPylon extends TangibleObject{ public Vector get_Dearic_Route_10(){// just for tests Vector patrolpoints = new Vector(); - patrolpoints.add(new Point3D(620.0F, 6.00F, -3009F)); - patrolpoints.add(new Point3D(565.0F, 6.00F, -3025F)); - patrolpoints.add(new Point3D(535.0F, 6.00F, -3023F)); + patrolpoints.add(new Point3D(618.0F, 6.00F, -2972F)); + patrolpoints.add(new Point3D(617.0F, 6.00F, -2980F)); + patrolpoints.add(new Point3D(616.0F, 6.00F, -2990F)); + patrolpoints.add(new Point3D(615.0F, 6.00F, -3010F)); + patrolpoints.add(new Point3D(500.0F, 6.00F, -3035F)); return patrolpoints; } @@ -362,11 +419,12 @@ public class GCWPylon extends TangibleObject{ public class PylonType { public static final int SoldierPatrol = 0; - public static final int VehiclePatrol = 1; - public static final int SiegeVehiclePatrol = 2; - public static final int Barricade = 3; - public static final int Turret = 4; - public static final int Tower = 5; + public static final int SoldierDefense = 1; + public static final int VehiclePatrol = 2; + public static final int SiegeVehiclePatrol = 3; + public static final int Barricade = 4; + public static final int Turret = 5; + public static final int Tower = 6; } /* @@ -400,4 +458,5 @@ public class GCWPylon extends TangibleObject{ public void setTotalSpawnedUnits(int totalSpawnedUnits) { this.totalSpawnedUnits = totalSpawnedUnits; } + } diff --git a/src/services/gcw/GCWSpawner.java b/src/services/gcw/GCWSpawner.java new file mode 100644 index 00000000..458fc224 --- /dev/null +++ b/src/services/gcw/GCWSpawner.java @@ -0,0 +1,502 @@ +/******************************************************************************* + * 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 services.gcw; + +import java.util.Random; +import java.util.Vector; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import engine.resources.scene.Planet; +import engine.resources.scene.Point3D; +import engine.resources.scene.Quaternion; +import main.NGECore; +import resources.datatables.Factions; +import resources.objects.creature.CreatureObject; +import resources.objects.tangible.TangibleObject; + +/** + * @author Charon + */ + +public class GCWSpawner extends TangibleObject{ + + private static final long serialVersionUID = 1L; + private int spawnerType = 0; + private int spawnerFaction = 0; + private int spawnLevel = 0; + private int totalSpawnedUnits = 0; + private String[] soldierTemplates = new String[]{""}; + private String[] rebelSoldierTemplates1 = new String[]{""}; + private String[] rebelSoldierTemplates2 = new String[]{""}; + private String[] rebelSoldierTemplates3 = new String[]{"gcw_city_rebel_soldier"}; + private String[] imperialSoldierTemplates1 = new String[]{""}; + private String[] imperialSoldierTemplates2 = new String[]{""}; + private String[] imperialSoldierTemplates3 = new String[]{"elite_imperial_stormtrooper_90"}; + + private String[] vehicleTemplates = new String[]{""}; + private String[] rebelVehicleTemplates1 = new String[]{"rebel_invasion_at_xt"}; + private String[] rebelVehicleTemplates2 = new String[]{"rebel_invasion_at_xt"}; + private String[] rebelVehicleTemplates3 = new String[]{"rebel_invasion_at_xt"}; + private String[] imperialVehicleTemplates1 = new String[]{"imp_invasion_at_st"}; + private String[] imperialVehicleTemplates2 = new String[]{"imp_invasion_at_st"}; + private String[] imperialVehicleTemplates3 = new String[]{"imp_invasion_at_st"}; + + private String[] siegeVehicleTemplates = new String[]{""}; + private String[] rebelSiegeVehicleTemplates1 = new String[]{"rebel_invasion_hailfire_droid"}; + private String[] rebelSiegeVehicleTemplates2 = new String[]{"rebel_invasion_hailfire_droid"}; + private String[] rebelSiegeVehicleTemplates3 = new String[]{"rebel_invasion_hailfire_droid"}; + private String[] imperialSiegeVehicleTemplates1 = new String[]{"imp_invasion_at_at"}; + private String[] imperialSiegeVehicleTemplates2 = new String[]{"imp_invasion_at_at"}; + private String[] imperialSiegeVehicleTemplates3 = new String[]{"imp_invasion_at_at"}; + + private String barricadeTemplate = ""; + private String rebelBarricadeTemplate = "object/tangible/destructible/shared_gcw_rebel_barricade.iff"; + private String imperialBarricadeTemplate = "object/tangible/destructible/shared_gcw_imperial_barricade.iff"; + + + private String turretTemplates = ""; + private String[] rebelTurretTemplates1 = new String[]{""}; + private String[] rebelTurretTemplates2 = new String[]{""}; + private String[] rebelTurretTemplates3 = new String[]{"object/tangible/destructible/shared_gcw_rebel_turret.iff"}; + private String[] imperialTurretTemplates1 = new String[]{""}; + private String[] imperialTurretTemplates2 = new String[]{""}; + private String[] imperialTurretTemplates3 = new String[]{"object/tangible/destructible/shared_gcw_imperial_turret.iff"}; + + private String towerTemplate = ""; + private String rebelTowerTemplate = "object/tangible/destructible/shared_gcw_rebel_tower.iff"; + private String imperialTowerTemplate = "object/tangible/destructible/shared_gcw_imperial_tower.iff"; + + private Vector patrolRoute = new Vector(); + private CreatureObject lastDefender = null; + + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + + public GCWSpawner() { + super(); + } + + public GCWSpawner(long objectID, Planet planet, Point3D position, Quaternion orientation, String template){ + super(objectID, planet, position, orientation, template); + } + + public int getSpawnerType() { + return spawnerType; + } + + public void setSpawnerType(int spawnerType) { + this.spawnerType = spawnerType; + + if (spawnerType==SpawnerType.SoldierPatrol){ + scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + spawnSoldier(); + } catch (Exception e) { + System.err.println("Exception in SoldierPatrolPylon->scheduleAtFixedRate->spawnSoldier() " + e.getMessage()); + } + } + }, 5, 60, TimeUnit.SECONDS); + } + + if (spawnerType==SpawnerType.SoldierDefense){ + scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + spawnSoldierDefender(); + } catch (Exception e) { + System.err.println("Exception in SoldierDefensePylon->scheduleAtFixedRate->spawnSoldier() " + e.getMessage()); + } + } + }, 5, 90, TimeUnit.SECONDS); + } + + if (spawnerType==SpawnerType.VehiclePatrol){ + scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + spawnVehicle(); + } catch (Exception e) { + System.err.println("Exception in SoldierPatrolPylon->scheduleAtFixedRate->spawnVehicle() " + e.getMessage()); + } + } + }, 5, 120, TimeUnit.SECONDS); + } + + if (spawnerType==SpawnerType.SiegeVehiclePatrol){ + scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + spawnSiegeVehicle(); + } catch (Exception e) { + System.err.println("Exception in SoldierPatrolPylon->scheduleAtFixedRate->spawnSoldier() " + e.getMessage()); + } + } + }, 10, 600, TimeUnit.SECONDS); + } + + } + + public int getSpawnerFaction() { + return spawnerFaction; + } + + public void setSpawnerFaction(int spawnerFaction) { + this.spawnerFaction = spawnerFaction; + } + + public int getSpawnLevel() { + return spawnLevel; + } + + public void setSpawnLevel(int spawnLevel) { + this.spawnLevel = spawnLevel; + } + + public void spawnSoldier(){ + + if (NGECore.getInstance().invasionService.getInvasionPhase()==2){ + if (spawnerFaction==Factions.Rebel){ + switch (spawnLevel) { + case 1: soldierTemplates = rebelSoldierTemplates1; + case 2: soldierTemplates = rebelSoldierTemplates2; + case 3: soldierTemplates = rebelSoldierTemplates3; + } + } + if (spawnerFaction==Factions.Imperial){ + switch (spawnLevel) { + case 1: soldierTemplates = imperialSoldierTemplates1; + case 2: soldierTemplates = imperialSoldierTemplates2; + case 3: soldierTemplates = imperialSoldierTemplates3; + } + } + String soldierTemplate = soldierTemplates[new Random().nextInt(soldierTemplates.length)]; + //if (totalSpawnedUnits==0){ + CreatureObject soldier = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(soldierTemplate, this.getPlanet().getName(), 0L, this.getPosition().x, this.getPosition().y, this.getPosition().z, this.getOrientation().w, this.getOrientation().x, this.getOrientation().y,this.getOrientation().z,-1); + + NGECore.getInstance().aiService.setPatrol(soldier, patrolRoute); + NGECore.getInstance().aiService.setPatrolLoop(soldier,false); + NGECore.getInstance().invasionService.registerInvader(soldier); + totalSpawnedUnits++; + //} + } + } + + public void spawnSoldierDefender(){ + + if (NGECore.getInstance().invasionService.getInvasionPhase()==2){ + if (spawnerFaction==Factions.Rebel){ + switch (spawnLevel) { + case 1: soldierTemplates = rebelSoldierTemplates1; + case 2: soldierTemplates = rebelSoldierTemplates2; + case 3: soldierTemplates = rebelSoldierTemplates3; + } + } + if (spawnerFaction==Factions.Imperial){ + switch (spawnLevel) { + case 1: soldierTemplates = imperialSoldierTemplates1; + case 2: soldierTemplates = imperialSoldierTemplates2; + case 3: soldierTemplates = imperialSoldierTemplates3; + } + } + if (lastDefender!=null) + if (lastDefender.getPosture()!=13 && lastDefender.getPosture()!=13) + return; + String soldierTemplate = soldierTemplates[new Random().nextInt(soldierTemplates.length)]; + lastDefender = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(soldierTemplate, this.getPlanet().getName(), 0L, this.getPosition().x, this.getPosition().y, this.getPosition().z, this.getOrientation().w, this.getOrientation().x, this.getOrientation().y,this.getOrientation().z,-1); + + NGECore.getInstance().invasionService.registerDefender(lastDefender); + totalSpawnedUnits++; + } + } + + public void spawnVehicle(){ + + if (NGECore.getInstance().invasionService.getInvasionPhase()==2){ + if (spawnerFaction==Factions.Rebel){ + switch (spawnLevel) { + case 1: vehicleTemplates = rebelVehicleTemplates1; + case 2: vehicleTemplates = rebelVehicleTemplates2; + case 3: vehicleTemplates = rebelVehicleTemplates3; + } + } + if (spawnerFaction==Factions.Imperial){ + switch (spawnLevel) { + case 1: vehicleTemplates = imperialVehicleTemplates1; + case 2: vehicleTemplates = imperialVehicleTemplates2; + case 3: vehicleTemplates = imperialVehicleTemplates3; + } + } + String vehicleTemplate = vehicleTemplates[new Random().nextInt(vehicleTemplates.length)]; + CreatureObject vehicle = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(vehicleTemplate, this.getPlanet().getName(), 0L, this.getPosition().x, this.getPosition().y, this.getPosition().z, this.getOrientation().w, this.getOrientation().x, this.getOrientation().y,this.getOrientation().z,-1); + + NGECore.getInstance().aiService.setPatrol(vehicle, patrolRoute); + NGECore.getInstance().aiService.setPatrolLoop(vehicle,false); + NGECore.getInstance().invasionService.registerInvader(vehicle); + totalSpawnedUnits++; + } + } + + public void spawnSiegeVehicle(){ + + if (NGECore.getInstance().invasionService.getInvasionPhase()==2){ + if (spawnerFaction==Factions.Rebel){ + switch (spawnLevel) { + case 1: vehicleTemplates = rebelSiegeVehicleTemplates1; + case 2: vehicleTemplates = rebelSiegeVehicleTemplates2; + case 3: vehicleTemplates = rebelSiegeVehicleTemplates3; + } + } + if (spawnerFaction==Factions.Imperial){ + switch (spawnLevel) { + case 1: vehicleTemplates = imperialSiegeVehicleTemplates1; + case 2: vehicleTemplates = imperialSiegeVehicleTemplates2; + case 3: vehicleTemplates = imperialSiegeVehicleTemplates3; + } + } + String vehicleTemplate = vehicleTemplates[new Random().nextInt(vehicleTemplates.length)]; + CreatureObject vehicle = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(vehicleTemplate, this.getPlanet().getName(), 0L, this.getPosition().x, this.getPosition().y, this.getPosition().z, this.getOrientation().w, this.getOrientation().x, this.getOrientation().y,this.getOrientation().z,-1); + + NGECore.getInstance().aiService.setPatrol(vehicle, patrolRoute); + NGECore.getInstance().aiService.setPatrolLoop(vehicle,false); + NGECore.getInstance().invasionService.registerInvader(vehicle); + totalSpawnedUnits++; + } + } + + public void setPatrolRoute(int route){ + switch(route){ + case PatrolRoute.Dearic1: patrolRoute = get_Dearic_Route_1(); + break; + case PatrolRoute.Dearic2: patrolRoute = get_Dearic_Route_2(); + break; + case PatrolRoute.Dearic3: patrolRoute = get_Dearic_Route_3(); + break; + case PatrolRoute.Dearic4: patrolRoute = get_Dearic_Route_4(); + break; + case PatrolRoute.Dearic5: patrolRoute = get_Dearic_Route_5(); + break; + case PatrolRoute.Dearic6: patrolRoute = get_Dearic_Route_6(); + break; + case PatrolRoute.Dearic7: patrolRoute = get_Dearic_Route_7(); + break; + case PatrolRoute.Dearic8: patrolRoute = get_Dearic_Route_8(); + break; + case PatrolRoute.Dearic9: patrolRoute = get_Dearic_Route_9(); + break; + case PatrolRoute.Dearic10: patrolRoute = get_Dearic_Route_10(); + break; + case PatrolRoute.Dearic11: patrolRoute = get_Dearic_Route_11(); + break; + } + } + + public Vector get_Dearic_Route_1(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(68.0F, 6.00F, -2959F)); + patrolpoints.add(new Point3D(151.93F,6.00F, -2961.66F)); + patrolpoints.add(new Point3D(170.18F, 6.00F, -2992.99F)); + patrolpoints.add(new Point3D(262.76F, 6.00F, -2999.76F)); + patrolpoints.add(new Point3D(275.87F, 6.00F, -3008.44F)); + patrolpoints.add(new Point3D(303.41F, 6.00F, -3005.19F)); + patrolpoints.add(new Point3D(343.31F, 6.00F, -2961.06F)); + patrolpoints.add(new Point3D(379.98F, 6.00F, -2963.31F)); + patrolpoints.add(new Point3D(404.70F, 6.00F, -2980.57F)); + patrolpoints.add(new Point3D(412.54F, 6.00F, -3039.39F)); + patrolpoints.add(new Point3D(423.06F, 6.00F, -3050.75F)); + patrolpoints.add(new Point3D(446.92F, 6.00F, -3046.32F)); + patrolpoints.add(new Point3D(470.48F, 6.00F, -3023.43F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_2(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(76.0F, 6.00F, -2893F)); + patrolpoints.add(new Point3D(153.0F, 6.00F, -2898F)); + patrolpoints.add(new Point3D(162.89F, 6.00F, -2836.9F)); + patrolpoints.add(new Point3D(291.44F, 6.00F, -2844.6F)); + patrolpoints.add(new Point3D(333.19F, 6.00F, -2878.0F)); + patrolpoints.add(new Point3D(337.00F, 6.00F, -2954.0F)); + patrolpoints.add(new Point3D(378.00F, 6.00F, -2959.0F)); + patrolpoints.add(new Point3D(407.00F, 6.00F, -2978.0F)); + patrolpoints.add(new Point3D(414.00F, 6.00F, -3041.0F)); + patrolpoints.add(new Point3D(448.00F, 6.00F, -3043.0F)); + patrolpoints.add(new Point3D(463.00F, 6.00F, -3017.0F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_3(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(199.0F, 6.00F, -2790F)); + patrolpoints.add(new Point3D(200.0F, 6.00F, -2838F)); + patrolpoints.add(new Point3D(294.0F, 6.00F, -2841F)); + patrolpoints.add(new Point3D(335.0F, 6.00F, -2882F)); + patrolpoints.add(new Point3D(341.0F, 6.00F, -2950F)); + patrolpoints.add(new Point3D(378.0F, 6.00F, -2958F)); + patrolpoints.add(new Point3D(405.0F, 6.00F, -2981F)); + patrolpoints.add(new Point3D(414.00F, 6.00F, -3041.0F)); + patrolpoints.add(new Point3D(448.00F, 6.00F, -3043.0F)); + patrolpoints.add(new Point3D(473.0F, 6.00F, -3024F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_4(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(332.0F, 6.00F, -2715F)); + patrolpoints.add(new Point3D(324.0F, 6.00F, -2817F)); + patrolpoints.add(new Point3D(302.0F, 6.00F, -2835F)); + patrolpoints.add(new Point3D(338.0F, 6.00F, -2888F)); + patrolpoints.add(new Point3D(342.0F, 6.00F, -2949F)); + patrolpoints.add(new Point3D(407.0F, 6.00F, -2972F)); + patrolpoints.add(new Point3D(415.0F, 6.00F, -3055F)); + patrolpoints.add(new Point3D(451.0F, 6.00F, -3044F)); + patrolpoints.add(new Point3D(460.0F, 6.00F, -3011F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_5(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(384.0F, 6.00F, -2720F)); + patrolpoints.add(new Point3D(404.0F, 6.00F, -2817F)); + patrolpoints.add(new Point3D(417.0F, 6.00F, -2827F)); + patrolpoints.add(new Point3D(414.0F, 6.00F, -2854F)); + patrolpoints.add(new Point3D(384.0F, 6.00F, -2888F)); + patrolpoints.add(new Point3D(384.0F, 6.00F, -2959F)); + patrolpoints.add(new Point3D(407.0F, 6.00F, -2975F)); + patrolpoints.add(new Point3D(416.0F, 6.00F, -3049F)); + patrolpoints.add(new Point3D(450.0F, 6.00F, -3043F)); + patrolpoints.add(new Point3D(474.0F, 6.00F, -3025F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_6(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(590.0F, 6.00F, -2825F)); + patrolpoints.add(new Point3D(567.0F, 6.00F, -2860F)); + patrolpoints.add(new Point3D(563.0F, 6.00F, -2943F)); + patrolpoints.add(new Point3D(563.0F, 6.00F, -2943F)); + patrolpoints.add(new Point3D(507.0F, 6.00F, -2955F)); + patrolpoints.add(new Point3D(500.0F, 6.00F, -3011F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_7(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(723.0F, 6.00F, -2995F)); + patrolpoints.add(new Point3D(720.0F, 6.00F, -2964F)); + patrolpoints.add(new Point3D(623.0F, 6.00F, -2961F)); + patrolpoints.add(new Point3D(614.0F, 6.00F, -3010F)); + patrolpoints.add(new Point3D(510.0F, 6.00F, -3032F)); + patrolpoints.add(new Point3D(484.0F, 6.00F, -3021F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_8(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(733.0F, 6.00F, -3004F)); + patrolpoints.add(new Point3D(701.0F, 6.00F, -3004F)); + patrolpoints.add(new Point3D(699.0F, 6.00F, -3039F)); + patrolpoints.add(new Point3D(627.0F, 6.00F, -3041F)); + patrolpoints.add(new Point3D(605.0F, 6.00F, -3018F)); + patrolpoints.add(new Point3D(509.0F, 6.00F, -3033F)); + patrolpoints.add(new Point3D(496.0F, 6.00F, -3018F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_9(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(330.0F, 23.00F, -3402F)); + patrolpoints.add(new Point3D(360.0F, 6.00F, -3357F)); + patrolpoints.add(new Point3D(415.0F, 6.00F, -3273F)); + patrolpoints.add(new Point3D(464.0F, 6.00F, -3256F)); + patrolpoints.add(new Point3D(467.0F, 6.00F, -3236F)); + patrolpoints.add(new Point3D(498.0F, 6.00F, -3230F)); + patrolpoints.add(new Point3D(501.0F, 6.00F, -3205F)); + patrolpoints.add(new Point3D(481.0F, 6.00F, -3174F)); + patrolpoints.add(new Point3D(482.0F, 6.00F, -3126F)); + patrolpoints.add(new Point3D(437.0F, 6.00F, -3065F)); + patrolpoints.add(new Point3D(465.0F, 6.00F, -3019F)); + return patrolpoints; + } + + public Vector get_Dearic_Route_10(){// just for tests + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(618.0F, 6.00F, -2972F)); + patrolpoints.add(new Point3D(617.0F, 6.00F, -2980F)); + patrolpoints.add(new Point3D(616.0F, 6.00F, -2990F)); + patrolpoints.add(new Point3D(615.0F, 6.00F, -3010F)); + patrolpoints.add(new Point3D(500.0F, 6.00F, -3035F)); + + return patrolpoints; + } + + public Vector get_Dearic_Route_11(){ + Vector patrolpoints = new Vector(); + patrolpoints.add(new Point3D(332.0F, 6.00F, -2715F)); + return patrolpoints; + } + + public class SpawnerType { + + public static final int SoldierPatrol = 0; + public static final int SoldierDefense = 1; + public static final int VehiclePatrol = 2; + public static final int SiegeVehiclePatrol = 3; + public static final int Barricade = 4; + public static final int Turret = 5; + public static final int Tower = 6; + + } + /* + Soldier Patrol Pylons - Spawns a continuous stream of NPCs to aid in the battle - shown with a Helmet icon. + Vehicle Patrol Pylons - Spawns vehicles that are considerably more lethal than the Soldiers - shown with a Terminal icon. + Siege Vehicle Patrol Pylon - Spawns Rebel Hailfire Driods or Imperial AT-ATs (only spawn at a Level 3 Pylon) - shown with the same Terminal icon. + Barricade Pylon - Spawns a barricade that defends units behind it by giving them a defensive buff - shown with a Barricade icon. + Turret Pylon - Spawns an AI controlled turret that fires on enemy units - shown with a Gun Barrel or Turret Dish icon. + Tower Pylon - Spawns a watch tower that grants intelligence to nearby NPCs and offers combat missions to players - shown with a Tower icon. + */ + + public class PatrolRoute { + + public static final int Dearic1 = 0; + public static final int Dearic2 = 1; + public static final int Dearic3 = 2; + public static final int Dearic4 = 3; + public static final int Dearic5 = 4; + public static final int Dearic6 = 5; + public static final int Dearic7 = 6; + public static final int Dearic8 = 7; + public static final int Dearic9 = 8; + public static final int Dearic10 = 9; + public static final int Dearic11 = 10; + + } + + public int getTotalSpawnedUnits() { + return totalSpawnedUnits; + } + + public void setTotalSpawnedUnits(int totalSpawnedUnits) { + this.totalSpawnedUnits = totalSpawnedUnits; + } + +} diff --git a/src/services/gcw/InvasionService.java b/src/services/gcw/InvasionService.java index 1e4ed6c2..19a3f0ec 100644 --- a/src/services/gcw/InvasionService.java +++ b/src/services/gcw/InvasionService.java @@ -23,28 +23,40 @@ package services.gcw; import java.util.HashSet; import java.util.Map; +import java.util.Random; import java.util.Set; +import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import org.apache.mina.core.session.IoSession; + +import protocol.swg.CommPlayerMessage; import protocol.swg.UpdateContainmentMessage; +import resources.common.OutOfBand; import resources.datatables.FactionStatus; import resources.datatables.Factions; +import resources.datatables.GcwType; import resources.datatables.Options; import resources.datatables.WeaponType; import resources.objects.building.BuildingObject; import resources.objects.creature.CreatureObject; +import resources.objects.installation.InstallationMessageBuilder; import resources.objects.installation.InstallationObject; import resources.objects.tangible.TangibleObject; import resources.objects.weapon.WeaponObject; import services.ai.AIActor; import services.ai.TurretAIActor; -import services.gcw.GCWPylon.PatrolRoute; +import services.gcw.GCWSpawner.PatrolRoute; import services.gcw.GCWPylon.PylonType; +import services.gcw.GCWSpawner.SpawnerType; import main.NGECore; import engine.clients.Client; -import engine.resources.common.CRC; -import engine.resources.objects.SWGObject; +import engine.resources.scene.Planet; import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; import engine.resources.service.INetworkDispatch; @@ -61,14 +73,167 @@ public class InvasionService implements INetworkDispatch { private long dearicInvasionStartTime = 3; private CreatureObject invasionGeneral = null; + private CreatureObject defendingGeneral = null; + private CreatureObject defendingQuestOfficer = null; private int invasionLocation=InvasionLocation.Dearic; + private Point3D invasionLocationCenter; private int invadingFaction=Factions.Imperial; private int defendingFaction=Factions.Rebel; private int invasionPhase=2; // Test phase 2 + private long temptimestartreference = 0L; + private boolean message1sent = false; + private boolean message2sent = false; + private boolean message3sent = false; + private boolean message4sent = false; + + private ScheduledFuture eventManagerTask = null; + + private Map invadingCreatures = new ConcurrentHashMap(); + private int invaderRegistryCounter = 0; + private Map defendingCreatures = new ConcurrentHashMap(); + private int defenderRegistryCounter = 0; + private Vector defensiveBanners = new Vector(); + public InvasionService(final NGECore core) { this.core = core; + + Executors.newSingleThreadScheduledExecutor().schedule(() -> { + testPylons(); + // temp time reference, will be server time later + temptimestartreference = System.currentTimeMillis(); + scheduleInvasionEventManager(); + }, 30, TimeUnit.SECONDS); // Start invasion phase 2 after 30 seconds from server start + + + } + + public void scheduleInvasionEventManager(){ + + eventManagerTask = scheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + try { + invasionEventManager(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + }, 10, 2000, TimeUnit.MILLISECONDS); + } + + public void invasionEventManager(){ + + // Determine planet here + + setInvasionLocationCenter(); + + if (invasionPhase==2 && System.currentTimeMillis()>temptimestartreference + 90000 && ! message1sent){ + sendDefenderMessage1(); + message1sent = true; + System.out.println("Defender msg1 sent "); + } + if (invasionPhase==2 && System.currentTimeMillis()>temptimestartreference + 600000 && ! message2sent){ + sendDefenderMessage2(); + message2sent = true; + invasionPhase=3; + defendingGeneral.setOptionsBitmask(Options.ATTACKABLE); + makeDefensiveGeneralDefenderForNPCs(); + System.out.println("Defender msg2 sent "); // Local server gives only 30 mins time, so its 20 mins for this phase + } + if (invasionPhase==3 && System.currentTimeMillis()>temptimestartreference + 1000000 && ! message3sent){ + sendDefenderMessage3(); + message3sent = true; + sendInvaderLostMessage(); + sendDefenderWonMessage(); + System.out.println("Defender msg3 sent "); + } + + if (defendingGeneral!=null){ + if (invasionPhase==3 && (defendingGeneral.getPosture()==13 || defendingGeneral.getPosture()==14) && ! message4sent){ + sendInvaderWonMessage(); + sendDefenderLostMessage(); + message4sent = true; + invasionPhase=4; // Post-Invasion phase + System.out.println("Defender msg4 sent "); + + // Take care of GCW points + grantGCWPoints(invadingFaction,1000); + grantGCWPoints(defendingFaction,100); + // ToDo: tokens + + // Clean Up + wipeInvaders(); + wipeDefenders(); + } + } + } + + public void grantGCWPoints(int faction, int gcwPoints){ + String factionName = getFactionName(faction); + Vector allPlayers = core.simulationService.getAllNearSameFactionPlayers(500,invasionLocationCenter, getInvasionPlanet(invasionLocation), factionName); + for (CreatureObject player : allPlayers) { + if (player.getFaction().length() > 0 && player.getFactionStatus() > FactionStatus.OnLeave) { + core.gcwService.addGcwPoints(player, gcwPoints, GcwType.Enemy); + } + } + } + + public void registerInvader(CreatureObject registrant){ + invadingCreatures.put(invaderRegistryCounter++, registrant); + } + + public void registerDefender(CreatureObject registrant){ + defendingCreatures.put(invaderRegistryCounter++, registrant); + } + + public void wipeInvaders(){ + + for (Map.Entry entry : invadingCreatures.entrySet()) { + CreatureObject creature = entry.getValue(); + AIActor actor = (AIActor)creature.getAttachment("AI"); + core.simulationService.remove(creature, creature.getWorldPosition().x, creature.getWorldPosition().z, true); // Make sure + actor.destroyActor(); + } + + Executors.newSingleThreadScheduledExecutor().schedule(() -> { + for (Map.Entry entry : invadingCreatures.entrySet()) { + CreatureObject creature = entry.getValue(); + core.simulationService.remove(creature, creature.getWorldPosition().x, creature.getWorldPosition().z, true); // Make sure + core.objectService.destroyObject(creature.getObjectID()); + } + System.out.println("Destroyed all invaders."); + }, 15, TimeUnit.SECONDS); // Make sure remaining AI is finished with moves that might make them re-appear + } + + public void wipeDefenders(){ + + for (TangibleObject banner : defensiveBanners){ + core.objectService.destroyObject(banner.getObjectID()); + } + + core.objectService.destroyObject(defendingGeneral.getObjectID()); + core.objectService.destroyObject(defendingQuestOfficer.getObjectID()); + +// for (Map.Entry entry : defendingCreatures.entrySet()) { +// CreatureObject creature = entry.getValue(); +// AIActor actor = (AIActor)creature.getAttachment("AI"); +// core.simulationService.remove(creature, creature.getWorldPosition().x, creature.getWorldPosition().z, true); // Make sure +// actor.destroyActor(); +// } + + Executors.newSingleThreadScheduledExecutor().schedule(() -> { + for (Map.Entry entry : defendingCreatures.entrySet()) { + CreatureObject creature = entry.getValue(); + core.simulationService.remove(creature, creature.getWorldPosition().x, creature.getWorldPosition().z, true); // Make sure + core.objectService.destroyObject(creature.getObjectID()); + } + System.out.println("Destroyed all defenders."); + }, 15, TimeUnit.SECONDS); // Make sure remaining AI is finished with moves that might make them re-appear + } @@ -77,113 +242,156 @@ public class InvasionService implements INetworkDispatch { } public void spawnDefensiveAssets(){ - spawnGeneral(); + spawnDefendingGeneral(); spawnDefensiveQuestOfficer(); spawnBarricades(); spawnTurrets(); + spawnTower(); + spawnBanners(); + spawnSupplyTerminals(); + } + + public void spawnSupplyTerminals(){ } public void testPylons(){ + spawnDefensiveAssets(); + spawnOffensiveAssets(); + Quaternion quaternion = new Quaternion(0.28F,0F,0.95F,0F); - /* - GCWPylon pylon1 = (GCWPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(-48, 6, -2798), quaternion); + GCWSpawner pylon1 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(-48, 6, -2798), quaternion); core.simulationService.add(pylon1, pylon1.getPosition().x, pylon1.getPosition().z, true); pylon1.setPatrolRoute(PatrolRoute.Dearic1); - pylon1.setPylonType(PylonType.SoldierPatrol); - pylon1.setPylonFaction(invadingFaction); + pylon1.setSpawnerType(PylonType.SoldierPatrol); + pylon1.setSpawnerFaction(invadingFaction); pylon1.setSpawnLevel(3); - GCWPylon pylon2 = (GCWPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(-51, 6, -2798), quaternion); + GCWSpawner pylon2 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(-51, 6, -2798), quaternion); core.simulationService.add(pylon2, pylon2.getPosition().x, pylon2.getPosition().z, true); pylon2.setPatrolRoute(PatrolRoute.Dearic1); - pylon2.setPylonType(PylonType.VehiclePatrol); - pylon2.setPylonFaction(invadingFaction); + pylon2.setSpawnerType(PylonType.VehiclePatrol); + pylon2.setSpawnerFaction(invadingFaction); pylon2.setSpawnLevel(3); -// GCWPylon pylon4 = (GCWPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(506, 6, -3025), quaternion); +// GCWPylon pylon4 = (GCWPylon) core.objectService.createObject("object/tangible/gcw/shared_gcw_city_spawner.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(506, 6, -3025), quaternion); // core.simulationService.add(pylon4, pylon4.getPosition().x, pylon4.getPosition().z, true); // pylon4.setPylonType(PylonType.SoldierPatrol); // pylon4.setPylonFaction(invadingFaction); // pylon4.setSpawnLevel(3); - GCWPylon pylon3 = (GCWPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(5, 6, -2683), quaternion); + GCWSpawner pylon3 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(5, 6, -2683), quaternion); core.simulationService.add(pylon3, pylon3.getPosition().x, pylon3.getPosition().z, true); pylon3.setPatrolRoute(PatrolRoute.Dearic2); - pylon3.setPylonType(PylonType.SoldierPatrol); - pylon3.setPylonFaction(invadingFaction); + pylon3.setSpawnerType(SpawnerType.SoldierPatrol); + pylon3.setSpawnerFaction(invadingFaction); pylon3.setSpawnLevel(3); - - - GCWPylon pylon4 = (GCWPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(141, 6, -2517), quaternion); + + GCWSpawner pylon4 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(141, 6, -2517), quaternion); core.simulationService.add(pylon4, pylon4.getPosition().x, pylon4.getPosition().z, true); pylon4.setPatrolRoute(PatrolRoute.Dearic3); - pylon4.setPylonType(PylonType.SoldierPatrol); - pylon4.setPylonFaction(invadingFaction); + pylon4.setSpawnerType(SpawnerType.SoldierPatrol); + pylon4.setSpawnerFaction(invadingFaction); pylon4.setSpawnLevel(3); - GCWPylon pylon5 = (GCWPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(275, 6, -2481), quaternion); + GCWSpawner pylon5 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(275, 6, -2481), quaternion); core.simulationService.add(pylon5, pylon5.getPosition().x, pylon5.getPosition().z, true); pylon5.setPatrolRoute(PatrolRoute.Dearic4); - pylon5.setPylonType(PylonType.SoldierPatrol); - pylon5.setPylonFaction(invadingFaction); + pylon5.setSpawnerType(SpawnerType.SoldierPatrol); + pylon5.setSpawnerFaction(invadingFaction); pylon5.setSpawnLevel(3); - GCWPylon pylon6 = (GCWPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(519, 6, -2452), quaternion); + GCWSpawner pylon5a = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(271, 6, -2481), quaternion); + core.simulationService.add(pylon5a, pylon5a.getPosition().x, pylon5a.getPosition().z, true); + pylon5a.setPatrolRoute(PatrolRoute.Dearic11); + pylon5a.setSpawnerType(SpawnerType.SiegeVehiclePatrol); + pylon5a.setSpawnerFaction(invadingFaction); + pylon5a.setSpawnLevel(3); + + GCWSpawner pylon6 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(519, 6, -2452), quaternion); core.simulationService.add(pylon6, pylon6.getPosition().x, pylon6.getPosition().z, true); pylon6.setPatrolRoute(PatrolRoute.Dearic5); - pylon6.setPylonType(PylonType.SoldierPatrol); - pylon6.setPylonFaction(invadingFaction); + pylon6.setSpawnerType(SpawnerType.SoldierPatrol); + pylon6.setSpawnerFaction(invadingFaction); pylon6.setSpawnLevel(3); - GCWPylon pylon7 = (GCWPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(845, 6, -2550), quaternion); + GCWSpawner pylon7 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(845, 6, -2550), quaternion); core.simulationService.add(pylon7, pylon7.getPosition().x, pylon7.getPosition().z, true); pylon7.setPatrolRoute(PatrolRoute.Dearic6); - pylon7.setPylonType(PylonType.SoldierPatrol); - pylon7.setPylonFaction(invadingFaction); + pylon7.setSpawnerType(SpawnerType.SoldierPatrol); + pylon7.setSpawnerFaction(invadingFaction); pylon7.setSpawnLevel(3); - GCWPylon pylon8 = (GCWPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(1082, 6, -2855), quaternion); + GCWSpawner pylon8 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(1082, 6, -2855), quaternion); core.simulationService.add(pylon8, pylon8.getPosition().x, pylon8.getPosition().z, true); pylon8.setPatrolRoute(PatrolRoute.Dearic7); - pylon8.setPylonType(PylonType.SoldierPatrol); - pylon8.setPylonFaction(invadingFaction); + pylon8.setSpawnerType(SpawnerType.SoldierPatrol); + pylon8.setSpawnerFaction(invadingFaction); pylon8.setSpawnLevel(3); - GCWPylon pylon9 = (GCWPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(946, 6, -3075), quaternion); + GCWSpawner pylon9 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(946, 6, -3075), quaternion); core.simulationService.add(pylon9, pylon9.getPosition().x, pylon9.getPosition().z, true); pylon9.setPatrolRoute(PatrolRoute.Dearic8); - pylon9.setPylonType(PylonType.SoldierPatrol); - pylon9.setPylonFaction(invadingFaction); + pylon9.setSpawnerType(SpawnerType.SoldierPatrol); + pylon9.setSpawnerFaction(invadingFaction); pylon9.setSpawnLevel(3); - GCWPylon pylon10 = (GCWPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(314, 43, -3546), quaternion); + GCWSpawner pylon10 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(314, 43, -3546), quaternion); core.simulationService.add(pylon10, pylon10.getPosition().x, pylon10.getPosition().z, true); pylon10.setPatrolRoute(PatrolRoute.Dearic9); - pylon10.setPylonType(PylonType.SoldierPatrol); - pylon10.setPylonFaction(invadingFaction); + pylon10.setSpawnerType(SpawnerType.SoldierPatrol); + pylon10.setSpawnerFaction(invadingFaction); pylon10.setSpawnLevel(3); - */ + + // to test turret // object/tangible/destructible/shared_gcw_city_construction_beacon.iff +// GCWSpawner pylon10a = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(618, 4, -2963), quaternion); +// core.simulationService.add(pylon10a, pylon10a.getPosition().x, pylon10a.getPosition().z, true); +// pylon10a.setPatrolRoute(PatrolRoute.Dearic10); +// pylon10a.setSpawnerType(PylonType.SoldierPatrol); +// pylon10a.setSpawnerFaction(invadingFaction); +// pylon10a.setSpawnLevel(3); + + + // Defenders object/tangible/ground_spawning/shared_patrol_spawner.iff + GCWSpawner pylonD1 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(410.98F, 6, -2988.05F), quaternion); + core.simulationService.add(pylonD1, pylonD1.getPosition().x, pylonD1.getPosition().z, true); + pylonD1.setSpawnerType(PylonType.SoldierDefense); + pylonD1.setSpawnerFaction(defendingFaction); + pylonD1.setSpawnLevel(3); + + GCWSpawner pylonD2 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(500, 6, -2954), quaternion); + core.simulationService.add(pylonD2, pylonD2.getPosition().x, pylonD2.getPosition().z, true); + pylonD2.setSpawnerType(SpawnerType.SoldierDefense); + pylonD2.setSpawnerFaction(defendingFaction); + pylonD2.setSpawnLevel(3); + + GCWSpawner pylonD3 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(548, 6, -2941), quaternion); + core.simulationService.add(pylonD3, pylonD3.getPosition().x, pylonD3.getPosition().z, true); + pylonD3.setSpawnerType(SpawnerType.SoldierDefense); + pylonD3.setSpawnerFaction(defendingFaction); + pylonD3.setSpawnLevel(3); + + GCWSpawner pylonD4 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(449F, 6, -3077), quaternion); + core.simulationService.add(pylonD4, pylonD4.getPosition().x, pylonD4.getPosition().z, true); + pylonD4.setSpawnerType(SpawnerType.SoldierDefense); + pylonD4.setSpawnerFaction(defendingFaction); + pylonD4.setSpawnLevel(3); - // to test turret - GCWPylon pylon10a = (GCWPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(621, 4, -2996), quaternion); - core.simulationService.add(pylon10a, pylon10a.getPosition().x, pylon10a.getPosition().z, true); - pylon10a.setPatrolRoute(PatrolRoute.Dearic10); - pylon10a.setPylonType(PylonType.SoldierPatrol); - pylon10a.setPylonFaction(invadingFaction); - pylon10a.setSpawnLevel(3); + GCWSpawner pylonD5 = (GCWSpawner) core.objectService.createObject("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(339F, 6, -2742), quaternion); + core.simulationService.add(pylonD5, pylonD5.getPosition().x, pylonD5.getPosition().z, true); + pylonD5.setSpawnerType(SpawnerType.SoldierDefense); + pylonD5.setSpawnerFaction(defendingFaction); + pylonD5.setSpawnLevel(3); - spawnDefensiveAssets(); - spawnOffensiveAssets(); } - public void spawnGeneral(){ + public void spawnDefendingGeneral(){ System.out.println("Spawn general"); String generalTemplate = ""; if (invadingFaction==Factions.Imperial){ @@ -194,13 +402,13 @@ public class InvasionService implements INetworkDispatch { } if (invasionLocation==InvasionLocation.Keren){ - invasionGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(generalTemplate, "naboo", 0L, 1786, 6, 2511, 1, 0); + defendingGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(generalTemplate, "naboo", 0L, 1786, 6, 2511, 1, 0); } if (invasionLocation==InvasionLocation.Bestine){ - invasionGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(generalTemplate, "tatooine", 0L, -1214, 6, -3626, 1, 0); + defendingGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(generalTemplate, "tatooine", 0L, -1214, 6, -3626, 1, 0); } if (invasionLocation==InvasionLocation.Dearic){ - invasionGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(generalTemplate, "talus", 0L, 480.071F, 6, -3006.851F, 1, 0); + defendingGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(generalTemplate, "talus", 0L, 480.071F, 6, -3006.851F, 1, 0); } } @@ -216,71 +424,514 @@ public class InvasionService implements INetworkDispatch { } if (invasionLocation==InvasionLocation.Keren){ - invasionGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(questOfficerTemplate, "naboo", 0L, 1787, 6, 2512, 1, 0); + defendingQuestOfficer = (CreatureObject) NGECore.getInstance().staticService.spawnObject(questOfficerTemplate, "naboo", 0L, 1787, 6, 2512, 1, 0); } if (invasionLocation==InvasionLocation.Bestine){ - invasionGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(questOfficerTemplate, "tatooine", 0L, -1195, 6, -3620, 1, 0); + defendingQuestOfficer = (CreatureObject) NGECore.getInstance().staticService.spawnObject(questOfficerTemplate, "tatooine", 0L, -1195, 6, -3620, 1, 0); } if (invasionLocation==InvasionLocation.Dearic){ - invasionGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(questOfficerTemplate, "talus", 0L, 478, 6, -3023, 0, 1); + defendingQuestOfficer = (CreatureObject) NGECore.getInstance().staticService.spawnObject(questOfficerTemplate, "talus", 0L, 478, 6, -3023, 0, 1); } } public void spawnOffensiveCamps(){ -// Quaternion quaternion = new Quaternion(0.28F,0F,0.95F,0F); -// String campTemplate = "object/building/military/shared_gcw_battlefield_base.iff"; -// //String campTemplate = "object/building/poi/shared_gcw_rebel_clone_tent_small.iff"; // LOL why doesn't this spawn?!?!?! -// BuildingObject camp = (BuildingObject) core.objectService.createObject(campTemplate, 0, core.terrainService.getPlanetByName("talus"), new Point3D(-890,9, -2994), quaternion); -// core.simulationService.add(camp, camp.getPosition().x, camp.getPosition().z, true); + Quaternion quaternion = new Quaternion(0.00F,0F,1.00F,0F); + String campTemplate = "object/building/military/shared_gcw_battlefield_base.iff"; + //String campTemplate = "object/building/poi/shared_gcw_rebel_clone_tent_small.iff"; // LOL why doesn't this spawn?!?!?! + BuildingObject camp = (BuildingObject) core.objectService.createObject(campTemplate, 0, core.terrainService.getPlanetByName("talus"), new Point3D(-890,9, -2994), quaternion); + //TangibleObject camp = (TangibleObject) core.objectService.createObject(campTemplate, 0, core.terrainService.getPlanetByName("talus"), new Point3D(-890,9, -2994), quaternion); + core.simulationService.add(camp, camp.getPosition().x, camp.getPosition().z, true); + System.out.println("checkForObject: " + core.simulationService.checkForObject(30, camp)); + System.out.println("camp: " + camp.getTemplate()); } public void spawnBarricades(){ - Quaternion quaternion = new Quaternion(0.28F,0F,0.95F,0F); - String campTemplate = "object/tangible/destructible/shared_gcw_rebel_barricade.iff"; - //String campTemplate = "object/building/poi/shared_gcw_rebel_clone_tent_small.iff"; // LOL why doesn't this spawn?!?!?! - TangibleObject barricade = (TangibleObject) core.objectService.createObject(campTemplate, 0, core.terrainService.getPlanetByName("talus"), new Point3D( 475, 6, -3013), quaternion); - core.simulationService.add(barricade, barricade.getPosition().x, barricade.getPosition().z, true); - barricade.setCustomName("Rebel Barricade"); - //barricade.setOptions(Options.ATTACKABLE, true); - barricade.setOptionsBitmask(Options.ATTACKABLE | Options.QUEST); - barricade.setFaction("rebel"); - barricade.setFactionStatus(FactionStatus.Combatant); - barricade.setMaximumCondition(50000); + createBarricade("object/tangible/destructible/shared_gcw_rebel_barricade.iff", 480.05F, 6, -3009.93F, 1.0F, 0F, 50000); + createBarricade("object/tangible/destructible/shared_gcw_rebel_barricade.iff", 483.42F, 6, -3007.00F, -0.7F, 0.7F, 50000); + createBarricade("object/tangible/destructible/shared_gcw_rebel_barricade.iff", 476.95F, 6, -3006.85F, -0.69F, 0.716F, 50000); + + createBarricade("object/tangible/destructible/shared_gcw_rebel_barricade.iff", 410.82F, 6, -3012.75F, 1.00F, 0.00F, 50000); + + createBarricade("object/tangible/destructible/shared_gcw_rebel_barricade.iff", 431.76F, 6, -3072.4F, 0.41F, 0.91F, 50000); + createBarricade("object/tangible/destructible/shared_gcw_rebel_barricade.iff", 444.5F, 6, -3074.5F, 0.41F, 0.91F, 50000); + + createBarricade("object/tangible/destructible/shared_gcw_rebel_barricade.iff", 509.8F, 6, -2955.06F, 0.72F, 0.69F, 50000); // Bank + + createBarricade("object/tangible/destructible/shared_gcw_rebel_barricade.iff", 552.81F, 6, -2938.06F, 0.72F, 0.69F, 50000); + + + createBarricade("object/tangible/destructible/shared_gcw_rebel_barricade.iff", 387.98F, 6, -2742.24F, 0.032F, 0.999F, 50000); + createBarricade("object/tangible/destructible/shared_gcw_rebel_barricade.iff", 332.25F, 6, -2741.97F, 0.032F, 0.999F, 50000); } public void spawnTurrets(){ - Quaternion quaternion = new Quaternion(0.28F,0F,0.95F,0F); - String turretTemplate = "object/installation/turret/gcw/shared_adv_turret_dish_sm_heat.iff"; - //String turretTemplate = "object/tangible/destructible/shared_gcw_rebel_turret.iff"; - InstallationObject turret = (InstallationObject) core.objectService.createObject(turretTemplate, 0, core.terrainService.getPlanetByName("talus"), new Point3D( 557, 6, -3028), quaternion); + + createTurret("object/installation/turret/gcw/shared_adv_turret_dish_large_heat.iff", 557, 6, -3028, 0.62F, 0.78F, 2000, 2400); + createTurret("object/installation/turret/gcw/shared_adv_turret_dish_large_heat.iff", 405.09F, 6, -3020.4F, 1.00F, 0.00F, 2000, 2400); + createTurret("object/installation/turret/gcw/shared_adv_turret_dish_large_heat.iff", 423.5F, 6, -3059.5F, 0.97F, -0.23F, 2000, 2400); + createTurret("object/installation/turret/gcw/shared_adv_turret_dish_large_heat.iff", 498.87F, 6, -2950.12F, 0.72F, 0.69F, 2000, 2400); + // object/tangible/destructible/shared_gcw_rebel_turret.iff crashes the client, not fixable + + createTurret("object/installation/turret/gcw/shared_adv_turret_dish_large_heat.iff", 378.07F, 6, -2742.26F, -0.023F, 0.999F, 2000, 2400); + } + + public void createTurret(String turretTemplate, float x, float y, float z, float qy, float qw, int minDamage, int maxDamage){ + Quaternion quaternion = new Quaternion(qy,0F,qw,0F); + InstallationObject turret = (InstallationObject) core.objectService.createObject(turretTemplate, 0, getInvasionPlanet(invasionLocation), new Point3D(x, y, z), quaternion); + //TangibleObject turret = (TangibleObject) core.objectService.createObject(turretTemplate, 0, getInvasionPlanet(invasionLocation), new Point3D(x, y, z), quaternion); core.simulationService.add(turret, turret.getPosition().x, turret.getPosition().z, true); - turret.setCustomName("Rebel Turret"); + String customName = "Rebel Turret"; + String factionString = "rebel"; + if (defendingFaction==Factions.Imperial){ + customName = "Imperial Turret"; + factionString = "imperial"; + } + turret.setCustomName(customName); +// turret.setCustomName2(customName); + +// turret.setStfFilename(stfFilename); +// turret.setStfName(stfName); + +// InstallationMessageBuilder messageBuilder = new InstallationMessageBuilder(); +// // steal a session for lack of a better method +// Client stolenClient = null; +// synchronized(core.getActiveConnectionsMap()) { +// for (Client client : core.getActiveConnectionsMap().values()) { +// if (client.getParent() != null && client.getParent() instanceof CreatureObject) { +// if (((CreatureObject)client.getParent()).isPlayer()) +// stolenClient = client; +// } +// } +// } +// if (stolenClient!=null) +// stolenClient.getSession().write(messageBuilder.buildCustomNameDelta(turret,customName)); + turret.setOptionsBitmask(Options.ATTACKABLE | Options.QUEST); - turret.setFaction("rebel"); + turret.setFaction(factionString); turret.setFactionStatus(FactionStatus.Combatant); turret.setMaximumCondition(50000); TurretAIActor actor = new TurretAIActor(turret, turret.getPosition(), scheduler); turret.setAttachment("AI", actor); - turret.setFaction("rebel"); - - // const static int TURRET = 0x1004; - WeaponObject defaultWeapon = (WeaponObject) core.objectService.createObject("object/weapon/ranged/turret/shared_turret_heat.iff", turret.getPlanet()); - defaultWeapon.setAttackSpeed(1.0F); - defaultWeapon.setWeaponType(WeaponType.RIFLE); - defaultWeapon.setMaxRange(14.0F); // defaultWeapon.setMaxRange(60.0F); - defaultWeapon.setDamageType("energy"); - defaultWeapon.setMinDamage(2000); - defaultWeapon.setMaxDamage(2400); - turret.add(defaultWeapon); - turret.setAttachment("TurretWeapon",defaultWeapon.getObjectID()); + + WeaponObject turretWeapon = (WeaponObject) core.objectService.createObject("object/weapon/ranged/turret/shared_turret_heat.iff", turret.getPlanet()); + turretWeapon.setAttackSpeed(5.0F); + //turretWeapon.setAttackSpeed(0.50F); + turretWeapon.setWeaponType(WeaponType.RIFLE); + turretWeapon.setMaxRange(60.0F); // setMaxRange(60.0F); 14.0F + turretWeapon.setDamageType("energy"); + turretWeapon.setMinDamage(minDamage); + turretWeapon.setMaxDamage(maxDamage); + turret.add(turretWeapon); + turret.setAttachment("TurretWeapon",turretWeapon.getObjectID()); Set newObservers = new HashSet(turret.getObservers()); for(Client c : newObservers) { - UpdateContainmentMessage ucm = new UpdateContainmentMessage(defaultWeapon.getObjectID(), turret.getObjectID(), 4); + UpdateContainmentMessage ucm = new UpdateContainmentMessage(turretWeapon.getObjectID(), turret.getObjectID(), 4); c.getSession().write(ucm.serialize()); } } + public void createBarricade(String barricadeTemplate, float x, float y, float z, float qy, float qw, int maxCondition){ + Quaternion quaternion = new Quaternion(qy,0F,qw,0F); + TangibleObject barricade = (TangibleObject) core.objectService.createObject(barricadeTemplate, 0, getInvasionPlanet(invasionLocation), new Point3D(x, y, z), quaternion); + core.simulationService.add(barricade, barricade.getPosition().x, barricade.getPosition().z, true); + String customName = "Rebel Barricade"; + String factionString = "rebel"; + if (defendingFaction==Factions.Imperial){ + customName = "Imperial Barricade"; + factionString = "imperial"; + } + barricade.setCustomName(customName); + barricade.setOptionsBitmask(Options.ATTACKABLE | Options.QUEST); + barricade.setFaction(factionString); + barricade.setFactionStatus(FactionStatus.Combatant); + barricade.setMaximumCondition(maxCondition); + + final Future[] fut = {null}; + fut[0] = scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + if (NGECore.getInstance().objectService.getObject(barricade.getObjectID())==null){ + Thread.yield(); + fut[0].cancel(false); + } + + Vector nearAllies = NGECore.getInstance().simulationService.getAllNearSameFactionNPCs(5, barricade); + for (CreatureObject ally : nearAllies){ + if (! ally.hasBuff("barricade_defender")){ + core.buffService.addBuffToCreature(ally, "barricade_defender", ally); + } else { + /*System.out.println("HASBUFF " + nearAllies.size());*/ +// if (ally.getClient()!=null) +// System.out.println("ALLY: " + ally.getCustomName()); + } + } // towFacGuardDefenseItem + Thread.currentThread().interrupt(); + } catch (Exception e) { + System.err.println("Exception in Barricade thread " + e.getMessage()); + } + } + }, 5, 2, TimeUnit.SECONDS); + } + // gcw_general_resistance_stack_rebel + // for Towers: tower_defender + + public void spawnTower(){ + createTower(548.8F, 6, -2872.06F, 0.72F, 0.69F, 100000); + } + + public void createTower(float x, float y, float z, float qy, float qw, int maxCondition){ + Quaternion quaternion = new Quaternion(qy,0F,qw,0F); + String towerTemplate = "object/tangible/destructible/shared_gcw_rebel_tower.iff"; + String factionString = "rebel"; + String towerString = "Rebel Tower"; + if (defendingFaction==Factions.Imperial){ + towerTemplate = "object/tangible/destructible/shared_gcw_imperial_tower.iff"; + factionString = "imperial"; + towerString = "Imperial Tower"; + } + TangibleObject tower = (TangibleObject) core.objectService.createObject(towerTemplate, 0, getInvasionPlanet(invasionLocation), new Point3D(x, y, z), quaternion); + core.simulationService.add(tower, tower.getPosition().x, tower.getPosition().z, true); + tower.setCustomName(towerString); + tower.setOptionsBitmask(Options.ATTACKABLE | Options.QUEST); + tower.setFaction(factionString); + tower.setFactionStatus(FactionStatus.Combatant); + tower.setMaximumCondition(maxCondition); + + final Future[] fut = {null}; + fut[0] = scheduler.scheduleAtFixedRate(new Runnable() { + @Override public void run() { + try { + if (NGECore.getInstance().objectService.getObject(tower.getObjectID())==null){ + Thread.yield(); + fut[0].cancel(false); + } + + Vector nearAllies = NGECore.getInstance().simulationService.getAllNearSameFactionNPCs(500, tower); + for (CreatureObject ally : nearAllies){ + if (!ally.isPlayer()){ + if (! ally.hasBuff("tower_defender")){ + core.buffService.addBuffToCreature(ally, "tower_defender", ally); + } + } + } + Thread.currentThread().interrupt(); + } catch (Exception e) { + System.err.println("Exception in Tower thread " + e.getMessage()); + } + } + }, 5, 2, TimeUnit.SECONDS); + } + + + public void spawnBanners(){ + + // Starport + createBanner(329.34F, 6, -2936.67F, 0.71F, 0.7F); + createBanner(329.34F, 6, -2925.15F, 0.71F, 0.7F); + + createBanner(414.98F, 6, -3027.86F, 0.71F, -0.7F); + createBanner(414.98F, 6, -2988.05F, 0.71F, -0.7F); + createBanner(448.98F, 6, -3028.05F, 0.68F, -0.73F); + createBanner(448.98F, 6, -2987.95F, 0.70F, 0.71F); + + createBanner(369.96F, 6, -2944.02F, 1.00F, 0.0F); + + createBanner(537.96F, 6, -3038.97F, 0.00F, 1.0F); + + createBanner(569.96F, 6, -2940.37F, 0.71F, -0.69F); + + createBanner(476.09F, 6, -2955.1F, 0.71F, 0.69F); + + createBanner(471.56F, 6, -3004.66F, 1.0F, 0.00F); + createBanner(488.40F, 6, -3004.66F, 1.0F, 0.00F); + + createBanner(524.88F, 6.51F, -3004.96F, 0.927F, 0.374F); + createBanner(525.03F, 6.51F, -2974.90F, 0.91F, -0.41F); + createBanner(555.13F, 6.51F, -2975.05F, 0.93F, 0.37F); + createBanner(555.15F, 6.51F, -3004.96F, 0.39F, 0.922F); + + } + + public void createBanner(float x, float y, float z, float qy, float qw){ + Quaternion quaternion = new Quaternion(qy,0F,qw,0F); //object/installation/battlefield/destructible shared_banner_rebel_style_01.iff + String bannerTemplate = "object/tangible/gcw/shared_flip_banner_onpole_rebel.iff"; //object/tangible/event_perk/shared_banner_rebel_style_01.iff + String factionString = "rebel_banner"; + if (defendingFaction==Factions.Imperial){ + bannerTemplate = "object/tangible/gcw/shared_flip_banner_onpole_imperial.iff"; + factionString = "imperial_banner"; + } + TangibleObject banner = (TangibleObject) core.objectService.createObject(bannerTemplate, 0, getInvasionPlanet(invasionLocation), new Point3D(x, y, z), quaternion); + core.simulationService.add(banner, banner.getPosition().x, banner.getPosition().z, true); + banner.setStfFilename("obj_n"); + banner.setStfName(factionString); + banner.setDetailFilename("obj_d"); + banner.setDetailName(factionString); + defensiveBanners.add(banner); + } + + public int getInvasionPhase() { + return invasionPhase; + } + + public void setInvasionPhase(int invasionPhase) { + this.invasionPhase = invasionPhase; + } + + public void sendInvaderMessage1(){ + String message = ""; + if (invadingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_attack_city_imperial_talus_dearic"; + if (invadingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_attack_city_rebel_talus_dearic"; + + ConcurrentHashMap clients = NGECore.getInstance().getActiveConnectionsMap(); + for (Map.Entry entry : clients.entrySet()) { + Client client = entry.getValue(); + if (client.getParent().getPlanet().equals(getInvasionPlanet(invasionLocation))){ + CommPlayerMessage comm = new CommPlayerMessage(client.getParent().getObjectId(), OutOfBand.ProsePackage(message)); + comm.setTime(2000); + comm.setModel("object/mobile/shared_dressed_assassin_mission_giver_0" + Integer.toString(new Random().nextInt(2) + 1) + ".iff"); + client.getSession().write(comm.serialize()); + } + } + } + + public void sendDefenderMessage1(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_rally_for_invasion_imperial_talus_dearic"; + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_rally_for_invasion_rebel_talus_dearic"; + ConcurrentHashMap clients = NGECore.getInstance().getActiveConnectionsMap(); + for (Map.Entry entry : clients.entrySet()) { + Client client = entry.getValue(); + if (client.getParent()!=null){ + if (client.getParent().getPlanet().equals(getInvasionPlanet(invasionLocation))){ + CommPlayerMessage comm = new CommPlayerMessage(client.getParent().getObjectId(), OutOfBand.ProsePackage(message)); + comm.setTime(2000); + comm.setModel(defendingGeneral.getTemplate()); + client.getSession().write(comm.serialize()); + } + } + } + } + + public void sendInvaderMessage2(){ + String message = ""; + if (invadingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_attack_half_done_imperial_talus_dearic"; + if (invadingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_attack_city_rebel_talus_dearic"; + + ConcurrentHashMap clients = NGECore.getInstance().getActiveConnectionsMap(); + for (Map.Entry entry : clients.entrySet()) { + Client client = entry.getValue(); + if (client.getParent()!=null){ + if (client.getParent().getPlanet().equals(getInvasionPlanet(invasionLocation))){ + CommPlayerMessage comm = new CommPlayerMessage(client.getParent().getObjectId(), OutOfBand.ProsePackage(message)); + comm.setTime(2000); + comm.setModel("object/mobile/shared_dressed_assassin_mission_giver_0" + Integer.toString(new Random().nextInt(2) + 1) + ".iff"); + client.getSession().write(comm.serialize()); + } + } + } + } + + public void sendDefenderMessage2(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_defense_half_done_imperial_talus_dearic"; + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_defense_half_done_rebel_talus_dearic"; + ConcurrentHashMap clients = NGECore.getInstance().getActiveConnectionsMap(); + for (Map.Entry entry : clients.entrySet()) { + Client client = entry.getValue(); + if (client.getParent()!=null){ + if (client.getParent().getPlanet().equals(getInvasionPlanet(invasionLocation))){ + CommPlayerMessage comm = new CommPlayerMessage(client.getParent().getObjectId(), OutOfBand.ProsePackage(message)); + comm.setTime(2000); + comm.setModel(defendingGeneral.getTemplate()); + client.getSession().write(comm.serialize()); + } + } + } + } + + public void sendInvaderMessage3(){ + String message = ""; + if (invadingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_attack_half_done_imperial_talus_dearic"; + if (invadingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_attack_city_rebel_talus_dearic"; + + ConcurrentHashMap clients = NGECore.getInstance().getActiveConnectionsMap(); + for (Map.Entry entry : clients.entrySet()) { + Client client = entry.getValue(); + if (client.getParent()!=null){ + if (client.getParent().getPlanet().equals(getInvasionPlanet(invasionLocation))){ + CommPlayerMessage comm = new CommPlayerMessage(client.getParent().getObjectId(), OutOfBand.ProsePackage(message)); + comm.setTime(2000); + comm.setModel("object/mobile/shared_dressed_assassin_mission_giver_0" + Integer.toString(new Random().nextInt(2) + 1) + ".iff"); + client.getSession().write(comm.serialize()); + } + } + } + } + + public void sendDefenderMessage3(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_defense_half_done_imperial_talus_dearic"; + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_defense_half_done_rebel_talus_dearic"; + ConcurrentHashMap clients = NGECore.getInstance().getActiveConnectionsMap(); + for (Map.Entry entry : clients.entrySet()) { + Client client = entry.getValue(); + if (client.getParent()!=null){ + if (client.getParent().getPlanet().equals(getInvasionPlanet(invasionLocation))){ + CommPlayerMessage comm = new CommPlayerMessage(client.getParent().getObjectId(), OutOfBand.ProsePackage(message)); + comm.setTime(2000); + comm.setModel(defendingGeneral.getTemplate()); + client.getSession().write(comm.serialize()); + } + } + } + } + + + public void sendInvaderWonMessage(){ + String message = ""; + if (invadingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_city_won_imperial_talus_dearic"; + if (invadingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_city_won_rebel_talus_dearic"; + + ConcurrentHashMap clients = NGECore.getInstance().getActiveConnectionsMap(); + for (Map.Entry entry : clients.entrySet()) { + Client client = entry.getValue(); + if (client.getParent()!=null){ + if (client.getParent().getPlanet().equals(getInvasionPlanet(invasionLocation))){ + CommPlayerMessage comm = new CommPlayerMessage(client.getParent().getObjectId(), OutOfBand.ProsePackage(message)); + comm.setTime(2000); + comm.setModel("object/mobile/shared_dressed_assassin_mission_giver_0" + Integer.toString(new Random().nextInt(2) + 1) + ".iff"); + client.getSession().write(comm.serialize()); + } + } + } + } + + public void sendDefenderWonMessage(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_won_attack_imeprial_talus_dearic"; + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_won_attack_rebel_talus_dearic"; + ConcurrentHashMap clients = NGECore.getInstance().getActiveConnectionsMap(); + for (Map.Entry entry : clients.entrySet()) { + Client client = entry.getValue(); + if (client.getParent()!=null){ + if (client.getParent().getPlanet().equals(getInvasionPlanet(invasionLocation))){ + CommPlayerMessage comm = new CommPlayerMessage(client.getParent().getObjectId(), OutOfBand.ProsePackage(message)); + comm.setTime(2000); + comm.setModel(defendingGeneral.getTemplate()); + client.getSession().write(comm.serialize()); + } + } + } + } + + public void sendInvaderLostMessage(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_city_lost_imperial_tatooine_bestine"; + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_city_lost_rebel_talus_dearic"; + + ConcurrentHashMap clients = NGECore.getInstance().getActiveConnectionsMap(); + for (Map.Entry entry : clients.entrySet()) { + Client client = entry.getValue(); + if (client.getParent()!=null){ + if (client.getParent().getPlanet().equals(getInvasionPlanet(invasionLocation))){ + CommPlayerMessage comm = new CommPlayerMessage(client.getParent().getObjectId(), OutOfBand.ProsePackage(message)); + comm.setTime(2000); + comm.setModel("object/mobile/shared_dressed_assassin_mission_giver_0" + Integer.toString(new Random().nextInt(2) + 1) + ".iff"); + client.getSession().write(comm.serialize()); + } + } + } + } + + public void sendDefenderLostMessage(){ + String message = ""; + if (defendingFaction==Factions.Imperial) + message = "@gcw:gcw_announcement_city_lost_imperial_talus_dearic"; + if (defendingFaction==Factions.Rebel) + message = "@gcw:gcw_announcement_city_lost_rebel_talus_dearic"; + ConcurrentHashMap clients = NGECore.getInstance().getActiveConnectionsMap(); + for (Map.Entry entry : clients.entrySet()) { + Client client = entry.getValue(); + if (client.getParent()!=null){ + if (client.getParent().getPlanet().equals(getInvasionPlanet(invasionLocation))){ + CommPlayerMessage comm = new CommPlayerMessage(client.getParent().getObjectId(), OutOfBand.ProsePackage(message)); + comm.setTime(2000); + comm.setModel(defendingGeneral.getTemplate()); + client.getSession().write(comm.serialize()); + } + } + } + } + + + public Planet getInvasionPlanet(int location){ + Planet planet = null; + switch (location){ + case InvasionLocation.Dearic : planet = core.terrainService.getPlanetByName("talus"); + break; + case InvasionLocation.Keren : planet = core.terrainService.getPlanetByName("naboo"); + break; + case InvasionLocation.Bestine : planet = core.terrainService.getPlanetByName("tatooine"); + break; + } + return planet; + } + + public void makeDefensiveGeneralDefenderForNPCs(){ + Vector enemies = core.simulationService.getAllNearNonSameFactionNPCs(50, defendingGeneral); + for (CreatureObject enemy : enemies) { + AIActor actor = (AIActor)enemy.getAttachment("AI"); + actor.addDefender(defendingGeneral); + } + } + + public float getDistanceToDefensiveGeneral(CreatureObject checker){ + float dist = checker.getWorldPosition().getDistance2D(defendingGeneral.getWorldPosition()); + return dist; + } + + public CreatureObject getDefensiveGeneral(){ + return defendingGeneral; + } + + public void setInvasionLocationCenter(){ + switch (invasionLocation){ + case InvasionLocation.Dearic : invasionLocationCenter = new Point3D(452,6,-3002); + break; + case InvasionLocation.Keren : invasionLocationCenter = new Point3D(); + break; + case InvasionLocation.Bestine : invasionLocationCenter = new Point3D(); + break; + } + } + + public String getFactionName(int faction){ + if (faction==Factions.Rebel) + return "rebel"; + if (faction==Factions.Imperial) + return "imperial"; + return "neutral"; + } + @Override public void shutdown() { @@ -292,20 +943,6 @@ public class InvasionService implements INetworkDispatch { } - - // Test methods - public void buildPylon1(){ - - } - - public int getInvasionPhase() { - return invasionPhase; - } - - public void setInvasionPhase(int invasionPhase) { - this.invasionPhase = invasionPhase; - } - public class InvasionLocation { public static final int Keren = 0; diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index ef4d8fce..62c5395a 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -131,6 +131,7 @@ import services.bazaar.AuctionItem; import services.chat.ChatRoom; import services.equipment.EquipmentService; import services.gcw.GCWPylon; +import services.gcw.GCWSpawner; import services.sui.SUIWindow; import services.sui.SUIWindow.SUICallback; import services.sui.SUIWindow.Trigger; @@ -286,6 +287,12 @@ public class ObjectService implements INetworkDispatch { Point3D newpoint = new Point3D(position.x,positionY,position.z); object = new GCWPylon(objectID, planet, position, orientation, Template); + } else if(Template.startsWith("object/tangible/loot/creature_loot/collections/shared_dejarik_table_base")) { + + float positionY = core.terrainService.getHeight(planet.getID(), position.x, position.z)+1f; + Point3D newpoint = new Point3D(position.x,positionY,position.z); + object = new GCWSpawner(objectID, planet, position, orientation, Template); + } else if(Template.startsWith("object/tangible/destructible/")) { // float positionY = core.terrainService.getHeight(planet.getID(), position.x, position.z)-1f; diff --git a/src/services/spawn/SpawnService.java b/src/services/spawn/SpawnService.java index 38b9d45c..a036bc9a 100644 --- a/src/services/spawn/SpawnService.java +++ b/src/services/spawn/SpawnService.java @@ -113,6 +113,9 @@ public class SpawnService { creature.setFaction(mobileTemplate.getFaction()); creature.setFactionStatus(mobileTemplate.getFactionStatus()); creature.setPvpBitmask(mobileTemplate.getPvpBitmask()); + + creature.updatePvpStatus(); + if (mobileTemplate.getCustomName()==null){ creature.setStfFilename("mob/creature_names"); // TODO: set other STFs for NPCs other than creatures -> DONE if (mobileTemplate.getStfFilename()!=null) diff --git a/src/tools/DevLog.java b/src/tools/DevLog.java index 5a5c1a64..bc08181b 100644 --- a/src/tools/DevLog.java +++ b/src/tools/DevLog.java @@ -35,6 +35,10 @@ import java.util.Date; import java.util.HashMap; import java.util.Map; +import services.ai.AIActor; +import services.ai.TurretAIActor; +import main.NGECore; + /** * @author Charon */ @@ -110,25 +114,109 @@ public class DevLog { if (debugEnable.get(developer)==1){ logMessage = "Devlog->"+developer+"->"+testarea+"-> "+message; DevLogQueuer logger = DevLogQueuer.getInstance(); - logger.log(logMessage); + if (logger!=null) + logger.log(logMessage); } } if (isFileLoggingEnabled(debugRequester)){ if (loggingSessionID>0){ DevLogQueuer logger = DevLogQueuer.getInstance(); - logger.log(logMessage,newFile); + if (logger!=null) + logger.log(logMessage,newFile); } else { createLog(); - DevLogQueuer logger = DevLogQueuer.getInstance(); - logger.log(logMessage,newFile); - loggingSessionID++; + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null){ + logger.log(logMessage,newFile); + loggingSessionID++; + } } } } + public static void debugoutai(AIActor actor, String debugRequester, String testarea, String message){ + if (NGECore.getInstance().aiService.getCheckAI()!=null && actor!=null){ + if (!(NGECore.getInstance().aiService.getCheckAI().getAttachment("AI") instanceof AIActor)) + return; + AIActor checkActor = (AIActor) NGECore.getInstance().aiService.getCheckAI().getAttachment("AI"); + if (checkActor==actor){ + String developer = System.getProperty("user.name"); + String logMessage = ""; + if (!debugRequester.equals(developer)) + return; + if (debugEnable.keySet().contains(developer)){ + + if (debugEnable.get(developer)==1){ + logMessage = "Devlog->"+developer+"->"+testarea+"-> "+message; + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null) + logger.log(logMessage); + } + } + + if (isFileLoggingEnabled(debugRequester)){ + if (loggingSessionID>0){ + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null) + logger.log(logMessage,newFile); + + } else { + createLog(); + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null){ + logger.log(logMessage,newFile); + loggingSessionID++; + } + } + } + } + } + } + + public static void debugoutai(TurretAIActor actor, String debugRequester, String testarea, String message){ + if (NGECore.getInstance().aiService.getCheckAI()!=null && actor!=null){ + if (!(NGECore.getInstance().aiService.getCheckAI().getAttachment("AI") instanceof TurretAIActor)) + return; + + TurretAIActor checkActor = (TurretAIActor) NGECore.getInstance().aiService.getCheckAI().getAttachment("AI"); + + if (checkActor==actor){ + String developer = System.getProperty("user.name"); + String logMessage = ""; + if (!debugRequester.equals(developer)) + return; + if (debugEnable.keySet().contains(developer)){ + + if (debugEnable.get(developer)==1){ + logMessage = "Devlog->"+developer+"->"+testarea+"-> "+message; + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null) + logger.log(logMessage); + } + } + + if (isFileLoggingEnabled(debugRequester)){ + if (loggingSessionID>0){ + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null) + logger.log(logMessage,newFile); + + } else { + createLog(); + DevLogQueuer logger = DevLogQueuer.getInstance(); + if (logger!=null){ + logger.log(logMessage,newFile); + loggingSessionID++; + } + } + } + } + } + } + public static void createLog(){ try { @@ -144,7 +232,7 @@ public class DevLog { newFile = Files.createFile(newFile); createHeader(newFile); } catch (IOException ex) { - System.out.println("Error creating file"); + System.out.println("Error creating file " + ex.getMessage()); } }