Added TurretAI

- Added vehicles
- Tweaked AI to consider opposite faction-aligned Installationobjects
enemies
- Added turret shooting at NPCs
- Debugged actors
This commit is contained in:
CharonInferar
2014-07-16 16:52:36 +02:00
parent cc28f80394
commit db036574b7
30 changed files with 3140 additions and 268 deletions
@@ -0,0 +1,42 @@
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('fbase_imperial_colonel_extreme')
mobileTemplate.setLevel(90)
mobileTemplate.setDifficulty(Difficulty.ELITE)
mobileTemplate.setMinSpawnDistance(4)
mobileTemplate.setMaxSpawnDistance(8)
mobileTemplate.setDeathblow(False)
mobileTemplate.setSocialGroup("imperial")
mobileTemplate.setAssistRange(0)
mobileTemplate.setStalker(False)
mobileTemplate.setFaction("imperial")
mobileTemplate.setFactionStatus(FactionStatus.Combatant)
mobileTemplate.setOptionsBitmask(Options.CONVERSABLE | Options.INVULNERABLE)
templates = Vector()
templates.add('object/mobile/shared_dressed_imperial_colonel_m.iff')
mobileTemplate.setTemplates(templates)
weaponTemplates = Vector()
weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e11.iff', WeaponType.CARBINE, 1.0, 15, 'energy')
weaponTemplates.add(weapontemplate)
mobileTemplate.setWeaponTemplateVector(weaponTemplates)
attacks = Vector()
mobileTemplate.setDefaultAttack('rangedShot')
mobileTemplate.setAttacks(attacks)
core.spawnService.addMobileTemplate('imp_defensive_quest_officer', mobileTemplate)
return
@@ -0,0 +1,42 @@
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('eow_gcw_city_at_st_2')
mobileTemplate.setLevel(90)
mobileTemplate.setDifficulty(Difficulty.ELITE)
mobileTemplate.setMinSpawnDistance(4)
mobileTemplate.setMaxSpawnDistance(8)
mobileTemplate.setDeathblow(True)
mobileTemplate.setScale(1)
mobileTemplate.setSocialGroup("imperial")
mobileTemplate.setAssistRange(0)
mobileTemplate.setStalker(False)
mobileTemplate.setFaction("imperial")
mobileTemplate.setFactionStatus(FactionStatus.Combatant)
templates = Vector()
templates.add('object/mobile/vehicle/shared_walker_at_st.iff')
mobileTemplate.setTemplates(templates)
weaponTemplates = Vector()
weapontemplate = WeaponTemplate('object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff', WeaponType.CARBINE, 1.0, 15, 'energy')
weaponTemplates.add(weapontemplate)
mobileTemplate.setWeaponTemplateVector(weaponTemplates)
attacks = Vector()
mobileTemplate.setDefaultAttack('rangedShot')
mobileTemplate.setAttacks(attacks)
core.spawnService.addMobileTemplate('imp_invasion_at_at', mobileTemplate)
return
@@ -0,0 +1,42 @@
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('eow_gcw_city_at_st_2')
mobileTemplate.setLevel(90)
mobileTemplate.setDifficulty(Difficulty.ELITE)
mobileTemplate.setMinSpawnDistance(4)
mobileTemplate.setMaxSpawnDistance(8)
mobileTemplate.setDeathblow(True)
mobileTemplate.setScale(1)
mobileTemplate.setSocialGroup("imperial")
mobileTemplate.setAssistRange(0)
mobileTemplate.setStalker(False)
mobileTemplate.setFaction("imperial")
mobileTemplate.setFactionStatus(FactionStatus.Combatant)
templates = Vector()
templates.add('object/mobile/vehicle/shared_walker_at_st.iff')
mobileTemplate.setTemplates(templates)
weaponTemplates = Vector()
weapontemplate = WeaponTemplate('object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff', WeaponType.CARBINE, 1.0, 15, 'energy')
weaponTemplates.add(weapontemplate)
mobileTemplate.setWeaponTemplateVector(weaponTemplates)
attacks = Vector()
mobileTemplate.setDefaultAttack('rangedShot')
mobileTemplate.setAttacks(attacks)
core.spawnService.addMobileTemplate('imp_invasion_at_st', mobileTemplate)
return
@@ -0,0 +1,43 @@
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('gcw_city_imperial_general')
mobileTemplate.setLevel(110)
mobileTemplate.setHealth(1000000)
mobileTemplate.setDifficulty(Difficulty.BOSS)
mobileTemplate.setMinSpawnDistance(4)
mobileTemplate.setMaxSpawnDistance(8)
mobileTemplate.setDeathblow(True)
mobileTemplate.setScale(1)
mobileTemplate.setSocialGroup("imperial")
mobileTemplate.setAssistRange(0)
mobileTemplate.setStalker(False)
mobileTemplate.setFaction("imperial")
mobileTemplate.setFactionStatus(FactionStatus.Combatant)
templates = Vector()
templates.add('object/mobile/shared_dressed_imperial_general_m.iff')
mobileTemplate.setTemplates(templates)
weaponTemplates = Vector()
weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e11.iff', WeaponType.CARBINE, 1.0, 15, 'energy')
weaponTemplates.add(weapontemplate)
mobileTemplate.setWeaponTemplateVector(weaponTemplates)
attacks = Vector()
mobileTemplate.setDefaultAttack('rangedShot')
mobileTemplate.setAttacks(attacks)
core.spawnService.addMobileTemplate('imp_invasion_general', mobileTemplate)
return
@@ -0,0 +1,46 @@
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('crackdown_rebel_colonel')
mobileTemplate.setLevel(90)
mobileTemplate.setDifficulty(Difficulty.ELITE)
mobileTemplate.setMinSpawnDistance(4)
mobileTemplate.setMaxSpawnDistance(8)
mobileTemplate.setSocialGroup("rebel")
mobileTemplate.setAssistRange(0)
mobileTemplate.setStalker(False)
mobileTemplate.setFaction("rebel")
mobileTemplate.setFactionStatus(FactionStatus.Combatant)
mobileTemplate.setOptionsBitmask(Options.CONVERSABLE | Options.INVULNERABLE)
mobileTemplate.setAIEnabled(False)
templates = Vector()
templates.add('object/mobile/shared_dressed_rebel_lieutenant_colonel_human_male_01.iff')
templates.add('object/mobile/shared_dressed_rebel_lieutenant_colonel_human_male_02.iff')
templates.add('object/mobile/shared_dressed_rebel_lieutenant_colonel_moncal_female_01.iff')
templates.add('object/mobile/shared_dressed_rebel_lieutenant_colonel_rodian_female_01.iff')
templates.add('object/mobile/shared_dressed_rebel_lieutenant_colonel_rodian_male_01.iff')
templates.add('object/mobile/shared_dressed_rebel_lieutenant_colonel_zabrak_male_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('rebel_defensive_quest_officer', mobileTemplate)
return
@@ -0,0 +1,42 @@
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('eow_gcw_city_at_xt_2')
mobileTemplate.setLevel(90)
mobileTemplate.setDifficulty(Difficulty.ELITE)
mobileTemplate.setMinSpawnDistance(4)
mobileTemplate.setMaxSpawnDistance(8)
mobileTemplate.setDeathblow(True)
mobileTemplate.setScale(1)
mobileTemplate.setSocialGroup("rebel")
mobileTemplate.setAssistRange(0)
mobileTemplate.setStalker(False)
mobileTemplate.setFaction("rebel")
mobileTemplate.setFactionStatus(FactionStatus.Combatant)
templates = Vector()
templates.add('object/mobile/vehicle/shared_walker_at_xt.iff')
mobileTemplate.setTemplates(templates)
weaponTemplates = Vector()
weapontemplate = WeaponTemplate('object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff', WeaponType.CARBINE, 1.0, 15, 'energy')
weaponTemplates.add(weapontemplate)
mobileTemplate.setWeaponTemplateVector(weaponTemplates)
attacks = Vector()
mobileTemplate.setDefaultAttack('rangedShot')
mobileTemplate.setAttacks(attacks)
core.spawnService.addMobileTemplate('rebel_invasion_at_xt', mobileTemplate)
return
@@ -0,0 +1,46 @@
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('gcw_city_rebel_general')
mobileTemplate.setLevel(110)
mobileTemplate.setHealth(1000000)
mobileTemplate.setDifficulty(Difficulty.BOSS)
mobileTemplate.setMinSpawnDistance(4)
mobileTemplate.setMaxSpawnDistance(8)
mobileTemplate.setDeathblow(True)
mobileTemplate.setSocialGroup("rebel")
mobileTemplate.setAssistRange(0)
mobileTemplate.setStalker(False)
mobileTemplate.setFaction("rebel")
mobileTemplate.setFactionStatus(FactionStatus.Combatant)
templates = Vector()
templates.add('object/mobile/shared_dressed_rebel_general_human_female_01.iff')
templates.add('object/mobile/shared_dressed_rebel_general_human_female_02.iff')
templates.add('object/mobile/shared_dressed_rebel_general_moncal_male_01.iff')
templates.add('object/mobile/shared_dressed_rebel_general_old_twilek_male_01.iff')
templates.add('object/mobile/shared_dressed_rebel_general_rieekan_01.iff')
templates.add('object/mobile/shared_dressed_rebel_general_rodian_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('rebel_invasion_general', mobileTemplate)
return
@@ -0,0 +1,42 @@
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('eow_gcw_city_at_st_2')
mobileTemplate.setLevel(90)
mobileTemplate.setDifficulty(Difficulty.ELITE)
mobileTemplate.setMinSpawnDistance(4)
mobileTemplate.setMaxSpawnDistance(8)
mobileTemplate.setDeathblow(True)
mobileTemplate.setScale(1)
mobileTemplate.setSocialGroup("rebel")
mobileTemplate.setAssistRange(0)
mobileTemplate.setStalker(False)
mobileTemplate.setFaction("rebel")
mobileTemplate.setFactionStatus(FactionStatus.Combatant)
templates = Vector()
templates.add('object/mobile/shared_hailfire_droid.iff')
mobileTemplate.setTemplates(templates)
weaponTemplates = Vector()
weapontemplate = WeaponTemplate('object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff', WeaponType.CARBINE, 1.0, 15, 'energy')
weaponTemplates.add(weapontemplate)
mobileTemplate.setWeaponTemplateVector(weaponTemplates)
attacks = Vector()
mobileTemplate.setDefaultAttack('rangedShot')
mobileTemplate.setAttacks(attacks)
core.spawnService.addMobileTemplate('rebel_invasion_hailfire_droid', mobileTemplate)
return
@@ -329,9 +329,11 @@ public class TangibleObject extends SWGObject implements Serializable {
}
public void addDefender(TangibleObject defender) {
if (((CreatureObject)this).getOwnerId()>0){
if (((CreatureObject)this).getOwnerId()==defender.getObjectID()){
return; // fix for now until determined where the tamer is added from
if (this instanceof CreatureObject){
if (((CreatureObject)this).getOwnerId()>0){
if (((CreatureObject)this).getOwnerId()==defender.getObjectID()){
return; // fix for now until determined where the tamer is added from
}
}
}
defendersList.add(defender);
+16 -1
View File
@@ -71,6 +71,14 @@ public class DevService implements INetworkDispatch {
public DevService(NGECore core) {
this.core = core;
loadFrogBuilding();
// Server developers quick frog access
if (System.getProperty("user.name").equals("Charon")){
TangibleObject frog = (TangibleObject) core.objectService.createObject("object/tangible/terminal/shared_terminal_character_builder.iff", core.terrainService.getPlanetByName("tatooine"));
frog.setPosition(new Point3D((float)3524, (float)4, (float)-4802));
frog.setOrientation(new Quaternion((float) 0.9965, 0, (float)-0.09, 0));
core.simulationService.add(frog, frog.getPosition().x, frog.getPosition().z, true);
}
}
public void sendCharacterBuilderSUI(CreatureObject creature, int childMenu)
@@ -85,6 +93,8 @@ public class DevService implements INetworkDispatch {
suiOptions.put((long) 3, "Locations");
if (System.getProperty("user.name").equals("Charon"))
suiOptions.put((long) 4, "Treasure chest test");
if (System.getProperty("user.name").equals("Charon"))
suiOptions.put((long) 6, "Dearic attack camp");
if (creature.getClient().isGM())
suiOptions.put((long) 200, "Get new CBT");
break;
@@ -219,7 +229,12 @@ public class DevService implements INetworkDispatch {
//treasureContainer.add(droppedItem);
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();
return;
// Character
case 10: // Set combat level to 90
if (player.getAttachment("hasLeveled") == null) {
+52 -1
View File
@@ -80,6 +80,7 @@ import resources.objects.cell.CellObject;
import resources.objects.creature.CreatureObject;
import resources.objects.group.GroupObject;
import resources.objects.harvester.HarvesterObject;
import resources.objects.installation.InstallationObject;
import resources.objects.player.PlayerObject;
import resources.objects.tangible.TangibleObject;
import resources.common.*;
@@ -281,12 +282,62 @@ public class SimulationService implements INetworkDispatch {
public Vector<CreatureObject> getAllNearNPCs(int distance, SWGObject value ){
Vector<CreatureObject> foundCreatures = new Vector<CreatureObject>();
core.simulationService.get(value.getPlanet(), value.getWorldPosition().x, value.getWorldPosition().z, distance).stream().forEach((objecta) -> {
if (objecta instanceof CreatureObject)
if (objecta instanceof CreatureObject && objecta!=value)
foundCreatures.add((CreatureObject)objecta);
}
);
return foundCreatures;
}
public Vector<CreatureObject> getAllNearNonSameFactionNPCs(int distance, SWGObject value ){
Vector<CreatureObject> foundCreatures = new Vector<CreatureObject>();
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);
}
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<TangibleObject> getAllNearTANOs(int distance, SWGObject value ){
Vector<TangibleObject> foundTANOs = new Vector<TangibleObject>();
core.simulationService.get(value.getPlanet(), value.getWorldPosition().x, value.getWorldPosition().z, distance).stream().forEach((objecta) -> {
if (objecta instanceof TangibleObject && objecta!=value)
foundTANOs.add((TangibleObject)objecta);
}
);
return foundTANOs;
}
public Vector<TangibleObject> getAllNearNonSameFactionTANOs(int distance, SWGObject value ){
Vector<TangibleObject> foundTANOs = new Vector<TangibleObject>();
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()))
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;
}
public boolean move(SWGObject object, int oldX, int oldZ, int newX, int newZ) {
if(quadTrees.get(object.getPlanet().getName()).remove(oldX, oldZ, object)) {
+56 -33
View File
@@ -59,7 +59,7 @@ public class AIActor {
private CreatureObject creature;
private Point3D spawnPosition;
private volatile AIState currentState;
private CreatureObject followObject;
private TangibleObject followObject;
private Vector<Point3D> movementPoints = new Vector<Point3D>();
private MobileTemplate mobileTemplate;
private ScheduledExecutorService scheduler;
@@ -157,15 +157,16 @@ public class AIActor {
factionCheckTask = scheduler.scheduleAtFixedRate(() -> {
try {
if(creature == null || creature.getFactionStatus()!=FactionStatus.Combatant || creature.getObservers().isEmpty() || creature.isInCombat())
// this is difficult, should NPC not fight when no player is near? || creature.getObservers().isEmpty()
if(creature == null || creature.getFactionStatus()!=FactionStatus.Combatant || creature.isInCombat())
return;
creature.getObservers().stream().map(Client::getParent).filter(obj -> obj.inRange(creature.getWorldPosition(), 15)).forEach((obj) -> {
if(new Random().nextFloat() <= 0.5 || creature.isInCombat()) {
DevLog.debugout("Charon", "CHECK faction creature ", "added " + creature.getFaction());
DevLog.debugout("Charon", "CHECK faction obj", "added " + ((TangibleObject)obj).getFaction());
DevLog.debugout("Charon", "CHECK factionCheckTask", "added " + obj.getCustomName());
DevLog.debugout("Charon", "CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj));
// DevLog.debugout("Charon", "CHECK faction creature ", "added " + creature.getFaction());
// DevLog.debugout("Charon", "CHECK faction obj", "added " + ((TangibleObject)obj).getFaction());
// DevLog.debugout("Charon", "CHECK factionCheckTask", "added " + obj.getCustomName());
// DevLog.debugout("Charon", "CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj));
if (obj instanceof CreatureObject && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)){
CreatureObject addedObject = (CreatureObject) obj;
if (addedObject.getCalledPet()!=null){
@@ -174,7 +175,32 @@ public class AIActor {
addDefender(calledPet);
}
}
if (addedObject.getPosture() != 13 && addedObject.getPosture() != 14){
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());
}
}
}
});
NGECore.getInstance().simulationService.getAllNearNonSameFactionNPCs(15, creature).forEach((obj) -> {
if(new Random().nextFloat() <= 0.5 || creature.isInCombat()) {
// DevLog.debugout("Charon", "CHECK faction creature ", "added " + creature.getFaction());
// DevLog.debugout("Charon", "CHECK faction obj", "added " + ((TangibleObject)obj).getFaction());
// DevLog.debugout("Charon", "CHECK factionCheckTask", "added " + obj.getCustomName());
// DevLog.debugout("Charon", "CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj));
if (obj instanceof CreatureObject && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)){
CreatureObject addedObject = (CreatureObject) obj;
if (addedObject.getCalledPet()!=null){
CreatureObject calledPet = addedObject.getCalledPet();
if (calledPet.getPosture() != 13 && calledPet.getPosture() != 14 & ! calledPet.getOption(Options.INVULNERABLE)){
addDefender(calledPet);
}
}
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());
@@ -184,26 +210,18 @@ public class AIActor {
}
});
NGECore.getInstance().simulationService.getAllNearNPCs(15, creature).forEach((obj) -> {
NGECore.getInstance().simulationService.getAllNearNonSameFactionTANOs(15, creature).forEach((obj) -> {
if(new Random().nextFloat() <= 0.5 || creature.isInCombat()) {
DevLog.debugout("Charon", "CHECK faction creature ", "added " + creature.getFaction());
DevLog.debugout("Charon", "CHECK faction obj", "added " + ((TangibleObject)obj).getFaction());
DevLog.debugout("Charon", "CHECK factionCheckTask", "added " + obj.getCustomName());
DevLog.debugout("Charon", "CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj));
if (obj instanceof CreatureObject && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)){
CreatureObject addedObject = (CreatureObject) obj;
if (addedObject.getCalledPet()!=null){
CreatureObject calledPet = addedObject.getCalledPet();
if (calledPet.getPosture() != 13 && calledPet.getPosture() != 14){
addDefender(calledPet);
}
}
if (addedObject.getPosture() != 13 && addedObject.getPosture() != 14){
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.debugout("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());
}
}
});
@@ -231,15 +249,19 @@ public class AIActor {
this.spawnPosition = spawnPosition;
}
public void addDefender(CreatureObject defender) {
// public void addDefender(CreatureObject defender) {
// addDefender(defender, false);
// }
public void addDefender(TangibleObject defender) {
addDefender(defender, false);
}
public void addDefender(CreatureObject defender, boolean isAssisting) {
public void addDefender(TangibleObject defender, boolean isAssisting) {
creature.addDefender(defender);
if(followObject == null)
setFollowObject(defender);
System.out.println("getFollowObject "+ getFollowObject().getTemplate());
setCurrentState(new AttackState());
if(!isAssisting) {
NGECore.getInstance().simulationService.get(creature.getPlanet(), creature.getWorldPosition().x, creature.getWorldPosition().z, 38).stream().filter((obj) ->
@@ -251,7 +273,7 @@ public class AIActor {
}
}
public void removeDefender(CreatureObject defender) {
public void removeDefender(TangibleObject defender) {
creature.removeDefender(defender);
damageMap.remove(defender);
defender.removeDefender(creature);
@@ -292,11 +314,11 @@ public class AIActor {
}
}
public CreatureObject getFollowObject() {
public TangibleObject getFollowObject() {
return followObject;
}
public void setFollowObject(CreatureObject followObject) {
public void setFollowObject(TangibleObject followObject) {
this.followObject = followObject;
}
@@ -346,7 +368,7 @@ public class AIActor {
@Handler
public void handleDamage(DamageTaken event) {
CreatureObject attacker = event.attacker;
CreatureObject attacker = (CreatureObject)event.attacker;
if(damageMap.containsKey(attacker))
damageMap.put(attacker, damageMap.get(attacker) + event.damage);
else
@@ -409,7 +431,8 @@ public class AIActor {
}
switch(result) {
case StateResult.DEAD:
setCurrentState(new DeathState());
break;
+2
View File
@@ -54,6 +54,8 @@ public class AIService {
// TODO: implement cell pathfinding, returning straight line for now
Vector<Point3D> path = new Vector<Point3D>();
if (pointA==null || pointB==null)
return path;
path.add(pointA);
float x = pointB.x - 1 + new Random().nextFloat();
float z = pointB.z - 1 + new Random().nextFloat();
+2 -2
View File
@@ -84,8 +84,8 @@ public class LairActor {
spawnNewCreatures();
for(AIActor ai : creatures) {
ai.addDefender(event.attacker);
event.attacker.addDefender(ai.getCreature());
ai.addDefender((CreatureObject)event.attacker);
((CreatureObject)event.attacker).addDefender(ai.getCreature());
}
+594
View File
@@ -0,0 +1,594 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* 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 <http://www.gnu.org/licenses/>.
*
* 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.ai;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import main.NGECore;
import net.engio.mbassy.listener.Handler;
import engine.clients.Client;
import engine.resources.objects.SWGObject;
import engine.resources.scene.Point3D;
import engine.resources.scene.Quaternion;
import resources.datatables.Options;
import resources.objects.cell.CellObject;
import resources.objects.creature.CreatureObject;
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.TurretAttackState;
import services.ai.states.TurretIdleState;
import services.combat.CombatEvents.DamageTaken;
import services.spawn.MobileTemplate;
import tools.DevLog;
import resources.datatables.FactionStatus;
import java.util.Random;
public class TurretAIActor {
private TangibleObject creature;
private Point3D spawnPosition;
private volatile TurretAIState currentState;
private TangibleObject followObject;
private Vector<Point3D> movementPoints = new Vector<Point3D>();
private MobileTemplate mobileTemplate;
private ScheduledExecutorService scheduler;
private Map<CreatureObject, Integer> damageMap = new ConcurrentHashMap<CreatureObject, Integer>();
private volatile boolean hasReachedPosition;
private long lastAttackTimestamp;
private ScheduledFuture<?> regenTask;
private ScheduledFuture<?> aggroCheckTask;
private ScheduledFuture<?> factionCheckTask;
private boolean isStalking = false;
private byte milkState = 0;
private boolean hasBeenHarvested = false;
private Vector<Point3D> patrolPoints = new Vector<Point3D>();
private int patrolPointIndex = 0;
private String loiterDestType = "LOITER";
private Point3D loiterDestination;
private Point3D originPosition;
private float minLoiterDist;
private float maxLoiterDist;
private String waitState = "NO";
private long waitStartTime = 0L;
private TurretAIState intendedPrimaryTurretAIState;
private Point3D lastPositionBeforeStateChange;
private boolean patrolLoop = true; // default
private ScheduledFuture recoveryFuture;
public TurretAIActor(TangibleObject creature, Point3D spawnPosition, ScheduledExecutorService scheduler) {
this.creature = creature;
this.spawnPosition = spawnPosition;
setLastPositionBeforeStateChange(spawnPosition); // just to make sure it's initialized
this.scheduler = scheduler;
creature.getEventBus().subscribe(this);
this.currentState = new TurretIdleState();
setIntendedPrimaryTurretAIState(this.currentState); // to switch back to after aggro
if(creature.getOption(Options.AGGRESSIVE)) {
aggroCheckTask = scheduler.scheduleAtFixedRate(() -> {
try {
if(creature == null || creature.getObservers().isEmpty() || creature.isInCombat() || isStalking)
return;
if (creature.getAttachment("tamed")!=null){
DevLog.debugout("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"));
creature.getObservers().stream().map(Client::getParent).filter(obj -> obj.inRange(creature.getWorldPosition(), 60)).forEach((obj) -> {
if(new Random().nextFloat() <= 0.5 || creature.isInCombat() || isStalking) {
/*if(mobileTemplate.isStalker()) {
setFollowObject((CreatureObject) obj);
setCurrentState(new StalkState());
} else */
if (creature.getAttachment("IsBeingTamed")!=null)
return;
if (obj instanceof CreatureObject){
CreatureObject addedObject = (CreatureObject) obj;
if (addedObject.getCalledPet()!=null){
CreatureObject calledPet = addedObject.getCalledPet();
if (calledPet.getPosture() != 13 && calledPet.getPosture() != 14){
addDefender(calledPet);
}
}
if (addedObject.getPosture() != 13 && addedObject.getPosture() != 14){
addDefender(addedObject);
}
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}, 0, 5000, TimeUnit.MILLISECONDS);
}
if(creature.getFaction().length()>0 || !creature.getOption(Options.AGGRESSIVE)) {
factionCheckTask = scheduler.scheduleAtFixedRate(() -> {
System.out.println("Turret faction thread");
try {
if(creature == null || creature.getFactionStatus()!=FactionStatus.Combatant || creature.getObservers().isEmpty() || creature.isInCombat())
return;
creature.getObservers().stream().map(Client::getParent).filter(obj -> obj.inRange(creature.getWorldPosition(), 60)).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());
// DevLog.debugout("Charon", "TURRET CHECK factionCheckTask", "added " + obj.getCustomName());
// DevLog.debugout("Charon", "TURRET CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj));
if (obj instanceof CreatureObject && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)){
CreatureObject addedObject = (CreatureObject) obj;
if (addedObject.getCalledPet()!=null){
CreatureObject calledPet = addedObject.getCalledPet();
if (calledPet.getPosture() != 13 && calledPet.getPosture() != 14){
addDefender(calledPet);
}
}
if (addedObject.getPosture() != 13 && addedObject.getPosture() != 14 && ! addedObject.getOption(Options.INVULNERABLE)){
addDefender(addedObject);
// DevLog.debugout("Charon", "TURRET faction creature ", "added " + creature.getFaction());
// DevLog.debugout("Charon", "TURRET faction obj", "added " + ((TangibleObject)obj).getFaction());
// DevLog.debugout("Charon", "TURRET factionCheckTask", "added " + obj.getCustomName());
}
}
}
});
NGECore.getInstance().simulationService.getAllNearNPCs(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());
// DevLog.debugout("Charon", "TURRET CHECK factionCheckTask", "added " + obj.getCustomName());
// DevLog.debugout("Charon", "TURRET CHECK isFactionEnemy", "res " + NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj));
if (obj instanceof CreatureObject && NGECore.getInstance().factionService.isFactionEnemy((TangibleObject)creature, (TangibleObject)obj)){
CreatureObject addedObject = (CreatureObject) obj;
if (addedObject.getCalledPet()!=null){
CreatureObject calledPet = addedObject.getCalledPet();
if (calledPet.getPosture() != 13 && calledPet.getPosture() != 14 & ! calledPet.getOption(Options.INVULNERABLE)){
addDefender(calledPet);
}
}
if (addedObject.getPosture() != 13 && addedObject.getPosture() != 14 & ! addedObject.getOption(Options.INVULNERABLE)){
addDefender(addedObject);
// DevLog.debugout("Charon", "TURRET faction creature ", "added " + creature.getFaction());
// DevLog.debugout("Charon", "TURRET faction obj", "added " + ((TangibleObject)obj).getFaction());
// DevLog.debugout("Charon", "TURRET factionCheckTask", "added " + obj.getCustomName());
}
}
}
});
NGECore.getInstance().simulationService.getAllNearTANOs(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));
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());
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}, 0, 5000, TimeUnit.MILLISECONDS);
}
}
public TangibleObject getCreature() {
return creature;
}
public void setCreature(CreatureObject creature) {
this.creature = creature;
}
public Point3D getSpawnPosition() {
return spawnPosition;
}
public void setSpawnPosition(Point3D spawnPosition) {
this.spawnPosition = spawnPosition;
}
// public void addDefender(CreatureObject defender) {
// addDefender(defender, false);
// }
public void addDefender(TangibleObject defender) {
addDefender(defender, false);
}
public void addDefender(TangibleObject defender, boolean isAssisting) {
creature.addDefender(defender);
if(followObject == null)
setFollowObject(defender);
setCurrentState(new TurretAttackState());
// if(!isAssisting) {
// NGECore.getInstance().simulationService.get(creature.getPlanet(), creature.getWorldPosition().x, creature.getWorldPosition().z, 38).stream().filter((obj) ->
// obj instanceof CreatureObject &&
// obj.getAttachment("AI") != null &&
// ((TurretAIActor) obj.getAttachment("AI")).getMobileTemplate().getSocialGroup().equals(getMobileTemplate().getSocialGroup()) &&
// obj.inRange(creature.getWorldPosition(), ((TurretAIActor) obj.getAttachment("AI")).getMobileTemplate().getAssistRange())
// ).forEach((obj) -> ((TurretAIActor) obj.getAttachment("AI")).addDefender(defender, true));
// }
}
public void removeDefender(TangibleObject defender) {
creature.removeDefender(defender);
damageMap.remove(defender);
defender.removeDefender(creature);
if(followObject == defender) {
setFollowObject(getHighestDamageDealer());
if(creature.getDefendersList().size() == 0)
setCurrentState(new TurretIdleState());
}
}
public CreatureObject getHighestDamageDealer() {
CreatureObject highestDamageDealer = null;
highestDamageDealer = damageMap.keySet().stream().max((c1, c2) -> damageMap.get(c1) - damageMap.get(c2)).orElse(null);
// return first defender if no damage has been dealt
if(highestDamageDealer == null) {
for(TangibleObject tangible : creature.getDefendersList().toArray(new TangibleObject[]{})) {
if(tangible instanceof CreatureObject)
return (CreatureObject) tangible;
}
}
return highestDamageDealer;
}
public TurretAIState getCurrentState() {
return currentState;
}
public void setCurrentState(TurretAIState currentState) {
try {
if(currentState.getClass() == this.currentState.getClass())
return;
if(this.currentState != null)
doStateAction(this.currentState.onExit(this));
this.currentState = currentState;
doStateAction(currentState.onEnter(this));
} catch (Exception e) {
e.printStackTrace();
}
}
public TangibleObject getFollowObject() {
return followObject;
}
public void setFollowObject(TangibleObject followObject) {
this.followObject = followObject;
}
public Vector<Point3D> getMovementPoints() {
return movementPoints;
}
public void setMovementPoints(Vector<Point3D> movementPoints) {
this.movementPoints = movementPoints;
}
public MobileTemplate getMobileTemplate() {
return mobileTemplate;
}
public void setMobileTemplate(MobileTemplate mobileTemplate) {
this.mobileTemplate = mobileTemplate;
}
public void scheduleRecovery() {
recoveryFuture = scheduler.schedule(() -> {
try {
doStateAction(currentState.recover(TurretAIActor.this));
} catch (Exception e) {
e.printStackTrace();
}
}, 2000, TimeUnit.MILLISECONDS);
}
public void setNextPosition(Point3D position) {
movementPoints.add(0, position);
}
@Handler
public void handleDamage(DamageTaken event) {
CreatureObject attacker = (CreatureObject)event.attacker;
if(damageMap.containsKey(attacker))
damageMap.put(attacker, damageMap.get(attacker) + event.damage);
else
damageMap.put(attacker, event.damage);
}
public Map<CreatureObject, Integer> getDamageMap() {
return damageMap;
}
public boolean hasReachedPosition() {
return hasReachedPosition;
}
public void setHasReachedPosition(boolean hasReachedPosition) {
this.hasReachedPosition = hasReachedPosition;
}
public void faceObject(SWGObject object) {
// Null checks due to a null error at: float direction =
if (object == null) DevLog.debugout("Charon", "AI Actor", "faceObject object is NULL");
if (creature == null) DevLog.debugout("Charon", "AI Actor", "faceObject creature is NULL");
if (object.getWorldPosition() == null) DevLog.debugout("Charon", "AI Actor", "faceObject object's position is NULL");
if (creature.getWorldPosition() == null) DevLog.debugout("Charon", "AI Actor", "faceObject creature's position is NULL");
float direction = (float) Math.atan2(object.getWorldPosition().x - creature.getWorldPosition().x, object.getWorldPosition().z - creature.getWorldPosition().z);
if(direction < 0)
direction = (float) (2 * Math.PI + direction);
if(Math.abs(direction - creature.getRadians()) < 0.05)
return;
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;
}
if(creature.getContainer() instanceof CellObject)
NGECore.getInstance().simulationService.moveObject(creature, creature.getPosition(), quaternion, creature.getMovementCounter(), 0, (CellObject) creature.getContainer());
else
NGECore.getInstance().simulationService.moveObject(creature, creature.getPosition(), quaternion, creature.getMovementCounter(), 0, null);
}
public long getLastAttackTimestamp() {
return lastAttackTimestamp;
}
public void setLastAttackTimestamp(long lastAttackTimestamp) {
this.lastAttackTimestamp = lastAttackTimestamp;
}
public long getTimeSinceLastAttack() {
return System.currentTimeMillis() - getLastAttackTimestamp();
}
public void doStateAction(byte result) {
if (creature==null){
destroyActor();
return;
}
switch(result) {
case StateResult.DEAD:
destroyActor();
break;
case StateResult.FINISHED:
case StateResult.UNFINISHED:
return;
case StateResult.IDLE:
setCurrentState(new TurretIdleState());
return;
//case StateResult.NONE:
// System.out.println("State action returned error result");
}
}
public void scheduleDespawn() {
// Sometimes these tasks are null?
try {
if (aggroCheckTask!=null)
aggroCheckTask.cancel(true);
if (factionCheckTask!=null)
factionCheckTask.cancel(true);
} catch(Exception e) {
}
try {
regenTask.cancel(true);
} catch(Exception e) {
}
}
public void destroyActor(){
creature.getEventBus().unsubscribe(this);
// Make sure to kill all AI helper threads
if (aggroCheckTask!=null)
aggroCheckTask.cancel(true);
if (factionCheckTask!=null)
factionCheckTask.cancel(true);
if (regenTask!=null)
regenTask.cancel(true);
}
public void cancelAggro(){
try {
aggroCheckTask.cancel(true);
} catch(Exception e) {
}
}
public ScheduledFuture<?> getRegenTask() {
return regenTask;
}
public void setRegenTask(ScheduledFuture<?> regenTask) {
this.regenTask = regenTask;
}
public boolean isStalking() {
return isStalking;
}
public void setStalking(boolean isStalking) {
this.isStalking = isStalking;
}
public byte getMilkState() {
synchronized(creature.getMutex()) {
return milkState;
}
}
public void setMilkState(byte milkState) {
synchronized(creature.getMutex()) {
this.milkState = milkState;
}
}
public boolean hasBeenHarvested() {
synchronized(creature.getMutex()) {
return hasBeenHarvested;
}
}
public void setHasBeenHarvested(boolean hasBeenHarvested) {
synchronized(creature.getMutex()) {
this.hasBeenHarvested = hasBeenHarvested;
}
}
public void setPatrolPoints(Vector<Point3D> patrolPoints){
this.patrolPoints = patrolPoints;
//setMovementPoints(patrolPoints);
}
public int getPatrolPointIndex() {
return patrolPointIndex;
}
public void setPatrolPointIndex(int patrolPointIndex) {
this.patrolPointIndex = patrolPointIndex;
}
public Point3D getLoiterDestination() {
return loiterDestination;
}
public void setLoiterDestination(Point3D loiterDestination) {
this.loiterDestination = loiterDestination;
}
public Point3D getOriginPosition() {
return originPosition;
}
public void setOriginPosition(Point3D originPosition) {
this.originPosition = originPosition;
}
public String getLoiterDestType() {
return loiterDestType;
}
public void setLoiterDestType(String loiterDestType) {
this.loiterDestType = loiterDestType;
}
public float getMinLoiterDist() {
return minLoiterDist;
}
public void setMinLoiterDist(float minLoiterDist) {
this.minLoiterDist = minLoiterDist;
}
public float getMaxLoiterDist() {
return maxLoiterDist;
}
public void setMaxLoiterDist(float maxLoiterDist) {
this.maxLoiterDist = maxLoiterDist;
}
public String getWaitState() {
return waitState;
}
public void setWaitState(String waitState) {
this.waitState = waitState;
}
public long getWaitStartTime() {
return waitStartTime;
}
public void setWaitStartTime(long waitStartTime) {
this.waitStartTime = waitStartTime;
}
public Vector<Point3D> getPatrolPoints() {
return patrolPoints;
}
public TurretAIState getIntendedPrimaryTurretAIState() {
return intendedPrimaryTurretAIState;
}
public void setIntendedPrimaryTurretAIState(TurretAIState intendedPrimaryTurretAIState) {
this.intendedPrimaryTurretAIState = intendedPrimaryTurretAIState;
}
public Point3D getLastPositionBeforeStateChange() {
return lastPositionBeforeStateChange;
}
public void setLastPositionBeforeStateChange(
Point3D lastPositionBeforeStateChange) {
this.lastPositionBeforeStateChange = lastPositionBeforeStateChange;
}
public boolean isPatrolLoop() {
return patrolLoop;
}
public void setPatrolLoop(boolean patrolLoop) {
this.patrolLoop = patrolLoop;
}
}
+6 -4
View File
@@ -30,6 +30,7 @@ import engine.resources.scene.Quaternion;
import resources.common.SpawnPoint;
import resources.objects.cell.CellObject;
import resources.objects.creature.CreatureObject;
import resources.objects.tangible.TangibleObject;
import resources.objects.weapon.WeaponObject;
import services.ai.AIActor;
@@ -54,6 +55,7 @@ public abstract class AIState {
public static final byte PATROL = 5;
public static final byte LOITER = 6;
public static final byte FOLLOW = 7;
public static final byte ATTACK = 8;
}
@@ -421,7 +423,7 @@ public abstract class AIState {
actor.setFollowObject(null);
return;
}
CreatureObject target = actor.getFollowObject();
TangibleObject target = actor.getFollowObject();
float speed = (float) creature.getRunSpeed();
float maxDistance = 6;
if(creature.getWeaponId() != 0) {
@@ -467,7 +469,7 @@ public abstract class AIState {
actor.setFollowObject(null);
return;
}
CreatureObject target = actor.getFollowObject();
TangibleObject target = actor.getFollowObject();
float speed = (float) creature.getWalkSpeed();
float maxDistance = 6;
if(creature.getWeaponId() != 0) {
@@ -544,7 +546,7 @@ public abstract class AIState {
actor.setFollowObject(null);
return;
}
CreatureObject target = actor.getFollowObject();
TangibleObject target = actor.getFollowObject();
float speed = (float) creature.getWalkSpeed();
float maxDistance = 6;
if(creature.getWeaponId() != 0) {
@@ -666,7 +668,7 @@ public abstract class AIState {
actor.setFollowObject(null);
return;
}
CreatureObject target = actor.getFollowObject();
TangibleObject target = actor.getFollowObject();
float speed = (float) creature.getRunSpeed();
float maxDistance = 6;
if(creature.getWeaponId() != 0) {
+27 -20
View File
@@ -26,6 +26,7 @@ import java.util.Vector;
import main.NGECore;
import resources.objects.creature.CreatureObject;
import resources.objects.tangible.TangibleObject;
import resources.objects.weapon.WeaponObject;
import services.ai.AIActor;
import tools.DevLog;
@@ -105,6 +106,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());
float maxDistance = 0;
WeaponObject weapon = null;
if(creature.getWeaponId() != 0) {
@@ -133,7 +135,7 @@ public class AttackState extends AIState {
actor.setCurrentState(new RetreatState());
return StateResult.FINISHED;
}
CreatureObject target = actor.getFollowObject();
TangibleObject target = actor.getFollowObject();
if(target != actor.getHighestDamageDealer() && actor.getHighestDamageDealer() != null) {
actor.setFollowObject(actor.getHighestDamageDealer());
target = actor.getFollowObject();
@@ -143,27 +145,32 @@ public class AttackState extends AIState {
actor.scheduleRecovery();
return StateResult.UNFINISHED;
}
if(target.getPosture() == 13 || target.getPosture() == 14 || target.isInStealth()) {
actor.setFollowObject(actor.getHighestDamageDealer());
target = actor.getFollowObject();
if(target == null)
{
creature.setLookAtTarget(0);
creature.setIntendedTarget(0);
}
actor.setFollowObject(null);
actor.removeDefender(target);
if (target instanceof CreatureObject){
CreatureObject targetCreature = (CreatureObject) target;
if(targetCreature.getPosture() == 13 || targetCreature.getPosture() == 14 || targetCreature.isInStealth()) {
actor.setFollowObject(actor.getHighestDamageDealer());
target = (CreatureObject) actor.getFollowObject();
if(target == null)
{
creature.setLookAtTarget(0);
creature.setIntendedTarget(0);
}
actor.setFollowObject(null);
actor.removeDefender(target);
actor.setCurrentState(new RetreatState());
return StateResult.FINISHED;
}
if(target.getWorldPosition().getDistance(creature.getWorldPosition()) > 128 || target.getPosture() == 13 || target.getPosture() == 14) {
actor.removeDefender(target);
actor.scheduleRecovery();
return StateResult.UNFINISHED;
actor.setCurrentState(new RetreatState());
return StateResult.FINISHED;
}
if(targetCreature.getWorldPosition().getDistance(creature.getWorldPosition()) > 128 || targetCreature.getPosture() == 13 || targetCreature.getPosture() == 14) {
actor.removeDefender(target);
actor.scheduleRecovery();
return StateResult.UNFINISHED;
}
}
if(target.getWorldPosition().getDistance(creature.getWorldPosition()) > maxDistance) {
actor.scheduleRecovery();
return StateResult.UNFINISHED;
+8 -5
View File
@@ -36,12 +36,15 @@ public class DeathState extends AIState {
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<RadialOptions>());
actor.scheduleDespawn();
CreatureObject killer = (CreatureObject)actor.getCreature().getKiller();
if (killer==null)
killer = actor.getHighestDamageDealer();
actor.getCreature().setContainerPermissions(CreatureContainerPermissions.CREATURE_CONTAINER_PERMISSIONS);
NGECore.getInstance().lootService.DropLoot(killer,(TangibleObject)(actor.getCreature()));
if (actor.getCreature().getKiller() instanceof CreatureObject){
CreatureObject killer = (CreatureObject)actor.getCreature().getKiller();
if (killer==null)
killer = actor.getHighestDamageDealer();
actor.getCreature().setContainerPermissions(CreatureContainerPermissions.CREATURE_CONTAINER_PERMISSIONS);
if (killer.isPlayer()) // No point to do this for NPCs
NGECore.getInstance().lootService.DropLoot(killer,(TangibleObject)(actor.getCreature()));
}
actor.destroyActor(); // to prevent standing up right after death
return 0;
+427
View File
@@ -0,0 +1,427 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* 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 <http://www.gnu.org/licenses/>.
*
* 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.ai.states;
import java.util.NoSuchElementException;
import java.util.Vector;
import main.NGECore;
import engine.resources.scene.Point3D;
import engine.resources.scene.Quaternion;
import resources.common.SpawnPoint;
import resources.objects.cell.CellObject;
import resources.objects.creature.CreatureObject;
import resources.objects.tangible.TangibleObject;
import resources.objects.weapon.WeaponObject;
import services.ai.TurretAIActor;
public abstract class TurretAIState {
public abstract byte onEnter(TurretAIActor actor) throws Exception;
public abstract byte onExit(TurretAIActor actor) throws Exception;
public abstract byte move(TurretAIActor actor) throws Exception;
public abstract byte recover(TurretAIActor actor) throws Exception;
public enum StateResult {;
// default error state result
public static final byte NONE = 0;
// finished with state
public static final byte FINISHED = 1;
// unfinished with state, call recover()
public static final byte UNFINISHED = 2;
public static final byte DEAD = 3;
// for deaggro or idling
public static final byte IDLE = 4;
public static final byte PATROL = 5;
public static final byte LOITER = 6;
public static final byte FOLLOW = 7;
}
public boolean findNewPosition(TurretAIActor actor, float speed, float stopDistance, Point3D newPosition) {
speed *= 0.5; // 2 updates per second
TangibleObject creature = actor.getCreature();
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<Point3D> movementPoints = actor.getMovementPoints();
Vector<Point3D> patrolPoints = actor.getPatrolPoints();
CellObject cell = null;
//while(!finished && movementPoints.size() != 0) {
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<Point3D> path = core.aiService.findPath(creature.getPlanetId(), currentPosition, targetPosition);
float distanceToTarget = targetPosition.getWorldPosition().getDistance(creature.getWorldPosition());
if(distanceToTarget > stopDistance) {
maxDistance = Math.min(speed, distanceToTarget - stopDistance);
} else {
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.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)));
} 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 findNewLoiterPosition(TurretAIActor actor, float speed, float stopDistance, Point3D newPosition) {
speed *= 0.5; // 2 updates per second
TangibleObject creature = actor.getCreature();
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<Point3D> movementPoints = actor.getMovementPoints();
CellObject cell = null;
targetPosition = actor.getLoiterDestination();
Vector<Point3D> path = core.aiService.findPath(creature.getPlanetId(), currentPosition, targetPosition);
float distanceToTarget = targetPosition.getWorldPosition().getDistance(creature.getWorldPosition());
if(distanceToTarget > stopDistance) {
maxDistance = Math.min(speed, distanceToTarget - stopDistance);
} else {
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(currentPosition.getWorldPosition().getDistance(currentPathPosition.getWorldPosition()) <= stopDistance && cell == creature.getContainer()) {
// if(i == path.size() - 1)
// 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)));
} 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 findNewFollowPosition(TurretAIActor actor, float speed, float stopDistance, Point3D newPosition) {
speed *= 0.5; // 2 updates per second
TangibleObject creature = actor.getCreature();
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<Point3D> movementPoints = actor.getMovementPoints();
Vector<Point3D> patrolPoints = actor.getPatrolPoints();
CellObject cell = null;
//while(!finished && movementPoints.size() != 0) {
if (movementPoints.size() != 0)
targetPosition = movementPoints.firstElement();
if (actor.getCurrentState().getClass().equals(PatrolState.class)){
targetPosition = patrolPoints.get(actor.getPatrolPointIndex());
}
if (actor.getCurrentState().getClass().equals(FollowState.class)){
targetPosition = actor.getFollowObject().getWorldPosition();
}
Vector<Point3D> path = core.aiService.findPath(creature.getPlanetId(), currentPosition, targetPosition);
float distanceToTarget = targetPosition.getWorldPosition().getDistance(creature.getWorldPosition());
if(distanceToTarget > stopDistance) {
maxDistance = Math.min(speed, distanceToTarget - stopDistance);
} else {
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.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)));
} 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 void doMove(TurretAIActor actor) {
}
public void doPatrol(TurretAIActor actor) {
}
public void doLoiter(TurretAIActor actor) {
}
public void doFollow(TurretAIActor actor) {
}
}
@@ -0,0 +1,160 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* 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 <http://www.gnu.org/licenses/>.
*
* 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.ai.states;
import java.util.Random;
import java.util.Vector;
import main.NGECore;
import resources.objects.creature.CreatureObject;
import resources.objects.tangible.TangibleObject;
import resources.objects.weapon.WeaponObject;
import services.ai.AIActor;
import services.ai.TurretAIActor;
import tools.DevLog;
public class TurretAttackState extends TurretAIState {
@Override
public byte onEnter(TurretAIActor actor) {
// DevLog.debugout("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;
// 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());
if(!creature.isInCombat() || creature.getDefendersList().size() == 0 || actor.getFollowObject() == null)
return StateResult.FINISHED;
actor.scheduleRecovery();
return StateResult.UNFINISHED;
}
@Override
public byte onExit(TurretAIActor actor) {
// TODO Auto-generated method stub
// actor.getCreature().setLookAtTarget(0);
// actor.getCreature().setIntendedTarget(0);
actor.setFollowObject(null);
// DevLog.debugout("Charon", "AI Attack State", "onExit");
return StateResult.FINISHED;
}
@Override
public byte move(TurretAIActor actor) {
return StateResult.FINISHED;
}
@Override
public byte recover(TurretAIActor actor) {
TangibleObject creature = actor.getCreature();
float maxDistance = 0;
WeaponObject weapon = null;
//weapon = (WeaponObject) creature.getSlottedObject("default_weapon");
long weaponID = (long) creature.getAttachment("TurretWeapon");
weapon = (WeaponObject) NGECore.getInstance().objectService.getObject(weaponID);
//DevLog.debugout("Charon", "AI Attack State", "weapontype " + weapon.getTemplate());
if(weapon == null)
return StateResult.FINISHED;
maxDistance = weapon.getMaxRange() - 1;
if(actor.getTimeSinceLastAttack() < weapon.getAttackSpeed() * 1000) {
//actor.scheduleRecovery();
return StateResult.UNFINISHED;
}
NGECore core = NGECore.getInstance();
if(creature.getConditionDamage()>creature.getMaximumCondition())
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 TurretIdleState());
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");
actor.scheduleRecovery();
return StateResult.UNFINISHED;
}
if (target instanceof CreatureObject){
CreatureObject targetCreature = (CreatureObject) target;
if(targetCreature.getPosture() == 13 || targetCreature.getPosture() == 14 || targetCreature.isInStealth()) {
actor.setFollowObject(actor.getHighestDamageDealer());
target = (CreatureObject) actor.getFollowObject();
if(target == null)
{
// creature.setLookAtTarget(0);
// creature.setIntendedTarget(0);
}
actor.setFollowObject(null);
actor.removeDefender(target);
actor.setCurrentState(new TurretIdleState());
return StateResult.FINISHED;
}
if(targetCreature.getWorldPosition().getDistance(creature.getWorldPosition()) > 128 || targetCreature.getPosture() == 13 || targetCreature.getPosture() == 14) {
actor.removeDefender(target);
actor.scheduleRecovery();
return StateResult.UNFINISHED;
}
}
// DevLog.debugout("Charon", "AI Attack State", "prior to attacks dist " + target.getWorldPosition().getDistance(creature.getWorldPosition()));
// DevLog.debugout("Charon", "AI Attack State", "prior to attacks maxDistance " + maxDistance);
if(target.getWorldPosition().getDistance(creature.getWorldPosition()) > maxDistance) {
actor.scheduleRecovery();
return StateResult.UNFINISHED;
}
//actor.faceObject(target);
core.commandService.callCommand(creature, "rangedShot", target, "");
actor.setLastAttackTimestamp(System.currentTimeMillis());
actor.scheduleRecovery();
return StateResult.UNFINISHED;
}
}
@@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* 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 <http://www.gnu.org/licenses/>.
*
* 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.ai.states;
import services.ai.TurretAIActor;
public class TurretIdleState extends TurretAIState {
@Override
public byte onEnter(TurretAIActor actor) {
// TODO Auto-generated method stub
return 0;
}
@Override
public byte onExit(TurretAIActor actor) {
// TODO Auto-generated method stub
return 0;
}
@Override
public byte move(TurretAIActor actor) {
// TODO Auto-generated method stub
return 0;
}
@Override
public byte recover(TurretAIActor actor) {
// TODO Auto-generated method stub
return 0;
}
}
+2 -1
View File
@@ -23,12 +23,13 @@ package services.combat;
import resources.objects.creature.CreatureObject;
import engine.resources.common.Event;
import engine.resources.objects.SWGObject;
public class CombatEvents implements Event {
public class DamageTaken implements Event {
public CreatureObject attacker;
public SWGObject attacker;
public int damage;
}
+372 -2
View File
@@ -54,6 +54,7 @@ import resources.datatables.Elemental;
import resources.datatables.Posture;
import resources.datatables.WeaponType;
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;
@@ -240,6 +241,148 @@ public class CombatService implements INetworkDispatch {
}
}
}
public void doCombatForInstallation(final InstallationObject attacker, final TangibleObject target, final WeaponObject weapon, final CombatCommand command, final int actionCounter) {
if(target instanceof CreatureObject) if(((CreatureObject) target).getPosture() == Posture.Incapacitated || ((CreatureObject) target).getPosture() == Posture.Dead) return;
boolean success = true;
// if((command.getAttackType() == 0 || command.getAttackType() == 1 || command.getAttackType() == 3) && !attemptCombat(attacker, target))
// success = false;
// if(success && !applySpecialCost(attacker, weapon, command))
// success = false;
if(!success) {
IoSession session = attacker.getClient().getSession();
CommandEnqueueRemove commandRemove = new CommandEnqueueRemove(attacker.getObjectId(), actionCounter);
session.write(new ObjControllerMessage(0x0B, commandRemove).serialize());
StartTask startTask = new StartTask(actionCounter, attacker.getObjectID(), command.getCommandCRC(), CRC.StringtoCRC(command.getCooldownGroup()), -1);
session.write(new ObjControllerMessage(0x0B, startTask).serialize());
return;
}
final Point3D targetPos = target.getPosition();
final SWGObject targetParent = target.getContainer();
if(command.getDelayAttackParticle().length() > 0 || command.getInitialAttackDelay() > -1) {
if(command.getInitialAttackDelay() > 0) {
if(command.getDelayAttackParticle().length() > 0)
target.notifyObservers(new PlayClientEffectLocMessage(command.getDelayAttackParticle(), target.getPlanet().getName(), target.getWorldPosition()), true);
try {
Thread.sleep((long) command.getInitialAttackDelay() * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if(command.getInitialAttackDelay() <= 0 && command.getDelayAttackInterval() > 0 && command.getDelayAttackLoops() <= 1) {
try {
Thread.sleep((long) command.getDelayAttackInterval() * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(command.getDelayAttackParticle().length() > 0)
target.notifyObservers(new PlayClientEffectLocMessage(command.getDelayAttackParticle(), target.getPlanet().getName(), target.getWorldPosition()), true);
}
if(command.getDelayAttackLoops() > 1) {
final ScheduledFuture<?> task = scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
if(command.getDelayAttackParticle().length() > 0)
target.notifyObservers(new PlayClientEffectLocMessage(command.getDelayAttackParticle(), target.getPlanet().getName(), target.getWorldPosition()), true);
if(command.getAttackType() == 1)
doSingleTargetCombatForInstallation(attacker, target, weapon, command, actionCounter);
//else if(command.getAttackType() == 0 || command.getAttackType() == 2 || command.getAttackType() == 3)
//doAreaCombat(attacker, targetPos, weapon, command, actionCounter, targetParent);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 0, (long) (command.getDelayAttackInterval() * 1000), TimeUnit.MILLISECONDS);
scheduler.schedule(new Runnable() {
@Override
public void run() {
try {
task.cancel(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}, (long) ((command.getDelayAttackInterval() * 1000) * command.getDelayAttackLoops()), TimeUnit.MILLISECONDS);
return;
} else {
if(command.getAttackType() == 1)
doSingleTargetCombatForInstallation(attacker, target, weapon, command, actionCounter);
//else if(command.getAttackType() == 0 || command.getAttackType() == 2 || command.getAttackType() == 3)
//doAreaCombat(attacker, targetPos, weapon, command, actionCounter, targetParent);
}
} else {
if(command.getAttackType() == 1)
doSingleTargetCombatForInstallation(attacker, target, weapon, command, actionCounter);
//else if(command.getAttackType() == 0 || command.getAttackType() == 2 || command.getAttackType() == 3)
//doAreaCombat(attacker, target, weapon, command, actionCounter);
}
if(target instanceof CreatureObject)
{
CreatureObject creature = (CreatureObject)target;
if(creature.getPosture() == Posture.Incapacitated || creature.getPosture() == Posture.Dead)
{
for (TangibleObject defender : new ArrayList<TangibleObject>(creature.getDefendersList()))
{
defender.removeDefender(creature);
creature.removeDefender(defender);
}
if(((CreatureObject) target).getPlayerObject() == null)
{
target.setKiller(attacker);
scheduler.schedule(new Runnable()
{
@Override
public void run()
{
try {
core.objectService.destroyObject(target);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 2, TimeUnit.MINUTES);
}
}
}
else if(target instanceof TangibleObject)
{
if(target.getConditionDamage() == target.getMaximumCondition())
{
for(TangibleObject defender : target.getDefendersList()) defender.removeDefender(target);
core.objectService.destroyObject(target);
}
}
}
private void doAreaCombat(CreatureObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command, int actionCounter) {
if(target instanceof CreatureObject) {
@@ -313,6 +456,24 @@ public class CombatService implements INetworkDispatch {
}
private void doSingleTargetCombatForInstallation(InstallationObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command, int actionCounter) {
if(target instanceof CreatureObject) {
doSingleTargetCombatForInstallation(attacker, (CreatureObject) target, weapon, command, actionCounter);
return;
}
float damage = calculateDamageForInstallation(attacker, target, weapon, command);
if(damage > 0)
applyDamageForInstallation(attacker, target, (int) damage);
sendCombatPacketsForInstallation(attacker, target, weapon, command, actionCounter, damage, 0, HitType.HIT);
if(FileUtilities.doesFileExist("scripts/commands/combat/" + command.getCommandName() + ".py"))
core.scriptService.callScript("scripts/commands/combat/", command.getCommandName(), "run", core, attacker, target, damage);
}
private void applyDamage(CreatureObject attacker, TangibleObject target, int damage) {
target.setConditionDamage(target.getConditionDamage() + damage);
@@ -336,9 +497,127 @@ public class CombatService implements INetworkDispatch {
event.attacker = attacker;
event.damage = damage;
target.getEventBus().publish(event);
System.out.println("APPLY DAMAGE2");
attacker.setTefTime(300000);
}
private void applyDamageForInstallation(InstallationObject attacker, TangibleObject target, int damage) {
target.setConditionDamage(target.getConditionDamage() + damage);
if (target.getOption(Options.MOUNT)) {
core.mountService.damage((CreatureObject) target);
}
if (target instanceof CreatureObject){
CreatureObject targetCreature = (CreatureObject)target;
if (targetCreature.getCalledPet()!=null) {
AIActor petActor = (AIActor) targetCreature.getCalledPet().getAttachment("AI");
if (petActor!=null){
petActor.addDefender(attacker);
DevLog.debugout("Charon", "Pet AI", "applyDamage addDefender");
}
}
}
DamageTaken event = events.new DamageTaken();
event.attacker = attacker;
event.damage = damage;
target.getEventBus().publish(event);
//attacker.setTefTime(300000);
}
private void applyDamageForInstallation(InstallationObject attacker, CreatureObject target, int damage) {
if(target.getHealth() - damage <= 0 && target.getSlottedObject("ghost") != null) {
if(target.hasBuff("incapWeaken")) {
AIActor aiActor = (AIActor)attacker.getAttachment("AI");
deathblowPlayerFromInstallation(attacker, target);
return;
}
AIActor aiActor = (AIActor)attacker.getAttachment("AI");
if (aiActor.getMobileTemplate().isDeathblow()){
deathblowPlayerFromInstallation(attacker, target);
return;
}
synchronized(target.getMutex()) {
if (core.mountService.isMounted(target)) {
core.mountService.dismount(target, (CreatureObject) target.getContainer());
}
target.setHealth(1);
target.setPosture(Posture.Incapacitated);
target.setTurnRadius(0);
target.setSpeedMultiplierBase(0);
}
ScheduledFuture<?> incapTask = scheduler.schedule(() -> {
synchronized(target.getMutex()) {
try {
if(target.getPosture() != 13)
return;
target.setPosture(Posture.Upright);
target.setTurnRadius(1);
target.setSpeedMultiplierBase(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}, target.getIncapTimer(), TimeUnit.SECONDS);
target.setIncapTask(incapTask);
core.buffService.addBuffToCreature(target, "incapWeaken", target);
if(target.getSlottedObject("ghost") != null && attacker.getSlottedObject("ghost") != null) {
target.sendSystemMessage(OutOfBand.ProsePackage("@base_player:prose_victim_incap", "TT", attacker.getCustomName()), DisplayType.Broadcast);
//attacker.sendSystemMessage(OutOfBand.ProsePackage("@base_player:prose_target_incap", "TT", target.getCustomName()), DisplayType.Broadcast);
} else {target.sendSystemMessage(OutOfBand.ProsePackage("@base_player:prose_victim_incap", "TT", "@" + attacker.getStfFilename() + ":" + attacker.getStfName()), DisplayType.Broadcast); }
return;
} else if(target.getHealth() - damage <= 0 && target.getAttachment("AI") != null) {
synchronized(target.getMutex()) {
target.setHealth(0);
target.setPosture(Posture.Dead);
}
attacker.removeDefender(target);
target.removeDefender(attacker);
return;
}
synchronized(target.getMutex()) {
target.setHealth(target.getHealth() - damage);
}
if (target instanceof CreatureObject){
CreatureObject targetCreature = (CreatureObject)target;
if (targetCreature.getCalledPet()!=null) {
AIActor petActor = (AIActor) targetCreature.getCalledPet().getAttachment("AI");
if (petActor!=null){
petActor.addDefender(attacker);
DevLog.debugout("Charon", "Pet AI", "applyDamage addDefender");
}
}
}
if (target.getPosture()!=13){
DamageTaken event = events.new DamageTaken();
event.attacker = attacker;
event.damage = damage;
target.getEventBus().publish(event);
}
}
private void doAreaCombat(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command, int actionCounter) {
@@ -455,6 +734,27 @@ public class CombatService implements INetworkDispatch {
sendCombatPackets(attacker, target, weapon, command, actionCounter, damage, 0, HitType.HIT);
}
private void doSingleTargetCombatForInstallation(InstallationObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command, int actionCounter) {
float damage = calculateDamageForInstallation(attacker, target, weapon, command);
if(damage > 0) {
damage *= 1.5f;
int damageBeforeArmor = (int) damage;
damage *= 0.99;
int armorAbsorbed = (int) (damageBeforeArmor - damage);
if(damage > 0)
applyDamageForInstallation(attacker, target, (int) damage);
sendCombatPacketsForInstallation(attacker, target, weapon, command, actionCounter, damage, armorAbsorbed, HitType.CRITICAL);
if(FileUtilities.doesFileExist("scripts/commands/combat/" + command.getCommandName() + ".py"))
core.scriptService.callScript("scripts/commands/combat/", command.getCommandName(), "run", core, attacker, target, damage);
return;
}
}
private void sendCombatPackets(CreatureObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command, int actionCounter, float damage, int armorAbsorbed, int hitType) {
@@ -485,6 +785,21 @@ public class CombatService implements INetworkDispatch {
}
private void sendCombatPacketsForInstallation(InstallationObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command, int actionCounter, float damage, int armorAbsorbed, int hitType) {
String animationStr = command.getRandomAnimation(weapon);
int turret_fire = 0xD334C0B8; // 0xA7595B4E
//CombatAction combatAction = new CombatAction(CRC.StringtoCRC(animationStr), attacker.getObjectID(), weapon.getObjectID(), target.getObjectID(), command.getCommandCRC());
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);
ObjControllerMessage objController4 = new ObjControllerMessage(0x1B, combatSpam);
IoBuffer spam = objController4.serialize();
if(target.getClient() != null)
target.getClient().getSession().write(spam);
}
private void sendHealPackets(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command, int actionCounter) {
CombatAction combatAction = new CombatAction(CRC.StringtoCRC(command.getDefaultAnimations()[0]), attacker.getObjectID(), weapon.getObjectID(), target.getObjectID(), command.getCommandCRC());
@@ -682,6 +997,23 @@ public class CombatService implements INetworkDispatch {
return rawDamage;
}
private float calculateDamageForInstallation(InstallationObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command) {
float rawDamage = command.getAddedDamage();
if(command.getPercentFromWeapon() > 0) {
float weaponMinDmg = weapon.getMinDamage();
float weaponMaxDmg = weapon.getMaxDamage();
float weaponDmg = new Random().nextInt((int) (weaponMaxDmg - weaponMinDmg + 1)) + weaponMinDmg;
weaponDmg *= command.getPercentFromWeapon();
rawDamage += weaponDmg;
}
return rawDamage;
}
private float calculateDamage(CreatureObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command) {
@@ -723,6 +1055,24 @@ public class CombatService implements INetworkDispatch {
}
private float calculateDamageForInstallation(InstallationObject attacker, TangibleObject target, WeaponObject weapon, CombatCommand command) {
float rawDamage = command.getAddedDamage();
if(command.getPercentFromWeapon() > 0 && weapon != attacker.getSlottedObject("default_weapon")) {
float weaponMinDmg = weapon.getMinDamage();
float weaponMaxDmg = weapon.getMaxDamage();
float weaponDmg = new Random().nextInt((int) (weaponMaxDmg - weaponMinDmg + 1)) + weaponMinDmg;
weaponDmg *= command.getPercentFromWeapon();
rawDamage += weaponDmg;
}
return rawDamage;
}
public byte getHitType(CreatureObject attacker, CreatureObject target, WeaponObject weapon, CombatCommand command) {
float r;
@@ -1148,6 +1498,26 @@ public class CombatService implements INetworkDispatch {
core.playerService.sendCloningWindow(target, attacker.getSlottedObject("ghost") != null);
}
public void deathblowPlayerFromInstallation(InstallationObject attacker, CreatureObject target) {
target.stopIncapTask();
target.setIncapTask(null);
target.setPosture(Posture.Dead);
attacker.removeDefender(target);
target.removeDefender(attacker);
target.setSpeedMultiplierBase(0);
target.setTurnRadius(0);
if (attacker.getSlottedObject("ghost") != null)
target.sendSystemMessage(OutOfBand.ProsePackage("@base_player:prose_victim_dead", "TT", attacker.getCustomName()), DisplayType.Broadcast);
else
target.sendSystemMessage(OutOfBand.ProsePackage("@base_player:prose_victim_dead", "TT", "@" + attacker.getStfFilename() + ":" + attacker.getStfName()), DisplayType.Broadcast);
core.playerService.sendCloningWindow(target, attacker.getSlottedObject("ghost") != null);
}
public boolean areInDuel(CreatureObject creature1, CreatureObject creature2) {
if(creature1.getDuelList().contains(creature2) && creature2.getDuelList().contains(creature1))
@@ -1385,7 +1755,7 @@ public class CombatService implements INetworkDispatch {
if(creature.getClient() == null) {
if (creature.getAttachment("AI")!=null){
AIActor aiActor = (AIActor) creature.getAttachment("AI");
CreatureObject target = aiActor.getFollowObject();
TangibleObject target = aiActor.getFollowObject();
if (target.getClient()!=null)
client = target.getClient(); // Use player's client reference that is in combat with that NPC
}
+360 -1
View File
@@ -50,6 +50,7 @@ import protocol.swg.objectControllerObjects.CommandEnqueueRemove;
import protocol.swg.objectControllerObjects.StartTask;
import resources.objects.cell.CellObject;
import resources.objects.creature.CreatureObject;
import resources.objects.installation.InstallationObject;
import resources.objects.tangible.TangibleObject;
import resources.objects.weapon.WeaponObject;
@@ -149,6 +150,7 @@ public class CommandService implements INetworkDispatch {
if (!core.simulationService.checkLineOfSight(actor, target)) {
actor.showFlyText("@combat_effects:cant_see", 1.5f, new RGB(72, 209, 204), 1, true);
// If this is AI consider side steps to get LOS
return false;
}
@@ -328,8 +330,255 @@ public class CommandService implements INetworkDispatch {
return true;
}
public boolean callCommandForInstallation(InstallationObject actor, SWGObject target, BaseSWGCommand command, int actionCounter, String commandArgs) {
if (actor == null) {
return false;
}
if (command == null) {
return false;
}
if (command.isDisabled()) {
return false;
}
// if (actor.hasCooldown(command.getCooldownGroup()) || actor.hasCooldown(command.getCommandName())) {
// return false;
// }
//TangibleObject weapon = (TangibleObject) core.objectService.getObject(actor.getWeaponId());
TangibleObject weapon = (TangibleObject) core.objectService.getObject((long)actor.getAttachment("TurretWeapon"));
if (weapon != null && weapon instanceof WeaponObject && ((WeaponObject) weapon).getWeaponType() == command.getInvalidWeapon()) {
System.out.println("Invalid WEAPON!");
return false;
}
switch (command.getTargetType()) {
case 0: // Target Not Used For This Command
break;
case 1: // Other Only (objectId/targetName)
if (target == null || target == actor) {
if (commandArgs != null && !commandArgs.equals("")) {
String name = commandArgs.split(" ")[0];
target = core.objectService.getObjectByFirstName(name);
if (target == actor) {
target = null;
}
}
break;
}
if (target == actor) {
return false;
}
if (target.getContainer() == actor || target.getGrandparent() == actor) {
break;
}
if (command.getMaxRangeToTarget() != 0 && actor.getPosition().getDistance(target.getPosition()) > command.getMaxRangeToTarget()) {
return false;
}
if (!target.isInQuadtree() && (target.getContainer() == null || !(target.getContainer() instanceof CellObject))) {
break;
}
if (!core.simulationService.checkLineOfSight(actor, target)) {
actor.showFlyText("@combat_effects:cant_see", 1.5f, new RGB(72, 209, 204), 1, true);
// If this is AI consider side steps to get LOS
return false;
}
break;
case 2: // Anyone (objectId/targetName)
if (target == null) {
if (commandArgs != null && !commandArgs.equals("")) {
String name = commandArgs.split(" ")[0];
target = core.objectService.getObjectByFirstName(name);
if (target == actor) {
target = null;
}
// It's possible they use c cmdString to indicate if it should always be on self
if (name.contains("c")) {
//target = actor;
}
}
break;
}
if (target.getContainer() == actor || target.getGrandparent() == actor) {
break;
}
if (command.getMaxRangeToTarget() != 0 && actor.getPosition().getDistance(target.getPosition()) > command.getMaxRangeToTarget()) {
return false;
}
if (!target.isInQuadtree() && (target.getContainer() == null || !(target.getContainer() instanceof CellObject))) {
break;
}
if (!core.simulationService.checkLineOfSight(actor, target)) {
actor.showFlyText("@combat_effects:cant_see", 1.5f, new RGB(72, 209, 204), 1, true);
return false;
}
break;
case 3: // Free Target Mode (rally points, group waypoints)
target = null;
if (commandArgs == null) {
break;
}
String[] args = commandArgs.split(" ");
float x = 0, y = 0, z = 0;
try {
if (args.length == 2) {
x = Integer.valueOf(args[0]);
z = Integer.valueOf(args[1]);
} else if (args.length > 2) {
x = Integer.valueOf(args[0]);
y = Integer.valueOf(args[1]);
z = Integer.valueOf(args[2]);
} else {
return false;
}
} catch (NumberFormatException e) {
return false;
}
Point3D position = new Point3D(x, y, z);
if (command.getMaxRangeToTarget() != 0 && actor.getPosition().getDistance(position) > command.getMaxRangeToTarget()) {
return false;
}
break;
case 4: // Any object
if (target == null) {
break;
}
if (command.getMaxRangeToTarget() != 0 && actor.getPosition().getDistance(target.getPosition()) > command.getMaxRangeToTarget()) {
return false;
}
if (!target.isInQuadtree() && (target.getContainer() == null || !(target.getContainer() instanceof CellObject))) {
break;
}
if (!core.simulationService.checkLineOfSight(actor, target)) {
actor.showFlyText("@combat_effects:cant_see", 1.5f, new RGB(72, 209, 204), 1, true);
return false;
}
break;
default:
break;
}
switch (command.getTarget()) {
case 0: // Ally Only
if (target == null) {
target = actor;
}
if (!(target instanceof TangibleObject)) {
return false;
}
TangibleObject object = (TangibleObject) target;
if (!object.getFaction().equals("") && !object.getFaction().equals(actor.getFaction())) {
return false;
}
if (actor.getFactionStatus() < object.getFactionStatus()) {
return false;
}
// if (object.isAttackableBy(actor)) {
// return false;
// }
// Without this we could be buffing ally NPCs and such
// Think this is checked later on
if (actor.getSlottedObject("ghost") != null && object.getSlottedObject("ghost") == null) {
return false;
}
break;
case 1: // Enemy Only
if (target == null || !(target instanceof TangibleObject)) {
return false;
}
TangibleObject targetObject = (TangibleObject) target;
// if (!targetObject.isAttackableBy(actor)) {
// return false;
// }
break;
case 2: // Indifferent
break;
default:
break;
}
// if (command.shouldCallOnTarget()) {
// if (target == null || !(target instanceof CreatureObject)) {
// return false;
// }
//
// actor = (CreatureObject) target;
// }
long warmupTime = (long) (command.getWarmupTime() * 1000f);
if(warmupTime > 0) {
try {
Thread.sleep(warmupTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(command instanceof CombatCommand) {
try {
processCommandForInstallation(actor, target, (BaseSWGCommand) command.clone(), actionCounter, commandArgs);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
else
processCommandForInstallation(actor, target, command, actionCounter, commandArgs);
return true;
}
public void callCommand(SWGObject actor, String commandName, SWGObject target, String commandArgs) {
callCommand((CreatureObject) actor, target, getCommandByName(commandName), 0, commandArgs);
if (actor instanceof CreatureObject)
callCommand((CreatureObject) actor, target, getCommandByName(commandName), 0, commandArgs);
if (actor instanceof InstallationObject)
callCommandForInstallation((InstallationObject) actor, target, getCommandByName(commandName), 0, commandArgs);
}
public BaseSWGCommand getCommandByCRC(int commandCRC) {
@@ -450,6 +699,22 @@ public class CommandService implements INetworkDispatch {
}
}
public void processCommandForInstallation(InstallationObject actor, SWGObject target, BaseSWGCommand command, int actionCounter, String commandArgs) {
// if (command.getCooldown() > 0f) {
// actor.addCooldown(command.getCooldownGroup(), command.getCooldown());
// }
if (command instanceof CombatCommand) {
processCombatCommandForInstallation(actor, target, (CombatCommand) command, actionCounter, commandArgs);
} else {
if (FileUtilities.doesFileExist("scripts/commands/" + command.getCommandName().toLowerCase() + ".py")) {
core.scriptService.callScript("scripts/commands/", command.getCommandName().toLowerCase(), "run", core, actor, target, commandArgs);
} else if (FileUtilities.doesFileExist("scripts/commands/combat/" + command.getCommandName().toLowerCase() + ".py")) {
core.scriptService.callScript("scripts/commands/combat/", command.getCommandName().toLowerCase(), "run", core, actor, target, commandArgs);
}
}
}
public void processCombatCommand(CreatureObject attacker, SWGObject target, CombatCommand command, int actionCounter, String commandArgs) {
if (FileUtilities.doesFileExist("scripts/commands/combat/" + command.getCommandName() + ".py")) {
core.scriptService.callScript("scripts/commands/combat/", command.getCommandName(), "setup", core, attacker, target, command);
@@ -549,6 +814,100 @@ public class CommandService implements INetworkDispatch {
}
public void processCombatCommandForInstallation(InstallationObject attacker, SWGObject target, CombatCommand command, int actionCounter, String commandArgs) {
if (FileUtilities.doesFileExist("scripts/commands/combat/" + command.getCommandName() + ".py")) {
core.scriptService.callScript("scripts/commands/combat/", command.getCommandName(), "setup", core, attacker, target, command);
}
boolean success = true;
//if((command.getHitType() == 5 || command.getHitType() == 7) && !(target instanceof CreatureObject))
// success = false;
if(!(command.getAttackType() == 2) && !(command.getHitType() == 5) && !(command.getHitType() == 0)) {
if(target == null || !(target instanceof TangibleObject) || target == attacker)
success = false;
} else {
if(target == null)
target = attacker;
else if(!(target instanceof TangibleObject))
return;
}
if(target instanceof CreatureObject) {
if(!(command.getHitType() == 5))
if(((CreatureObject) target).getPosture() == 13)
success = false;
if(!(command.getHitType() == 7))
if(((CreatureObject) target).getPosture() == 14)
success = false;
}
if(command.getHitType() == 7 && target.getClient() == null)
success = false;
WeaponObject weapon;
weapon = (WeaponObject) core.objectService.getObject((long)attacker.getAttachment("TurretWeapon"));
if(weapon == null)
return;
float maxRange = 0;
if(command.getMaxRange() == 0)
maxRange = weapon.getMaxRange();
else
maxRange = command.getMaxRange();
Point3D attackerPos = attacker.getWorldPosition();
Point3D defenderPos = attacker.getWorldPosition();
if(attackerPos.getDistance(defenderPos) > maxRange && maxRange != 0)
success = false;
if(command.getMinRange() > 0) {
if(attackerPos.getDistance(defenderPos) < command.getMinRange())
success = false;
}
if(target != attacker && success && !core.simulationService.checkLineOfSight(attacker, target)) {
attacker.showFlyText("@combat_effects:cant_see", 1.5f, new RGB(72, 209, 204), 1, true);
success = false;
}
if(!success && attacker.getClient() != null) {
IoSession session = attacker.getClient().getSession();
CommandEnqueueRemove commandRemove = new CommandEnqueueRemove(attacker.getObjectId(), actionCounter);
session.write(new ObjControllerMessage(0x0B, commandRemove).serialize());
StartTask startTask = new StartTask(actionCounter, attacker.getObjectID(), command.getCommandCRC(), CRC.StringtoCRC(command.getCooldownGroup()), -1);
session.write(new ObjControllerMessage(0x0B, startTask).serialize());
} else {
// if(command.getHitType() == 5) {
// core.combatService.doHeal(attacker, (CreatureObject) target, weapon, command, actionCounter);
// return;
// }
//
// if(command.getHitType() == 7) {
// core.combatService.doRevive(attacker, (CreatureObject) target, weapon, command, actionCounter);
// return;
// }
//
// if(command.getHitType() == 0 && command.getBuffNameSelf() != null && command.getBuffNameSelf().length() > 0) {
// core.combatService.doSelfBuff(attacker, weapon, command, actionCounter);
// return;
// }
for(int i = 0 ; i < command.getAttack_rolls(); i++) {
core.combatService.doCombatForInstallation(attacker, (TangibleObject) target, weapon, command, actionCounter);
}
}
}
public void removeCommand(CreatureObject actor, int actionCounter, BaseSWGCommand command) {
if (actor == null || actor.getClient() == null || command == null) {
return;
+403
View File
@@ -0,0 +1,403 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* 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 <http://www.gnu.org/licenses/>.
*
* 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 GCWPylon extends TangibleObject{
private static final long serialVersionUID = 1L;
private int pylonType = 0;
private int pylonFaction = 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[]{""};
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<Point3D> patrolRoute = new Vector<Point3D>();
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public GCWPylon() {
super();
}
public GCWPylon(long objectID, Planet planet, Point3D position, Quaternion orientation, String template){
super(objectID, planet, position, orientation, template);
}
public int getPylonType() {
return pylonType;
}
public void setPylonType(int pylonType) {
this.pylonType = pylonType;
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, 30, TimeUnit.SECONDS);
}
if (pylonType==PylonType.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, 80, TimeUnit.SECONDS);
}
}
public int getPylonFaction() {
return pylonFaction;
}
public void setPylonFaction(int pylonFaction) {
this.pylonFaction = pylonFaction;
}
public int getSpawnLevel() {
return spawnLevel;
}
public void setSpawnLevel(int spawnLevel) {
this.spawnLevel = spawnLevel;
}
public void spawnSoldier(){
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;
}
}
String soldierTemplate = soldierTemplates[new Random().nextInt(soldierTemplates.length)];
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);
totalSpawnedUnits++;
}
}
public void spawnVehicle(){
if (NGECore.getInstance().invasionService.getInvasionPhase()==2){
if (pylonFaction==Factions.Rebel){
switch (spawnLevel) {
case 1: vehicleTemplates = rebelVehicleTemplates1;
case 2: vehicleTemplates = rebelVehicleTemplates2;
case 3: vehicleTemplates = rebelVehicleTemplates3;
}
}
if (pylonFaction==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, get_Dearic_Route_1());
NGECore.getInstance().aiService.setPatrolLoop(vehicle,false);
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;
}
}
public Vector<Point3D> get_Dearic_Route_1(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
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<Point3D> get_Dearic_Route_2(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
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<Point3D> get_Dearic_Route_3(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
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(473.0F, 6.00F, -3024F));
return patrolpoints;
}
public Vector<Point3D> get_Dearic_Route_4(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
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<Point3D> get_Dearic_Route_5(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
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<Point3D> get_Dearic_Route_6(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
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<Point3D> get_Dearic_Route_7(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
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<Point3D> get_Dearic_Route_8(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
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<Point3D> get_Dearic_Route_9(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
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<Point3D> get_Dearic_Route_10(){// just for tests
Vector<Point3D> patrolpoints = new Vector<Point3D>();
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));
return patrolpoints;
}
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;
}
/*
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 int getTotalSpawnedUnits() {
return totalSpawnedUnits;
}
public void setTotalSpawnedUnits(int totalSpawnedUnits) {
this.totalSpawnedUnits = totalSpawnedUnits;
}
}
+216 -10
View File
@@ -21,13 +21,30 @@
******************************************************************************/
package services.gcw;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import protocol.swg.UpdateContainmentMessage;
import resources.datatables.FactionStatus;
import resources.datatables.Factions;
import resources.datatables.Options;
import resources.datatables.WeaponType;
import resources.objects.building.BuildingObject;
import resources.objects.creature.CreatureObject;
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.GCWPylon.PylonType;
import main.NGECore;
import engine.clients.Client;
import engine.resources.common.CRC;
import engine.resources.objects.SWGObject;
import engine.resources.scene.Point3D;
import engine.resources.scene.Quaternion;
import engine.resources.service.INetworkDispatch;
@@ -43,36 +60,225 @@ public class InvasionService implements INetworkDispatch {
private long bestineInvasionStartTime = 2;
private long dearicInvasionStartTime = 3;
private CreatureObject invasionGeneral = null;
private int invasionLocation=InvasionLocation.Dearic;
private int invadingFaction=Factions.Imperial;
private int defendingFaction=Factions.Rebel;
private int invasionPhase=2; // Test phase 2
public InvasionService(final NGECore core) {
this.core = core;
this.core = core;
}
public void spawnOffensiveAssets(){
spawnOffensiveCamps();
}
public void spawnDefensiveAssets(){
spawnGeneral();
spawnDefensiveQuestOfficer();
spawnBarricades();
spawnTurrets();
}
public void testPylons(){
Quaternion quaternion = new Quaternion(0.28F,0F,0.95F,0F);
SoldierPatrolPylon pylon1 = (SoldierPatrolPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(-48, 4, -2798), quaternion);
pylon1.setPylonFaction(Factions.Imperial);
/*
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);
core.simulationService.add(pylon1, pylon1.getPosition().x, pylon1.getPosition().z, true);
pylon1.setPatrolRoute(PatrolRoute.Dearic1);
pylon1.setPylonType(PylonType.SoldierPatrol);
pylon1.setPylonFaction(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);
core.simulationService.add(pylon2, pylon2.getPosition().x, pylon2.getPosition().z, true);
pylon2.setPatrolRoute(PatrolRoute.Dearic1);
pylon2.setPylonType(PylonType.VehiclePatrol);
pylon2.setPylonFaction(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);
// 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);
core.simulationService.add(pylon3, pylon3.getPosition().x, pylon3.getPosition().z, true);
pylon3.setPatrolRoute(PatrolRoute.Dearic2);
pylon3.setPylonType(PylonType.SoldierPatrol);
pylon3.setPylonFaction(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);
core.simulationService.add(pylon4, pylon4.getPosition().x, pylon4.getPosition().z, true);
pylon4.setPatrolRoute(PatrolRoute.Dearic3);
pylon4.setPylonType(PylonType.SoldierPatrol);
pylon4.setPylonFaction(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);
core.simulationService.add(pylon5, pylon5.getPosition().x, pylon5.getPosition().z, true);
pylon5.setPatrolRoute(PatrolRoute.Dearic4);
pylon5.setPylonType(PylonType.SoldierPatrol);
pylon5.setPylonFaction(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);
core.simulationService.add(pylon6, pylon6.getPosition().x, pylon6.getPosition().z, true);
pylon6.setPatrolRoute(PatrolRoute.Dearic5);
pylon6.setPylonType(PylonType.SoldierPatrol);
pylon6.setPylonFaction(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);
core.simulationService.add(pylon7, pylon7.getPosition().x, pylon7.getPosition().z, true);
pylon7.setPatrolRoute(PatrolRoute.Dearic6);
pylon7.setPylonType(PylonType.SoldierPatrol);
pylon7.setPylonFaction(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);
core.simulationService.add(pylon8, pylon8.getPosition().x, pylon8.getPosition().z, true);
pylon8.setPatrolRoute(PatrolRoute.Dearic7);
pylon8.setPylonType(PylonType.SoldierPatrol);
pylon8.setPylonFaction(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);
core.simulationService.add(pylon9, pylon9.getPosition().x, pylon9.getPosition().z, true);
pylon9.setPatrolRoute(PatrolRoute.Dearic8);
pylon9.setPylonType(PylonType.SoldierPatrol);
pylon9.setPylonFaction(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);
core.simulationService.add(pylon10, pylon10.getPosition().x, pylon10.getPosition().z, true);
pylon10.setPatrolRoute(PatrolRoute.Dearic9);
pylon10.setPylonType(PylonType.SoldierPatrol);
pylon10.setPylonFaction(invadingFaction);
pylon10.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);
spawnDefensiveAssets();
spawnOffensiveAssets();
}
public void spawnGeneral(){
Quaternion quaternion = new Quaternion(0.28F,0F,0.95F,0F);
SoldierPatrolPylon pylon1 = (SoldierPatrolPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(-48, 4, -2798), quaternion);
System.out.println("Spawn general");
String generalTemplate = "";
if (invadingFaction==Factions.Imperial){
generalTemplate = "rebel_invasion_general";
}
if (invadingFaction==Factions.Rebel){
generalTemplate = "imp_invasion_general";
}
if (invasionLocation==InvasionLocation.Keren){
invasionGeneral = (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);
}
if (invasionLocation==InvasionLocation.Dearic){
invasionGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(generalTemplate, "talus", 0L, 480.071F, 6, -3006.851F, 1, 0);
}
}
public void spawnDefensiveQuestOfficer(){
Quaternion quaternion = new Quaternion(0.28F,0F,0.95F,0F);
SoldierPatrolPylon pylon1 = (SoldierPatrolPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(-48, 4, -2798), quaternion);
System.out.println("spawnDefensiveQuestOfficer");
String questOfficerTemplate = "";
if (invadingFaction==Factions.Imperial){
questOfficerTemplate = "rebel_defensive_quest_officer";
}
if (invadingFaction==Factions.Rebel){
questOfficerTemplate = "imp_defensive_quest_officer";
}
if (invasionLocation==InvasionLocation.Keren){
invasionGeneral = (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);
}
if (invasionLocation==InvasionLocation.Dearic){
invasionGeneral = (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);
}
public void spawnBarricades(){
Quaternion quaternion = new Quaternion(0.28F,0F,0.95F,0F);
SoldierPatrolPylon pylon1 = (SoldierPatrolPylon) core.objectService.createObject("object/tangible/destructible/shared_gcw_city_construction_beacon.iff", 0, core.terrainService.getPlanetByName("talus"), new Point3D(-48, 4, -2798), quaternion);
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);
}
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);
core.simulationService.add(turret, turret.getPosition().x, turret.getPosition().z, true);
turret.setCustomName("Rebel Turret");
turret.setOptionsBitmask(Options.ATTACKABLE | Options.QUEST);
turret.setFaction("rebel");
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());
Set<Client> newObservers = new HashSet<Client>(turret.getObservers());
for(Client c : newObservers) {
UpdateContainmentMessage ucm = new UpdateContainmentMessage(defaultWeapon.getObjectID(), turret.getObjectID(), 4);
c.getSession().write(ucm.serialize());
}
}
@Override
-177
View File
@@ -1,177 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013 <Project SWG>
*
* 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 <http://www.gnu.org/licenses/>.
*
* 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 SoldierPatrolPylon extends TangibleObject{
private static final long serialVersionUID = 1L;
private int pylonFaction = 0;
private int spawnLevel = 0;
private int totalSpawnedSoldiers = 0;
private String[] soldierTemplates = new String[]{""};
private String[] rebelTemplates1 = new String[]{""};
private String[] rebelTemplates2 = new String[]{""};
private String[] rebelTemplates3 = new String[]{""};
private String[] imperialTemplates1 = new String[]{""};
private String[] imperialTemplates2 = new String[]{""};
private String[] imperialTemplates3 = new String[]{"elite_imperial_stormtrooper_90"};
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public SoldierPatrolPylon() {
super();
}
public SoldierPatrolPylon(long objectID, Planet planet, Point3D position, Quaternion orientation, String template){
super(objectID, planet, position, orientation, template);
scheduler.scheduleAtFixedRate(new Runnable() {
@Override public void run() {
try {
spawnSoldier();
} catch (Exception e) {
System.err.println("Exception in SoldierPatrolPylon->scheduleAtFixedRate->spawnSoldier() " + e.getMessage());
}
}
}, 5, 20, TimeUnit.SECONDS);
}
public int getPylonFaction() {
return pylonFaction;
}
public void setPylonFaction(int pylonFaction) {
this.pylonFaction = pylonFaction;
}
public int getSpawnLevel() {
return spawnLevel;
}
public void setSpawnLevel(int spawnLevel) {
this.spawnLevel = spawnLevel;
}
public void spawnSoldier(){
if (NGECore.getInstance().invasionService.getInvasionPhase()==2){
if (pylonFaction==Factions.Rebel){
switch (spawnLevel) {
case 1: soldierTemplates = rebelTemplates1;
case 2: soldierTemplates = rebelTemplates2;
case 3: soldierTemplates = rebelTemplates3;
}
}
if (pylonFaction==Factions.Imperial){
switch (spawnLevel) {
case 1: soldierTemplates = imperialTemplates1;
case 2: soldierTemplates = imperialTemplates2;
case 3: soldierTemplates = imperialTemplates3;
}
}
String soldierTemplate = soldierTemplates[new Random().nextInt(soldierTemplates.length)];
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, get_Dearic_Route_1());
NGECore.getInstance().aiService.setPatrolLoop(soldier,false);
totalSpawnedSoldiers++;
}
}
public Vector<Point3D> get_Dearic_Route_1(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
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<Point3D> get_Dearic_Route_2(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
return patrolpoints;
}
public Vector<Point3D> get_Dearic_Route_3(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
return patrolpoints;
}
public Vector<Point3D> get_Dearic_Route_4(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
return patrolpoints;
}
public Vector<Point3D> get_Dearic_Route_5(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
return patrolpoints;
}
public Vector<Point3D> get_Dearic_Route_6(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
return patrolpoints;
}
public Vector<Point3D> get_Dearic_Route_7(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
return patrolpoints;
}
public Vector<Point3D> get_Dearic_Route_8(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
return patrolpoints;
}
public Vector<Point3D> get_Dearic_Route_9(){
Vector<Point3D> patrolpoints = new Vector<Point3D>();
return patrolpoints;
}
}
+18 -2
View File
@@ -130,7 +130,7 @@ import services.command.CombatCommand;
import services.bazaar.AuctionItem;
import services.chat.ChatRoom;
import services.equipment.EquipmentService;
import services.gcw.SoldierPatrolPylon;
import services.gcw.GCWPylon;
import services.sui.SUIWindow;
import services.sui.SUIWindow.SUICallback;
import services.sui.SUIWindow.Trigger;
@@ -284,7 +284,17 @@ public class ObjectService implements INetworkDispatch {
float positionY = core.terrainService.getHeight(planet.getID(), position.x, position.z)-1f;
Point3D newpoint = new Point3D(position.x,positionY,position.z);
object = new SoldierPatrolPylon(objectID, planet, position, orientation, Template);
object = new GCWPylon(objectID, planet, position, orientation, Template);
} else if(Template.startsWith("object/tangible/destructible/")) {
// float positionY = core.terrainService.getHeight(planet.getID(), position.x, position.z)-1f;
// Point3D newpoint = new Point3D(position.x,positionY,position.z);
// object = new InstallationObject(objectID, planet, newpoint, orientation, Template);
object = new TangibleObject(objectID, planet, position, orientation, Template);
//object = new BuildingObject(objectID, planet, position, orientation, Template);
} else if(Template.startsWith("object/tangible")) {
@@ -376,6 +386,12 @@ public class ObjectService implements INetworkDispatch {
Point3D newpoint = new Point3D(position.x,positionY,position.z);
object = new HarvesterObject(objectID, planet, newpoint, orientation, Template);
} else if(Template.startsWith("object/installation/turret")) {
float positionY = core.terrainService.getHeight(planet.getID(), position.x, position.z);
Point3D newpoint = new Point3D(position.x,positionY,position.z);
object = new InstallationObject(objectID, planet, newpoint, orientation, Template);
} else {
return null;
}
+9
View File
@@ -62,6 +62,7 @@ public class MobileTemplate implements Cloneable {
private List<LootGroup> lootGroups = new ArrayList<LootGroup>();
private String PCDTemplate="";
private String conversationFileName="";
private boolean AIEnabled = true;
public Vector<String> getTemplates() {
@@ -369,5 +370,13 @@ public class MobileTemplate implements Cloneable {
public void setConversationFileName(String conversationFileName) {
this.conversationFileName = conversationFileName;
}
public boolean isAIEnabled() {
return AIEnabled;
}
public void setAIEnabled(boolean aIEnabled) {
AIEnabled = aIEnabled;
}
}
+8 -6
View File
@@ -208,13 +208,15 @@ public class SpawnService {
armor = 6000;
core.skillModService.addSkillMod(creature, "expertise_innate_protection_all", armor);
}
AIActor actor = new AIActor(creature, creature.getPosition(), scheduler);
creature.setAttachment("AI", actor);
creature.setAttachment("radial_filename", "npc/mobile");
actor.setMobileTemplate(mobileTemplate);
if (mobileTemplate.isAIEnabled()){
AIActor actor = new AIActor(creature, creature.getPosition(), scheduler);
creature.setAttachment("AI", actor);
actor.setMobileTemplate(mobileTemplate);
}
creature.setAttachment("radial_filename", "npc/mobile");
if(cell == null) {
core.simulationService.add(creature, x, z, true);