Merge pull request #1211 from CharonInferar/LairFixes

Several Fixes for lairs
This commit is contained in:
CharonInferar
2014-09-06 16:51:53 +02:00
5 changed files with 136 additions and 28 deletions
@@ -389,7 +389,7 @@ public class CreatureObject extends TangibleObject implements IPersistent {
}
public void setHeight(float height) {
height = (((height < 0.7) || (height > 1.5)) ? 1 : height);
// height = (((height < 0.7) || (height > 1.5)) ? 1 : height); Babies need height values smaller than that
notifyObservers(getBaseline(3).set("height", height), true);
}
+82 -8
View File
@@ -21,15 +21,24 @@
******************************************************************************/
package services.ai;
import java.util.Collections;
import java.util.Map;
import java.util.Random;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import engine.resources.scene.Point3D;
import main.NGECore;
import net.engio.mbassy.listener.Handler;
import resources.common.SpawnPoint;
import resources.datatables.Posture;
import resources.objects.creature.CreatureObject;
import resources.objects.tangible.TangibleObject;
import services.ai.states.RetreatState;
import services.combat.CombatEvents.DamageTaken;
import tools.DevLog;
@@ -45,11 +54,13 @@ public class LairActor {
private short level;
private String bossTemplate;
private boolean bossSpawned = false;
private Map<CreatureObject, Long> attackerMap = new ConcurrentHashMap<CreatureObject, Long>();
public LairActor(TangibleObject lairObject, String creatureTemplate) {
this.lairObject = lairObject;
this.creatureTemplate = creatureTemplate;
lairObject.getEventBus().subscribe(this);
checkAttackerTask();
}
public LairActor(TangibleObject lairObject, String creatureTemplate, int maxSpawns, short level) {
@@ -58,6 +69,7 @@ public class LairActor {
this.maxSpawns = maxSpawns;
this.level = level;
lairObject.getEventBus().subscribe(this);
checkAttackerTask();
}
public LairActor(TangibleObject lairObject, Vector<String> creatureTemplates, int maxSpawns, short level) {
@@ -66,6 +78,7 @@ public class LairActor {
this.maxSpawns = maxSpawns;
this.level = level;
lairObject.getEventBus().subscribe(this);
checkAttackerTask();
}
@@ -90,40 +103,55 @@ public class LairActor {
ai.addDefender((CreatureObject)event.attacker);
((CreatureObject)event.attacker).addDefender(ai.getCreature());
}
attackerMap.put(((CreatureObject)event.attacker), System.currentTimeMillis());
}
public void spawnNewCreatures() {
// remove dead creatures from collection
creatures.removeAll(Collections.singleton(null));
Vector<AIActor> removers = new Vector<AIActor>();
for (AIActor act : creatures){
if (act!=null ){
if (act.getCreature().getPosture()==Posture.Dead)
removers.add(act);
else if (lairObject.getPosition().getDistance2D(act.getCreature().getPosition())>80)
removers.add(act);
}
}
creatures.removeAll(removers);
if(creatures.size() >= maxSpawns)
return;
int currentCondition = lairObject.getConditionDamage();
int maxCondition = lairObject.getMaximumCondition();
//System.out.println("spawnWave " + spawnWave + " currentCondition " + currentCondition + " maxCondition " + maxCondition + "quot " + ((float)currentCondition / (float)maxCondition));
switch(spawnWave) {
// TODO: play damage effect
case 0:
spawnWave++;
break;
case 1:
if((currentCondition / maxCondition) < 0.7) {
if(((float)currentCondition / (float)maxCondition) < 0.7) {
spawnWave++;
break;
} else {
return;
}
case 2:
if((currentCondition / maxCondition) < 0.3) {
if(((float)currentCondition / (float)maxCondition) < 0.3) {
spawnWave++;
break;
} else {
return;
}
break;
case 3:
if (bossTemplate!=null && ! bossSpawned){
//CreatureObject boss = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(bossTemplate, lairObject.getPlanet().getName(), 0L, lairObject.getPosition().x + 3, lairObject.getPosition().y, lairObject.getPosition().z, lairObject.getOrientation().w, lairObject.getOrientation().x, lairObject.getOrientation().y,lairObject.getOrientation().z,-1);
CreatureObject boss = (CreatureObject)NGECore.getInstance().spawnService.spawnCreature(bossTemplate, lairObject.getPlanet().getName(), 0L, lairObject.getPosition().x + 3, lairObject.getPosition().y, lairObject.getPosition().z, lairObject.getOrientation().w, lairObject.getOrientation().x, lairObject.getOrientation().y,lairObject.getOrientation().z,-1);
bossSpawned = true;
break;
}
return;
@@ -138,7 +166,9 @@ public class LairActor {
creatureAmount = new Random().nextInt(4) + (maxSpawns / 5);
tries++;
}
while(creatureAmount > maxSpawns && tries < 10);
while(tries < 10);
//while(creatureAmount > maxSpawns && tries < 10);
for(int i = 0; i < creatureAmount; i++) {
Point3D position = SpawnPoint.getRandomPosition(lairObject.getPosition(), 5, 30, lairObject.getPlanetId());
@@ -211,4 +241,48 @@ public class LairActor {
public void setBossTemplate(String bossTemplate) {
this.bossTemplate = bossTemplate;
}
private void checkAttackerTask(){
final Future<?>[] fut1 = {null};
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
fut1[0] = scheduler.scheduleAtFixedRate(new Runnable() {
@Override public void run() {
try {
if (lairObject==null){
Thread.yield();
fut1[0].cancel(false);
} else {
int currentCondition = lairObject.getConditionDamage();
int maxCondition = lairObject.getMaximumCondition();
if (currentCondition>maxCondition){
Thread.yield();
fut1[0].cancel(false);
}
}
checkAttackers();
} catch (Exception e) {
System.err.println("Exception in checkAttackerTask->scheduleAtFixedRate->checkAttackers() " + e.getMessage());
}
}
}, 0, 10, TimeUnit.SECONDS);
}
private void checkAttackers(){
Map<CreatureObject, Long> attackerMapClone = new ConcurrentHashMap<CreatureObject, Long>(attackerMap);
for (CreatureObject attacker : attackerMapClone.keySet()) {
Long lastAttackTime = attackerMapClone.get(attacker);
if (attacker.getWorldPosition().getDistance2D(lairObject.getWorldPosition())>100 || System.currentTimeMillis()-lastAttackTime>10000)
removeDefender(attacker);
}
attackerMapClone = null;
}
private void removeDefender(TangibleObject defender) {
if (defender==null){
return;
}
lairObject.removeDefender(defender);
if (attackerMap.containsKey(defender)) attackerMap.remove(defender);
defender.removeDefender(lairObject);
}
}
+7 -2
View File
@@ -1533,8 +1533,13 @@ public class CombatService implements INetworkDispatch {
public boolean areInDuel(CreatureObject creature1, CreatureObject creature2) {
if(creature1.getDuelList().contains(creature2) && creature2.getDuelList().contains(creature1))
return true;
// Vehicles are going through this too, but dont have duellists, so null checks must be done or NPE
if (creature1.getDuelList()!=null && creature2.getDuelList()!=null) {
if(creature1.getDuelList().contains(creature2) && creature2.getDuelList().contains(creature1))
return true;
} else {
return false;
}
return false;
}
+27 -12
View File
@@ -35,6 +35,7 @@ import resources.common.collidables.AbstractCollidable.ExitEvent;
import resources.objects.creature.CreatureObject;
import services.TerrainService;
import services.SimulationService.MoveEvent;
import services.ai.AIActor;
import services.ai.LairActor;
import engine.resources.config.Config;
import engine.resources.objects.SWGObject;
@@ -213,13 +214,15 @@ public class MixedSpawnArea extends SpawnArea {
}
}
if (this.spawnGroup instanceof LairGroupTemplate){
object = event.object;
//if(object == null || !(object instanceof CreatureObject) || object.getContainer() != null)
// return;
if(object == null || !(object instanceof CreatureObject))
if(object == null || !(object instanceof CreatureObject)){
return;
}
creature = (CreatureObject) object;
@@ -386,23 +389,26 @@ public class MixedSpawnArea extends SpawnArea {
// LairSpawnArea class methods
public void spawnLair(CreatureObject object) {
NGECore core = NGECore.getInstance();
LairGroupTemplate lairGroup = (LairGroupTemplate)this.spawnGroup;
Vector<LairSpawnTemplate> lairTemplates = lairGroup.getLairSpawnTemplates();
if(lairGroup == null || lairTemplates.isEmpty())
if(lairGroup == null || lairTemplates.isEmpty()){
return;
}
if((System.currentTimeMillis() - lastSpawnTime) < 10000)
if((System.currentTimeMillis() - lastSpawnTime) < 10000){
return;
}
Point3D randomPosition = getRandomPosition(object.getWorldPosition(), 32.f, 200.f);
if(randomPosition == null)
if(randomPosition == null){
return;
}
TerrainService terrainSvc = core.terrainService;
@@ -410,29 +416,38 @@ public class MixedSpawnArea extends SpawnArea {
randomPosition.y = height;
for(LairActor otherLair : lairs) {
if(otherLair.getLairObject().getWorldPosition().getDistance(randomPosition) < 30)
if(otherLair.getLairObject().getWorldPosition().getDistance(randomPosition) < 30){
return;
}
}
if(!terrainSvc.canBuildAtPosition(object, randomPosition.x, randomPosition.z))
if(!terrainSvc.canBuildAtPosition(object, randomPosition.x, randomPosition.z)){
return;
}
Random random = new Random();
LairSpawnTemplate lairSpawn = lairTemplates.get(random.nextInt(lairTemplates.size()));
int level = -1; // If level equals -1 then the mobile template CL will be used!
if (lairSpawn.getMinLevel() != -1 && lairSpawn.getMaxLevel()!=-1)
level = random.nextInt((int) (lairSpawn.getMaxLevel() - lairSpawn.getMinLevel()) + 1) + lairSpawn.getMinLevel();
AIActor actor = (AIActor) object.getAttachment("AI");
if (actor!=null)
level = actor.getMobileTemplate().getLevel();
if (level<0)
level = 10;
LairActor lairActor = core.spawnService.spawnLair(lairSpawn.getLairTemplate(), getPlanet(), randomPosition, (short) level);
if(lairActor == null)
if(lairActor == null){
return;
}
lairs.add(lairActor);
lastSpawnTime = System.currentTimeMillis();
}
}
+19 -5
View File
@@ -459,18 +459,23 @@ public class SpawnService {
}
public LairActor spawnLair(String lairSpawnTemplate, Planet planet, Point3D position, short level) {
LairTemplate lairTemplate = lairTemplates.get(lairSpawnTemplate);
if(lairTemplate == null)
return null;
// adapt to terrain
float positionY = core.terrainService.getHeight(planet.getID(), position.x, position.z);
Point3D adaptedPosition = new Point3D(position.x, positionY, position.z);
TangibleObject lairObject = null;
if (lairTemplate.getLairCRC()==null){
String lairCRC = lairTemplate.getLairCRCs().get(new Random().nextInt(lairTemplate.getLairCRCs().size()));
System.out.println("Lair CRC " + lairCRC);
lairObject = (TangibleObject) core.objectService.createObject(lairCRC, 0, planet, position, new Quaternion(1, 0, 0, 0));
//System.out.println("Lair CRC " + lairCRC);
lairObject = (TangibleObject) core.objectService.createObject(lairCRC, 0, planet, adaptedPosition, new Quaternion(1, 0, 0, 0));
} else {
lairObject = (TangibleObject) core.objectService.createObject(lairTemplate.getLairCRC().trim(), 0, planet, position, new Quaternion(1, 0, 0, 0));
lairObject = (TangibleObject) core.objectService.createObject(lairTemplate.getLairCRC().trim(), 0, planet, adaptedPosition, new Quaternion(1, 0, 0, 0));
}
if(lairObject == null)
@@ -478,8 +483,17 @@ public class SpawnService {
lairObject.setOptionsBitmask(Options.ATTACKABLE);
lairObject.setPvpBitmask(PvpStatus.Attackable);
lairObject.setMaximumCondition(1000 * level);
if (lairTemplate.getMobiles()!=null){
MobileTemplate mobileTemplate = mobileTemplates.get(lairTemplate.getMobiles().get(0));
level = mobileTemplate.getLevel();
}
lairObject.setMaximumCondition(1000 * level);
LairActor lairActor = new LairActor(lairObject, lairTemplate.getMobileName(), 10, level);
if (lairTemplate.getMobiles()!=null)