package org.jslaughter.component.action;
import java.util.ArrayList;
import java.util.Collection;
import org.jslaughter.event.eventtype.DeathEvent;
import org.jslaughter.event.eventtype.DeathListener;
import org.nvframe.component.AbstractComponent;
import org.nvframe.component.state.Position;
import org.nvframe.entity.Entity;
import org.nvframe.event.EventService;
import org.nvframe.event.eventtype.UpdateEvent;
import org.nvframe.event.eventtype.UpdateListener;
import org.nvframe.exception.NVFrameException;
import org.nvframe.factory.EntityFactory;
import org.nvframe.util.settings.SettingsObj;
/**
*
* @author Nik Van Looy
*/
public class SpawnAction extends AbstractComponent implements DeathListener, UpdateListener {
private final int minSpawnDelayMs;
private final int maxSpawnDelayMs;
private final int maxSimultaneousSpawns;
private final int maxActiveSpawns;
private final int offset;
private final String entityId;
private final boolean copyPosition;
private float spawnTimer;
private float nextSpawnDelayMs;
private Collection<Entity> activeSpawns;
public SpawnAction(String id, Entity owner, SettingsObj settings) throws NVFrameException {
super(id, owner);
if(!settings.containsKey("entityId"))
throw new NVFrameException("cannot spawn entity withouth an entityId");
entityId = settings.getString("entityId");
minSpawnDelayMs = settings.getInt("minSpawnDelayMs", 1000);
maxSpawnDelayMs = settings.getInt("maxSpawnDelayMs", 4000);
maxSimultaneousSpawns = settings.getInt("maxSimultaneousSpawns", 1);
maxActiveSpawns = settings.getInt("maxActiveSpawns", 1);
copyPosition = settings.getBoolean("copyPosition", false);
offset = settings.getInt("offset", 20);
activeSpawns = new ArrayList<Entity>();
spawnTimer = 0;
nextSpawnDelayMs = calculateSpawnDelay();
EventService.getInstance().addEventListener(this);
}
public float calculateSpawnDelay() {
return (float) ((Math.random() * (maxSpawnDelayMs - minSpawnDelayMs)) + minSpawnDelayMs);
}
private void spawnEntity() throws NVFrameException {
Entity entity = EntityFactory.getInstance().getEntityFromPrototype(entityId);
Position position = (Position) entity.getComponent(Position.class);
if(position == null)
throw new NVFrameException("cannot set spawn position, entity: " + entityId);
determineSpawnPosition(entity, position);
activeSpawns.add(entity);
}
private void determineSpawnPosition(Entity entity, Position position) {
Position ownerPosition = (Position) owner.getComponent(Position.class);
if(!copyPosition) {
// random direction
float direction = (float) ((Math.random() * 360) + 1);
position.setX(ownerPosition.getX() + (float) (Math.cos(Math.toRadians(direction)) * offset));
position.setY(ownerPosition.getY() + (float) (Math.sin(Math.toRadians(direction)) * offset));
position.setDirection(direction);
}
else {
position.setXY(ownerPosition.getXY());
position.setDirection(ownerPosition.getDirection());
}
}
@Override
public void onUpdate(UpdateEvent event) {
int delta = event.getDelta();
if(activeSpawns.size() >= maxActiveSpawns) {
spawnTimer = 0;
return;
}
spawnTimer += delta;
if (spawnTimer > nextSpawnDelayMs) {
spawnTimer = 0;
nextSpawnDelayMs = calculateSpawnDelay();
// spawn the entity / entities
try {
for(int i = 0; i < maxSimultaneousSpawns; i++) {
if(activeSpawns.size() < maxActiveSpawns)
spawnEntity();
}
} catch (NVFrameException e) {
e.printStackTrace();
}
}
}
@Override
public void onDeath(DeathEvent event) {
Entity entity = event.getEntity();
if(activeSpawns.contains(entity))
activeSpawns.remove(entity);
}
}
|