Fixed a few bugs

- Fixed KBT90
- Added simulationService method for nearby players
- Fixed an AI State issue
This commit is contained in:
CharonInferar
2014-08-06 22:26:24 +02:00
parent 1b6f522480
commit 79d56ca4ef
15 changed files with 519 additions and 54 deletions
+15
View File
@@ -214,6 +214,12 @@ def run(core, actor, target, commandString):
if latarget.getAttachment('AI'):
actor.sendSystemMessage('Checking AI progression %s' % latarget.getAttachment('AI').getProgressionMarker(), 0)
elif command == 'checkwithdrawn':
latargetID = long(actor.getIntendedTarget())
latarget = core.objectService.getObject(latargetID)
if latarget.getAttachment('isWithdrawn'):
actor.sendSystemMessage('Checking AIisWithdrawn %s' % latarget.getAttachment('isWithdrawn'), 0)
elif command == 'showbitmask':
latargetID = long(actor.getIntendedTarget())
latarget = core.objectService.getObject(latargetID)
@@ -269,6 +275,15 @@ def run(core, actor, target, commandString):
positionY = core.terrainService.getHeight(inst.getPlanetId(), inst.getPosition().x, inst.getPosition().z)
instpos = Point3D(inst.getPosition().x,positionY+2, inst.getPosition().z)
inst.setPosition(instpos)
elif command == 'los':
latargetID = long(actor.getIntendedTarget())
latarget = core.objectService.getObject(latargetID)
los = core.simulationService.checkLineOfSight(actor, latarget)
if los:
actor.sendSystemMessage('Line of sight between player and target', 0)
else:
actor.sendSystemMessage('NO Line of sight between player and target', 0)
elif command == 'unknownAbilityPacket' and arg1:
packet = UnknownAbilityPacket(arg1)
@@ -0,0 +1,45 @@
import sys
from services.spawn import MobileTemplate
from services.spawn import WeaponTemplate
from resources.datatables import WeaponType
from resources.datatables import Difficulty
from resources.datatables import Options
from resources.datatables import FactionStatus
from java.util import Vector
def addTemplate(core):
mobileTemplate = MobileTemplate()
mobileTemplate.setCustomName('A demoralized imperial soldier')
mobileTemplate.setLevel(90)
mobileTemplate.setDifficulty(Difficulty.ELITE)
mobileTemplate.setMinSpawnDistance(4)
mobileTemplate.setMaxSpawnDistance(8)
mobileTemplate.setDeathblow(True)
mobileTemplate.setSocialGroup("imperial")
mobileTemplate.setAssistRange(0)
mobileTemplate.setStalker(False)
mobileTemplate.setFaction("imperial")
mobileTemplate.setFactionStatus(FactionStatus.Combatant)
mobileTemplate.setAIEnabled(False)
templates = Vector()
templates.add('object/mobile/shared_dressed_stormtrooper_black_white.iff')
templates.add('object/mobile/shared_dressed_stormtrooper_white_black.iff')
templates.add('object/mobile/shared_dressed_stormtrooper_white_white.iff')
templates.add('object/mobile/shared_dark_trooper.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_demoralized_soldier', mobileTemplate)
return
@@ -0,0 +1,45 @@
import sys
from services.spawn import MobileTemplate
from services.spawn import WeaponTemplate
from resources.datatables import WeaponType
from resources.datatables import Difficulty
from resources.datatables import Options
from resources.datatables import FactionStatus
from java.util import Vector
def addTemplate(core):
mobileTemplate = MobileTemplate()
mobileTemplate.setCustomName('A disabled AT-ST')
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)
mobileTemplate.setOptionsBitmask(Options.ATTACKABLE)
mobileTemplate.setAIEnabled(False)
templates = Vector()
templates.add('object/mobile/shared_atst.iff')
mobileTemplate.setTemplates(templates)
weaponTemplates = Vector() # object/weapon/ranged/turret/shared_turret_heat.iff object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff
weapontemplate = WeaponTemplate('object/weapon/ranged/vehicle/shared_vehicle_atst_ranged.iff', WeaponType.CARBINE, 2.0, 55, 'energy')
#weapontemplate = WeaponTemplate('object/weapon/ranged/rifle/shared_rifle_t21.iff', WeaponType.RIFLE, 1.0, 24, 'energy')
weaponTemplates.add(weapontemplate)
mobileTemplate.setWeaponTemplateVector(weaponTemplates)
attacks = Vector()
mobileTemplate.setDefaultAttack('gcw_atst_attack_tower') #gcw_atst_attack_tower #rangedShot
mobileTemplate.setAttacks(attacks)
core.spawnService.addMobileTemplate('imp_invasion_at_st', mobileTemplate)
return
@@ -0,0 +1,44 @@
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_stormtrooper_hard')
mobileTemplate.setLevel(90)
mobileTemplate.setDifficulty(Difficulty.ELITE)
mobileTemplate.setMinSpawnDistance(4)
mobileTemplate.setMaxSpawnDistance(8)
mobileTemplate.setDeathblow(True)
mobileTemplate.setSocialGroup("imperial")
mobileTemplate.setAssistRange(0)
mobileTemplate.setStalker(False)
mobileTemplate.setFaction("imperial")
mobileTemplate.setFactionStatus(FactionStatus.Combatant)
templates = Vector()
templates.add('object/mobile/shared_dressed_stormtrooper_black_white.iff')
templates.add('object/mobile/shared_dressed_stormtrooper_white_black.iff')
templates.add('object/mobile/shared_dressed_stormtrooper_white_white.iff')
templates.add('object/mobile/shared_dark_trooper.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_soldier_cl90', 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('A demoralized rebel soldier')
mobileTemplate.setLevel(90)
mobileTemplate.setDifficulty(Difficulty.ELITE)
mobileTemplate.setMinSpawnDistance(4)
mobileTemplate.setMaxSpawnDistance(8)
mobileTemplate.setDeathblow(True)
mobileTemplate.setSocialGroup("rebel")
mobileTemplate.setAssistRange(0)
mobileTemplate.setStalker(True)
mobileTemplate.setFaction("rebel")
mobileTemplate.setFactionStatus(FactionStatus.Combatant)
mobileTemplate.setAIEnabled(False)
templates = Vector()
templates.add('object/mobile/shared_dressed_rebel_commando_human_female_01.iff')
templates.add('object/mobile/shared_dressed_rebel_commando_human_male_01.iff')
templates.add('object/mobile/shared_dressed_rebel_commando_moncal_male_01.iff')
templates.add('object/mobile/shared_dressed_rebel_commando_rodian_male_01.iff')
templates.add('object/mobile/shared_dressed_rebel_commando_twilek_female_01.iff')
templates.add('object/mobile/shared_dressed_rebel_commando_zabrak_female_01.iff')
mobileTemplate.setTemplates(templates)
weaponTemplates = Vector()
weapontemplate = WeaponTemplate('object/weapon/ranged/carbine/shared_carbine_e5.iff', WeaponType.CARBINE, 1.0, 15, 'energy')
weaponTemplates.add(weapontemplate)
mobileTemplate.setWeaponTemplateVector(weaponTemplates)
attacks = Vector()
mobileTemplate.setDefaultAttack('rangedShot')
mobileTemplate.setAttacks(attacks)
core.spawnService.addMobileTemplate('rebel_invasion_demoralized_soldier', mobileTemplate)
return
@@ -0,0 +1,44 @@
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.setCustomName('A disabled AT-XT')
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)
mobileTemplate.setOptionsBitmask(Options.ATTACKABLE)
mobileTemplate.setAIEnabled(False)
templates = Vector()
templates.add('object/mobile/shared_atxt.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('gcw_atst_attack_tower')
mobileTemplate.setAttacks(attacks)
core.spawnService.addMobileTemplate('rebel_invasion_disabled_atxt', mobileTemplate)
return
@@ -1150,9 +1150,7 @@ public class CreatureObject extends TangibleObject implements Serializable {
}
//destination.getSession().write(messageBuilder.buildBaseline8());
//destination.getSession().write(messageBuilder.buildBaseline9());
if(destination != getClient()) {
UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID(), NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) destination.getParent(), this), getFaction());
destination.getSession().write(upvpm.serialize());
@@ -408,7 +408,6 @@ public class TangibleObject extends SWGObject implements Serializable {
observer.getSession().write(new UpdatePVPStatusMessage(this.getObjectID(), NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) observer.getParent(), this), getFaction()).serialize());
if(getClient() != null){
getClient().getSession().write(new UpdatePVPStatusMessage(observer.getParent().getObjectID(), NGECore.getInstance().factionService.calculatePvpStatus((CreatureObject) this, (CreatureObject) observer.getParent()), getFaction()).serialize());
//System.out.println("SENT TO CLIENT!");
}
}
}
@@ -420,17 +419,6 @@ public class TangibleObject extends SWGObject implements Serializable {
companion.updatePvpStatus();
}
}
if (this instanceof CreatureObject){
if (((CreatureObject)this).isPlayer()){
// Here a specific CREO delta must be sent to update the faction info in character sheet and symbol in name
// If anyone knows which that would be, please replace it here!
sendBaselines(this.getClient());
}
}
}
public boolean isAttackableBy(CreatureObject attacker) {
@@ -623,7 +611,8 @@ public class TangibleObject extends SWGObject implements Serializable {
}
public void notifyClients(IoBuffer buffer, boolean notifySelf) {
notifyObservers(buffer, false);
// notifyObservers(buffer, false); // ??? Ignores the notifySelf argument. Was this done purposely? Faction Status etc. can't update the client without it
notifyObservers(buffer, notifySelf);
}
public ObjectMessageBuilder getMessageBuilder() {
@@ -678,6 +667,8 @@ public class TangibleObject extends SWGObject implements Serializable {
}
}
public void sendListDelta(byte viewType, short updateType, IoBuffer buffer) {
switch (viewType) {
case 3:
+34 -2
View File
@@ -290,6 +290,28 @@ public class SimulationService implements INetworkDispatch {
return foundCreatures;
}
public Vector<CreatureObject> getAllNearPlayers(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 && objecta!=value)
if (((CreatureObject)objecta).isPlayer())
foundCreatures.add((CreatureObject)objecta);
}
);
return foundCreatures;
}
public Vector<CreatureObject> getAllNearPlayers(int distance, Planet planet, Point3D pos ){
Vector<CreatureObject> foundCreatures = new Vector<CreatureObject>();
core.simulationService.get(planet, pos.x, pos.z, distance).stream().forEach((objecta) -> {
if (objecta instanceof CreatureObject)
if (((CreatureObject)objecta).isPlayer())
foundCreatures.add((CreatureObject)objecta);
}
);
return foundCreatures;
}
public Vector<TangibleObject> getAllNearNonSameFactionTargets(int distance, SWGObject center ){
Vector<TangibleObject> foundTargets = new Vector<TangibleObject>();
core.simulationService.get(center.getPlanet(), center.getWorldPosition().x, center.getWorldPosition().z, distance).stream().forEach((objecta) -> {
@@ -987,8 +1009,18 @@ public class SimulationService implements INetworkDispatch {
float cos = (float) Math.cos(radians);
WB_M44 rotationMatrix = new WB_M44(cos, 0, sin, 0, 0, 1, 0, 0, -sin, 0, cos, 0, 0, 0, 0, 1);
WB_M44 modelSpace = translateMatrix.mult(rotationMatrix).inverse();
WB_M44 modelSpace = null;
try {
modelSpace = translateMatrix.mult(rotationMatrix).inverse();
} catch (Exception ex){
// It's usually a bank terminal causing this
//System.out.println("The object " + object.getTemplate() + " at x:" + object.getWorldPosition().x + " z:" + object.getWorldPosition().z + " causes a problem during modelspaceconversion. Can be safely ignored.");
if (modelSpace==null)
return new Ray(origin, new Vector3D(0,0,0));
}
float originX = (float) (modelSpace.m11 * origin.x + modelSpace.m12 * origin.y + modelSpace.m13 * origin.z + modelSpace.m14);
float originY = (float) (modelSpace.m21 * origin.x + modelSpace.m22 * origin.y + modelSpace.m23 * origin.z + modelSpace.m24);
+80
View File
@@ -21,8 +21,13 @@
******************************************************************************/
package services.ai;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.Random;
import java.util.Vector;
@@ -40,6 +45,7 @@ import services.ai.states.LoiterState;
import services.ai.states.PatrolState;
import engine.resources.objects.SWGObject;
import engine.resources.scene.Point3D;
import engine.resources.service.INetworkDispatch;
import main.NGECore;
public class AIService {
@@ -238,6 +244,80 @@ public class AIService {
return (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y) + (p2.z - p1.z) * (p2.z - p1.z);
}
public void waitForEvent(AIActor actor, INetworkDispatch service, String serviceMethodName, boolean expectedValue, Class nextStateClass){
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
final Future<?>[] wfe = {null};
wfe[0] = scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
Class<?> noParams[] = {};
Method m = service.getClass().getMethod(serviceMethodName, noParams);
boolean value = (boolean) m.invoke(service);
if (value==expectedValue){
actor.setCurrentState((AIState)nextStateClass.newInstance());
System.out.println("condition true waitForEvent! " + nextStateClass.getName());
Thread.yield();
wfe[0].cancel(false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, 10, 3000, TimeUnit.MILLISECONDS);
}
public void waitForEvent(AIActor actor, INetworkDispatch service, String serviceMethodName, int expectedValue, Class nextStateClass){
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
final Future<?>[] wfe = {null};
wfe[0] = scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
Class<?> noParams[] = {};
Method m = service.getClass().getMethod(serviceMethodName, noParams);
int number = (int) m.invoke(service);
if (number==expectedValue){
actor.setCurrentState((AIState)nextStateClass.newInstance());
Thread.yield();
wfe[0].cancel(false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, 10, 3000, TimeUnit.MILLISECONDS);
}
// ToDo: Make an overloaded method with params
public void waitForEvent(INetworkDispatch service, String serviceMethodName, Object[] params){
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
final Future<?>[] wfe = {null};
wfe[0] = scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
boolean condition = true;
Object[] params; //The parameters for my method
Class<?> noParams[] = {};
Method m = service.getClass().getMethod(serviceMethodName, noParams);
m.invoke(service);
if (condition){
Thread.yield();
wfe[0].cancel(false);
}
// do something
} catch (Exception e) {
e.printStackTrace();
}
}
}, 10, 2000, TimeUnit.MILLISECONDS);
}
public void logAI(String logMsg){
if (checkDeveloperIdentity()){
System.err.println("AI-LOG: " + logMsg);
+12 -2
View File
@@ -27,6 +27,7 @@ import java.util.Vector;
import main.NGECore;
import engine.resources.scene.Point3D;
import engine.resources.scene.Quaternion;
import engine.resources.service.INetworkDispatch;
import resources.common.SpawnPoint;
import resources.objects.cell.CellObject;
import resources.objects.creature.CreatureObject;
@@ -777,8 +778,11 @@ public abstract class AIState {
if (isInvader==null)
return;
// If invader check for in weapon range general
if (core.invasionService.getInvasionPhase()==3 && core.invasionService.getDistanceToDefensiveGeneral(creature)<2500){
actor.addDefender(core.invasionService.getDefensiveGeneral());
if (core.invasionService.getDefensiveGeneral()!=null){
if (core.invasionService.getInvasionPhase()==3 && core.invasionService.getDefensiveGeneral().getPosture()!=13 && core.invasionService.getDefensiveGeneral().getPosture()!=14 && core.invasionService.getDistanceToDefensiveGeneral(creature)<2500){
actor.addDefender(core.invasionService.getDefensiveGeneral());
return;
}
}
// Check if there are more than 5 invaders at same spot
@@ -786,8 +790,14 @@ public abstract class AIState {
actor.setAIactive(false); // switch off auto-target-recognition to counter lag
actor.setCurrentState(new IdleState());
System.out.println("AI switched off!");
return;
}
//actor.setCurrentState(new IdleState());
// Wait state() Since this state does not require move,recover and all that its simple task
//NGECore.getInstance().aiService.waitForEvent(actor, NGECore.getInstance().invasionService, "isDefendingGeneralAlive", false, WithdrawalState.class);
return; // Last Patrol point reached and no loop
}
}
@@ -143,7 +143,7 @@ public class TurretAttackState extends TurretAIState {
target = (CreatureObject) actor.getFollowObject();
if(target == null)
{
// creature.setLookAtTarget(0);
// creature.setLookAtTarget(0); //Is only accessible from CreatureObject, not TANO
// creature.setIntendedTarget(0);
}
+1 -6
View File
@@ -235,13 +235,8 @@ public class GCWPylon extends TangibleObject{
turretWeapon.setMinDamage(minDamage);
turretWeapon.setMaxDamage(maxDamage);
turret.add(turretWeapon);
//turret.add(turretWeapon); // Does not have to be added explicitly, would cause engine slot arrangement error message
turret.setAttachment("TurretWeapon",turretWeapon.getObjectID());
// Set<Client> newObservers = new HashSet<Client>(turret.getObservers());
// for(Client c : newObservers) {
// UpdateContainmentMessage ucm = new UpdateContainmentMessage(turretWeapon.getObjectID(), turret.getObjectID(), 4);
// c.getSession().write(ucm.serialize());
// }
}
public void createBarricade(){
+25 -2
View File
@@ -196,25 +196,37 @@ public class GCWSpawner extends TangibleObject{
public void spawnSoldier(){
if (NGECore.getInstance().invasionService.getInvasionPhase()==2){
String stfName = "gcw_city_rebel_specforce_defense";
if (spawnerFaction==Factions.Rebel){
switch (spawnLevel) {
case 1: soldierTemplates = rebelSoldierTemplates1;
stfName = "gcw_city_rebel_grunt_assault";
break;
case 2: soldierTemplates = rebelSoldierTemplates2;
stfName = "gcw_city_rebel_grunt_assault";
break;
case 3: soldierTemplates = rebelSoldierTemplates3;
stfName = "gcw_city_rebel_specforce_assault";
break;
}
}
if (spawnerFaction==Factions.Imperial){
switch (spawnLevel) {
case 1: soldierTemplates = imperialSoldierTemplates1;
break;
case 2: soldierTemplates = imperialSoldierTemplates2;
break;
case 3: soldierTemplates = imperialSoldierTemplates3;
break;
}
}
String soldierTemplate = soldierTemplates[new Random().nextInt(soldierTemplates.length)];
//if (totalSpawnedUnits==0){
CreatureObject soldier = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(soldierTemplate, this.getPlanet().getName(), 0L, this.getPosition().x, this.getPosition().y, this.getPosition().z, this.getOrientation().w, this.getOrientation().x, this.getOrientation().y,this.getOrientation().z,-1);
if (spawnerFaction==Factions.Rebel)
soldier.setStfName(stfName);
NGECore.getInstance().invasionService.registerInvader(soldier);
totalSpawnedUnits++;
totalSpawnedUnits++;
soldier.setAttachment("IsInvader","yes");
NGECore.getInstance().aiService.setPatrol(soldier, patrolRoute);
NGECore.getInstance().aiService.setPatrolLoop(soldier,false);
@@ -226,18 +238,28 @@ public class GCWSpawner extends TangibleObject{
public void spawnSoldierDefender(){
if (NGECore.getInstance().invasionService.getInvasionPhase()==2){
String stfName = "gcw_city_rebel_specforce_defense";
if (spawnerFaction==Factions.Rebel){
switch (spawnLevel) {
case 1: soldierTemplates = rebelSoldierTemplates1;
stfName = "gcw_city_rebel_grunt_defense";
break;
case 2: soldierTemplates = rebelSoldierTemplates2;
stfName = "gcw_city_rebel_grunt_defense";
break;
case 3: soldierTemplates = rebelSoldierTemplates3;
stfName = "gcw_city_rebel_specforce_defense";
break;
}
}
if (spawnerFaction==Factions.Imperial){
switch (spawnLevel) {
case 1: soldierTemplates = imperialSoldierTemplates1;
break;
case 2: soldierTemplates = imperialSoldierTemplates2;
break;
case 3: soldierTemplates = imperialSoldierTemplates3;
break;
}
}
if (lastDefender!=null)
@@ -245,7 +267,8 @@ public class GCWSpawner extends TangibleObject{
return;
String soldierTemplate = soldierTemplates[new Random().nextInt(soldierTemplates.length)];
lastDefender = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(soldierTemplate, this.getPlanet().getName(), 0L, this.getPosition().x, this.getPosition().y, this.getPosition().z, this.getOrientation().w, this.getOrientation().x, this.getOrientation().y,this.getOrientation().z,-1);
if (spawnerFaction==Factions.Rebel)
lastDefender.setStfName(stfName);
NGECore.getInstance().invasionService.registerDefender(lastDefender);
totalSpawnedUnits++;
}
+122 -25
View File
@@ -24,7 +24,9 @@ package services.gcw;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
@@ -46,10 +48,13 @@ import resources.datatables.FactionStatus;
import resources.datatables.Factions;
import resources.datatables.GcwType;
import resources.datatables.Options;
import resources.datatables.Posture;
import resources.objects.building.BuildingObject;
import resources.objects.creature.CreatureObject;
import resources.objects.tangible.TangibleObject;
import services.ai.AIActor;
import services.ai.states.AIState;
import services.ai.states.DeathState;
import services.ai.states.WithdrawalState;
import services.gcw.GCWSpawner.PatrolRoute;
import services.gcw.GCWPylon.PylonType;
@@ -84,6 +89,7 @@ public class InvasionService implements INetworkDispatch {
private CreatureObject defendingGeneral = null;
private CreatureObject defendingQuestOfficer = null;
private Vector<CreatureObject> offensiveQuestOfficers = new Vector<CreatureObject>();
private boolean defendingGeneralAlive = true;
private int invasionLocation=-1;
private String invasionPlanet="tatooine";
@@ -116,6 +122,10 @@ public class InvasionService implements INetworkDispatch {
private int invaderRegistryCounter = 0;
private Map<Integer,CreatureObject> defendingCreatures = new ConcurrentHashMap<Integer,CreatureObject>();
private int defenderRegistryCounter = 0;
private Map<Integer,CreatureObject> demoralizedSoldiers = new ConcurrentHashMap<Integer,CreatureObject>();
private int demoralizedSoldierRegistryCounter = 0;
private Map<Integer,CreatureObject> disabledVehicles = new ConcurrentHashMap<Integer,CreatureObject>();
private int disabledVehicleRegistryCounter = 0;
private Map<Integer,TangibleObject> phase2Objects = new ConcurrentHashMap<Integer,TangibleObject>();
private int phase2ObjectRegistryCounter = 0;
private Vector<TangibleObject> defensiveBanners = new Vector<TangibleObject>();
@@ -256,9 +266,9 @@ public class InvasionService implements INetworkDispatch {
}
// Message at 30:00 -> 1800000 seconds
if (invasionPhase==1 && System.currentTimeMillis()>temptimestartreference + 180000 && ! ph2_message1sent){
if (invasionPhase==1 && System.currentTimeMillis()>temptimestartreference + 200000 && ! ph2_message1sent){
invasionPhase=2;
preparePhase2();
preparePhase2();
System.out.println("PHASE 2");
send_Phase2_InvaderMessage1();
send_Phase2_DefenderMessage1();
@@ -267,7 +277,7 @@ public class InvasionService implements INetworkDispatch {
}
// Message at 45:00 -> 2700000 seconds
if (invasionPhase==2 && System.currentTimeMillis()>temptimestartreference + 900000 && ! ph2_message2sent){ // 1200000
if (invasionPhase==2 && System.currentTimeMillis()>temptimestartreference + 400000 && ! ph2_message2sent){ // 1200000
send_Phase2_InvaderMessage2();
send_Phase2_DefenderMessage2();
ph2_message2sent = true;
@@ -305,24 +315,28 @@ public class InvasionService implements INetworkDispatch {
grantGCWTokens(invadingFaction,10);
grantGCWTokens(defendingFaction,130);
playVictoryMusic(defendingFaction);
// set up delayed tasks
//Clone Maps
Map<Integer,CreatureObject> invadingCreaturesClone = new ConcurrentHashMap<Integer,CreatureObject>();
Map<Integer,CreatureObject> defendingCreaturesClone = new ConcurrentHashMap<Integer,CreatureObject>();
for (Map.Entry<Integer, CreatureObject> entry : invadingCreatures.entrySet()) {
for (Map.Entry<Integer, CreatureObject> entry : getInvadingCreaturesEntrySet()) {
invadingCreaturesClone.put(entry.getKey(), entry.getValue());
}
for (Map.Entry<Integer, CreatureObject> entry : defendingCreatures.entrySet()) {
for (Map.Entry<Integer, CreatureObject> entry : getDefendingCreaturesEntrySet()) {
defendingCreaturesClone.put(entry.getKey(), entry.getValue());
}
withdrawInvaders();
Executors.newSingleThreadScheduledExecutor().schedule(() -> {
wipeInvaders(invadingCreaturesClone);
wipeDefenders(defendingCreaturesClone); // Make sure all are deleted
}, 360, TimeUnit.SECONDS);
withdrawInvaders();
for (BuildingObject camp : offensiveCamps){
core.simulationService.remove(camp, camp.getWorldPosition().x, camp.getWorldPosition().z, true);
core.objectService.destroyObject(camp.getObjectID());
@@ -373,6 +387,8 @@ public class InvasionService implements INetworkDispatch {
grantGCWTokens(invadingFaction,130);
grantGCWTokens(defendingFaction,10);
playVictoryMusic(invadingFaction);
// Clean Up
// wipeInvaders();
@@ -382,20 +398,22 @@ public class InvasionService implements INetworkDispatch {
//Clone Maps
Map<Integer,CreatureObject> invadingCreaturesClone = new ConcurrentHashMap<Integer,CreatureObject>();
Map<Integer,CreatureObject> defendingCreaturesClone = new ConcurrentHashMap<Integer,CreatureObject>();
for (Map.Entry<Integer, CreatureObject> entry : invadingCreatures.entrySet()) {
for (Map.Entry<Integer, CreatureObject> entry : getInvadingCreaturesEntrySet()) {
invadingCreaturesClone.put(entry.getKey(), entry.getValue());
}
for (Map.Entry<Integer, CreatureObject> entry : defendingCreatures.entrySet()) {
for (Map.Entry<Integer, CreatureObject> entry : getDefendingCreaturesEntrySet()) {
defendingCreaturesClone.put(entry.getKey(), entry.getValue());
}
withdrawInvaders();
Executors.newSingleThreadScheduledExecutor().schedule(() -> {
wipeInvaders(invadingCreaturesClone);
wipeDefenders(defendingCreaturesClone); // Make sure all are deleted
}, 360, TimeUnit.SECONDS);
withdrawInvaders();
for (BuildingObject camp : offensiveCamps){
core.simulationService.remove(camp, camp.getWorldPosition().x, camp.getWorldPosition().z, true);
core.objectService.destroyObject(camp.getObjectID());
@@ -442,7 +460,7 @@ public class InvasionService implements INetworkDispatch {
}
public void withdrawInvaders(){
for (Map.Entry<Integer, CreatureObject> entry : invadingCreatures.entrySet()) {
for (Map.Entry<Integer, CreatureObject> entry : getInvadingCreaturesEntrySet()) {
CreatureObject creature = entry.getValue();
if (creature!=null){
if (creature.getAttachment("AI")!=null){
@@ -452,6 +470,7 @@ public class InvasionService implements INetworkDispatch {
actor.setAIactive(true);
actor.setIntendedPrimaryAIState(new WithdrawalState());
actor.setCurrentState(new WithdrawalState());
creature.setAttachment("isWithdrawn",1);
}
}
}
@@ -499,14 +518,34 @@ public class InvasionService implements INetworkDispatch {
}
public void registerInvader(CreatureObject registrant){
// System.out.println("Registered! " + invaderRegistryCounter);
invadingCreatures.put(invaderRegistryCounter++, registrant);
synchronized(invadingCreatures) {
// System.out.println("Registered! " + invaderRegistryCounter);
invadingCreatures.put(invaderRegistryCounter++, registrant);
}
}
public void registerDefender(CreatureObject registrant){
defendingCreatures.put(invaderRegistryCounter++, registrant);
synchronized(defendingCreatures) {
defendingCreatures.put(defenderRegistryCounter++, registrant);
}
}
public void registerDemoralizedSoldier(CreatureObject registrant){
synchronized(demoralizedSoldiers) {
// System.out.println("Registered! " + invaderRegistryCounter);
demoralizedSoldiers.put(demoralizedSoldierRegistryCounter++, registrant);
}
}
public void registerDisabledVehicle(CreatureObject registrant){
synchronized(disabledVehicles) {
// System.out.println("Registered! " + invaderRegistryCounter);
disabledVehicles.put(disabledVehicleRegistryCounter++, registrant);
}
}
public void wipeInvaders(Map<Integer,CreatureObject> invaderMap){
for (BuildingObject camp : offensiveCamps){
@@ -619,7 +658,9 @@ public class InvasionService implements INetworkDispatch {
public void registerPhase2Objects(TangibleObject registrant){
phase2Objects.put(phase2ObjectRegistryCounter++, registrant);
synchronized(phase2Objects){
phase2Objects.put(phase2ObjectRegistryCounter++, registrant);
}
}
public void deletePhase2Objects(){
@@ -1280,7 +1321,7 @@ public class InvasionService implements INetworkDispatch {
spawnPylon(PylonType.Barricade, defendingFaction, "naboo", new Point3D(1782.81F, 12, 2516.37F), 0.71F, 0.70F);
spawnPylon(PylonType.Barricade, defendingFaction, "naboo", new Point3D(1991.90F, 30, 2713.51F), 0.25F, 0.96F);
//spawnPylon(PylonType.Barricade, defendingFaction, "naboo", new Point3D(1990.17F, 30.29F, 2685.63F), 0.99F, 0.07F); // Makes patrols fall through the bridge
spawnPylon(PylonType.Barricade, defendingFaction, "naboo", new Point3D(1998.98F, 30.0F, 2670.41F), 0.94F, -0.32F); // works better. Do not change, it prevents clipping problems!
spawnPylon(PylonType.Barricade, defendingFaction, "naboo", new Point3D(1998.98F, 30.0F, 2670.41F), 0.94F, -0.32F); // works better. Do not change, it prevents client clipping problems!
spawnPylon(PylonType.Barricade, defendingFaction, "naboo", new Point3D(1713.97F, 12, 2655.29F), 1.00F, 0.00F);
spawnPylon(PylonType.Barricade, defendingFaction, "naboo", new Point3D(1693.40F, 12, 2636.64F), 0.72F, -0.69F);
spawnPylon(PylonType.Barricade, defendingFaction, "naboo", new Point3D(1532.30F, 25, 2757.37F), -0.69F, 0.71F);
@@ -1300,7 +1341,6 @@ public class InvasionService implements INetworkDispatch {
spawnPylon(PylonType.SoldierDefense, defendingFaction, "naboo", new Point3D(1854.98F, 12, 2541.42F), 0.36F, 0.93F);
spawnPylon(PylonType.SoldierDefense, defendingFaction, "naboo", new Point3D(1857.63F, 12, 2545.66F), 0.36F, 0.93F);
spawnPylon(PylonType.SoldierDefense, defendingFaction, "naboo", new Point3D(1864.14F, 12, 2551.11F), 0.94F, 0.32F);
spawnPylon(PylonType.SoldierDefense, defendingFaction, "naboo", new Point3D(1864.14F, 12, 2551.11F), 0.94F, 0.32F);
spawnPylon(PylonType.SoldierDefense, defendingFaction, "naboo", new Point3D(1875.09F, 12, 2556.38F), 0.95F, 0.29F);
spawnPylon(PylonType.SoldierDefense, defendingFaction, "naboo", new Point3D(1875.03F, 12, 2522.12F), 0.93F, 0.36F);
spawnPylon(PylonType.SoldierDefense, defendingFaction, "naboo", new Point3D(1878.19F, 12, 2524.03F), 0.94F, 0.33F);
@@ -1426,7 +1466,6 @@ public class InvasionService implements INetworkDispatch {
spawnPylon(PylonType.SoldierPatrol, PatrolRoute.Dearic9 ,invadingFaction, "talus", 90, new Point3D(315.93475F, 42.105118F, -3551.3157F), 0.95F, -0.30F);
spawnPylon(PylonType.SoldierDefense, defendingFaction, "talus", new Point3D(410.98F, 6, -2988.05F), -0.69F, 0.71F);
spawnPylon(PylonType.SoldierDefense, defendingFaction, "talus", new Point3D(500, 6, -2954), -0.69F, 0.71F);
spawnPylon(PylonType.SoldierDefense, defendingFaction, "talus", new Point3D(548, 6, -2941), -0.69F, 0.71F);
@@ -1461,11 +1500,8 @@ public class InvasionService implements INetworkDispatch {
spawnPylon(PylonType.Turret, defendingFaction, "talus", new Point3D(344.91F, 6, -2741.06F), 1F, 0F);
spawnPylon(PylonType.Turret, defendingFaction, "talus", new Point3D(379.53F, 6, -2741.90F), 1F, 0F);
spawnPylon(PylonType.Turret, defendingFaction, "talus", new Point3D(362.86F, 6, -2754.18F), 1F, 0F);
// object/tangible/destructible/shared_gcw_rebel_turret.iff crashes the client, not fixable
}
public void spawnPylonsBestine(){
@@ -1473,10 +1509,10 @@ public class InvasionService implements INetworkDispatch {
spawnPylon(PylonType.Turret, defendingFaction, "tatooine", new Point3D(-1164.60F,12, -3643.42F), 0.42F, 0.9F);
spawnPylon(PylonType.Turret, defendingFaction, "tatooine", new Point3D(-1278.45F,12, -3615.71F), 0.41F, 0.9F);
spawnPylon(PylonType.Turret, defendingFaction, "tatooine", new Point3D(-1237.01F,12, -3640.84F), 0.89F, -0.44F);
spawnPylon(PylonType.Turret, defendingFaction, "tatooine", new Point3D(-1230.01F,12, -3647.99F), 0.89F, -0.44F);
spawnPylon(PylonType.Turret, defendingFaction, "tatooine", new Point3D(-1231.72F,12, -3646.87F), 0.89F, -0.44F);
spawnPylon(PylonType.Turret, defendingFaction, "tatooine", new Point3D(-1330.74F,12, -3678.19F), 0F, 1F);
spawnPylon(PylonType.Turret, defendingFaction, "tatooine", new Point3D(-1274.77F,12, -3572.47F), 0.28F, 0.95F);
spawnPylon(PylonType.Turret, defendingFaction, "tatooine", new Point3D(-1123.84F,12, -3727.56F), -0.17F, 0.98F);
spawnPylon(PylonType.Turret, defendingFaction, "tatooine", new Point3D(-1124.69F,8.89F, -3729.97F), -0.17F, 0.98F);
spawnPylon(PylonType.Turret, defendingFaction, "tatooine", new Point3D(-1156.16F,12, -3704.48F), 0.02F, 0.99F);
spawnPylon(PylonType.Turret, defendingFaction, "tatooine", new Point3D(-1108.44F,12, -3632.28F), 0.90F, 0.422F);
@@ -1607,7 +1643,7 @@ public class InvasionService implements INetworkDispatch {
defendingGeneral = (CreatureObject) NGECore.getInstance().staticService.spawnObject(generalTemplate, "talus", 0L, 480.071F, 6, -3006.851F, 1, 0);
}
if (defendingGeneral==null){
if (defendingGeneral==null || defendingGeneral.getTemplate()==null){
try {
throw new Exception();
} catch (Exception e) {
@@ -1615,14 +1651,20 @@ public class InvasionService implements INetworkDispatch {
e.printStackTrace();
}
}
defendingGeneralAlive = true;
defendingGeneralTask = scheduler.scheduleAtFixedRate(new Runnable() {
final Future<?>[] dgt = {null};
dgt[0] = defendingGeneralTask = scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
AIActor actor = (AIActor)defendingGeneral.getAttachment("AI");
if (actor.getCurrentState().getClass().equals(DeathState.class)){
defendingGeneralAlive = false;
Thread.yield();
dgt[0].cancel(false);
}
for (CreatureObject damager : actor.getDamageMap().keySet()){
if (damager.getOwnerId()>0){ // For pets doing damage
damager = (CreatureObject)core.objectService.getObject(damager.getOwnerId());
@@ -2104,6 +2146,7 @@ public class InvasionService implements INetworkDispatch {
AIActor actor = (AIActor)enemy.getAttachment("AI");
if (actor==null)
return;
actor.setLastPositionBeforeStateChange(enemy.getWorldPosition());
actor.addDefender(defendingGeneral);
}
}
@@ -2215,6 +2258,44 @@ public class InvasionService implements INetworkDispatch {
offensiveClonerList.add(cloner3);
}
private void spawnDemoralizedSoldier(int faction, Point3D pos, float qw, float qy){
String soldierTemplate = "rebel_invasion_demoralized_soldier";
if (faction==Factions.Imperial){
soldierTemplate = "imp_invasion_demoralized_soldier";
}
CreatureObject soldier = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(soldierTemplate, getInvasionPlanet(invasionLocation).getName(), 0L, pos.x, pos.y, pos.z, qw,0F,qy,0F,-1);
NGECore.getInstance().invasionService.registerDemoralizedSoldier(soldier);
}
private void spawnDisabledVehicle(int faction, Point3D pos, float qw, float qy){
String vehicleTemplate = "rebel_invasion_disabled_atxt";
if (faction==Factions.Imperial){
vehicleTemplate = "imp_invasion_disabled_atst";
}
CreatureObject vehicle = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(vehicleTemplate, getInvasionPlanet(invasionLocation).getName(), 0L, pos.x, pos.y, pos.z, qw,0F,qy,0F,-1);
vehicle.setPosture((byte) Posture.Incapacitated);
NGECore.getInstance().invasionService.registerDisabledVehicle(vehicle);
}
private void playVictoryMusic(int winnerFaction){
String audioTemplate = "sound/music_themequest_victory_rebel.snd";
if (winnerFaction==Factions.Imperial)
audioTemplate = "sound/music_themequest_victory_imperial.snd";
// Vector<CreatureObject> allPlayers = core.simulationService.getAllNearSameFactionPlayers(500,invasionLocationCenter, getInvasionPlanet(invasionLocation), getFactionName(winnerFaction));
// for (CreatureObject player : allPlayers) {
// if (player.getFaction().length() > 0 && player.getFactionStatus() > FactionStatus.OnLeave) {
// player.playMusic(audioTemplate);
// }
// }
Vector<CreatureObject> allPlayers = core.simulationService.getAllNearPlayers(500, getInvasionPlanet(invasionLocation), invasionLocationCenter);
for (CreatureObject player : allPlayers) {
player.playMusic(audioTemplate);
}
}
// Utility method
public void arrangePylons(Point3D center, int angle){
@@ -2262,6 +2343,17 @@ public class InvasionService implements INetworkDispatch {
return result;
}
private Set<Entry<Integer,CreatureObject>> getInvadingCreaturesEntrySet(){
synchronized(invadingCreatures){
return invadingCreatures.entrySet();
}
}
private Set<Entry<Integer,CreatureObject>> getDefendingCreaturesEntrySet(){
synchronized(defendingCreatures){
return defendingCreatures.entrySet();
}
}
public void setInvasionLocationCenter(){
@@ -2292,6 +2384,11 @@ public class InvasionService implements INetworkDispatch {
return "neutral";
}
public boolean isDefendingGeneralAlive() {
return defendingGeneralAlive;
}
@Override
public void shutdown() {