package propra2012.gruppe33.bomberman.graphics.rendering.scenegraph.grid.items;
import java.util.Deque;
import java.util.EnumMap;
import java.util.LinkedList;
import java.util.Map;
import propra2012.gruppe33.bomberman.GameConstants;
import propra2012.gruppe33.bomberman.GameRoutines;
import propra2012.gruppe33.bomberman.graphics.rendering.scenegraph.grid.input.GridRemoteInput;
import propra2012.gruppe33.bomberman.graphics.rendering.scenegraph.grid.input.Input;
import propra2012.gruppe33.bomberman.graphics.rendering.scenegraph.grid.items.bomb.Bomb;
import propra2012.gruppe33.bomberman.graphics.rendering.scenegraph.grid.items.bomb.BombDesc;
import propra2012.gruppe33.bomberman.graphics.rendering.scenegraph.grid.items.spawners.PalisadeDesc;
import propra2012.gruppe33.bomberman.graphics.rendering.scenegraph.grid.items.spawners.SpawnPalisade;
import propra2012.gruppe33.bomberman.graphics.rendering.scenegraph.grid.items.spawners.SpawnShield;
import propra2012.gruppe33.bomberman.graphics.rendering.scenegraph.grid.movement.GridMovement;
import com.indyforge.foxnet.rmi.Invoker;
import com.indyforge.foxnet.rmi.pattern.change.Session;
import com.indyforge.twod.engine.graphics.rendering.scenegraph.Entity;
import com.indyforge.twod.engine.graphics.rendering.scenegraph.GraphicsEntity;
import com.indyforge.twod.engine.graphics.rendering.scenegraph.Scene;
import com.indyforge.twod.engine.graphics.rendering.scenegraph.SceneProcessor;
import com.indyforge.twod.engine.graphics.rendering.scenegraph.Text;
import com.indyforge.twod.engine.graphics.rendering.scenegraph.network.input.InputChange;
/**
*
* @author Christopher Probst
*
*/
public final class ItemSpawner extends GraphicsEntity implements GameConstants {
/**
*
*/
private static final long serialVersionUID = 1L;
// The collectable items
private final Map<CollectableItem, Integer> items = new EnumMap<CollectableItem, Integer>(
CollectableItem.class);
// The collectable spawn items
private final Map<CollectableItem, Boolean> spawnItems = new EnumMap<CollectableItem, Boolean>(
CollectableItem.class);
// The input queue!
private final Deque<Map<Input, Boolean>> inputQueue = new LinkedList<Map<Input, Boolean>>();
/*
* (non-Javadoc)
*
* @see
* com.indyforge.twod.engine.graphics.rendering.scenegraph.Entity#onEvent
* (com.indyforge.twod.engine.graphics.rendering.scenegraph.Entity,
* java.lang.Object, java.lang.Object[])
*/
@SuppressWarnings("unchecked")
@Override
protected void onEvent(Entity source, Object event, Object... params) {
super.onEvent(source, event, params);
if (event == InputChange.class) {
// The input map
Map<Input, Boolean> input = (Map<Input, Boolean>) params[0];
// Offer next input
inputQueue.offer(input);
}
}
public ItemSpawner() {
// Set item counters
items.put(CollectableItem.DefaultBomb, 1);
items.put(CollectableItem.NukeBomb, 0);
items.put(CollectableItem.FastBomb, 0);
items.put(CollectableItem.Palisade, 0);
items.put(CollectableItem.ShieldPotion, 0);
items.put(CollectableItem.Speed, START_SPEED_ITEMS);
spawnItems.put(CollectableItem.DefaultBomb, Boolean.FALSE);
spawnItems.put(CollectableItem.NukeBomb, Boolean.FALSE);
spawnItems.put(CollectableItem.FastBomb, Boolean.FALSE);
spawnItems.put(CollectableItem.Palisade, Boolean.FALSE);
spawnItems.put(CollectableItem.ShieldPotion, Boolean.FALSE);
spawnItems.put(CollectableItem.Speed, Boolean.FALSE);
}
public float speedPercentage() {
return items.get(CollectableItem.Speed) / (float) START_SPEED_ITEMS;
}
/**
* @return the item map.
*/
public Map<CollectableItem, Integer> items() {
return items;
}
public ItemSpawner removeItems(CollectableItem item, int count,
boolean playSound) {
return addItems(item, -count, playSound);
}
public ItemSpawner addItems(final CollectableItem item, final int count,
boolean playSound) {
int value = items.get(item) + count;
items.put(item, value < 0 ? 0 : value);
// Find the scene processor
SceneProcessor proc = findSceneProcessor();
/*
* Server running ??
*/
if (proc.hasAdminSessionServer()) {
// Create item count sync
SyncItemCount syncItemCount = new SyncItemCount();
syncItemCount.item(item).playSound(playSound)
.count(items.get(item)).entities().add(registrationKey());
// Get session
Session<SceneProcessor> session = proc.adminSessionServer()
.session(Long.parseLong(parent().name()));
// If session exists...
if (session != null) {
Invoker.of(session.client()).invoke("applyChange",
syncItemCount);
}
}
return this;
}
/*
* (non-Javadoc)
*
* @see
* com.indyforge.twod.engine.graphics.rendering.scenegraph.Entity#onUpdate
* (float)
*/
@Override
protected void onUpdate(float tpf) {
super.onUpdate(tpf);
// Get the scene
Scene scene = findScene();
// Input/server-less entities will be ignored!
if ((parent().typeProp(GridRemoteInput.class) == null && scene
.processor().hasSession())) {
return;
}
/*
* Update item counts!
*/
for (CollectableItem item : CollectableItem.values()) {
// Set the text of the gui
scene.prop(item, Text.class).text(items.get(item).toString());
}
// Poll next
Map<Input, Boolean> input = inputQueue.poll();
// Process NOW
if (input != null) {
// Parse the input
spawnItems.put(CollectableItem.DefaultBomb,
input.get(Input.PlaceDefaultBomb));
spawnItems.put(CollectableItem.NukeBomb,
input.get(Input.PlaceNukeBomb));
spawnItems.put(CollectableItem.FastBomb,
input.get(Input.PlaceFastBomb));
spawnItems.put(CollectableItem.Palisade,
input.get(Input.PlacePalisade));
spawnItems.put(CollectableItem.ShieldPotion,
input.get(Input.ActivateShield));
}
// Get parent
GraphicsEntity node = ((GraphicsEntity) parent().parent());
// Collect spawn requests
int defBomb = spawnItems.get(CollectableItem.DefaultBomb) ? 1 : 0, nukeBomb = spawnItems
.get(CollectableItem.NukeBomb) ? 1 : 0, fastBomb = spawnItems
.get(CollectableItem.FastBomb) ? 1 : 0, pali = spawnItems
.get(CollectableItem.Palisade) ? 1 : 0;
// The item...
CollectableItem item;
if (defBomb + nukeBomb + fastBomb + pali == 1) {
if (pali == 0) {
if (nukeBomb == 1) {
item = CollectableItem.NukeBomb;
} else if (fastBomb == 1) {
item = CollectableItem.FastBomb;
} else {
item = CollectableItem.DefaultBomb;
}
// Bombable ?
if (GameRoutines.isFieldBombable(node)
// Spawn ?
&& spawnItems.get(item)
// Enough bombs ?
&& items.get(item) > 0) {
// Create bomb for the given field
Bomb bomb = new Bomb();
bomb.entities().add(node.registrationKey());
bomb.value((BombDesc) new BombDesc()
.player(parent().registrationKey())
.delay(GameRoutines.bombDelay(item))
.range(GameRoutines.bombRange(item)).item(item)
.randomItemEntity());
// Apply global change
node.findSceneProcessor().adminSessionServer().composite()
.queueChange(bomb, true);
// Clean up
removeItems(item, 1, true);
spawnItems.put(item, false);
}
} else {
item = CollectableItem.Palisade;
// Bombable (Pali...) ?
if (GameRoutines.isFieldBombable(node)
// Spawn ?
&& spawnItems.get(item)
// Enough items ?
&& items.get(item) > 0) {
// Create new spawn-paliside request
SpawnPalisade sp = new SpawnPalisade();
sp.entities().add(node.registrationKey());
// Set the nearest direction
sp.value((PalisadeDesc) new PalisadeDesc()
.direction(
parent().typeProp(GridMovement.class)
.direction().vector().swapLocal()
.nearestDirection()).item(item)
.randomItemEntity());
// Apply global change
node.findSceneProcessor().adminSessionServer().composite()
.queueChange(sp, true);
// Clean up
removeItems(item, 1, true);
spawnItems.put(item, false);
}
}
}
/*
* The shield potion.
*/
if (spawnItems.get(CollectableItem.ShieldPotion)
&& items.get(CollectableItem.ShieldPotion) > 0) {
// Add the node
SpawnShield ss = new SpawnShield();
ss.entities().add(parent().registrationKey());
// Register the item
ss.value(new ItemDesc().randomItemEntity().item(
CollectableItem.ShieldPotion));
// Apply global change
node.findSceneProcessor().adminSessionServer().composite()
.queueChange(ss, true);
// Clean up
removeItems(CollectableItem.ShieldPotion, 1, true);
spawnItems.put(CollectableItem.ShieldPotion, false);
}
}
}