package com.pointcliki.dizgruntled.logic;
import java.util.AbstractSet;
import java.util.ArrayList;
import org.json.JSONException;
import org.json.JSONObject;
import org.newdawn.slick.geom.Vector2f;
import com.pointcliki.core.Sprite;
import com.pointcliki.dizgruntled.EffectManager.TriggerEvent;
import com.pointcliki.dizgruntled.GruntzGame;
import com.pointcliki.dizgruntled.InvisibleLogic;
import com.pointcliki.dizgruntled.LogicProperty;
import com.pointcliki.dizgruntled.PressureManager.PressureEvent;
import com.pointcliki.dizgruntled.StringLogicProperty;
import com.pointcliki.dizgruntled.map.Map;
import com.pointcliki.dizgruntled.rez.MonolithPID;
import com.pointcliki.dizgruntled.rez.MonolithWWD;
import com.pointcliki.event.Dispatcher;
import com.pointcliki.event.FrameEvent;
import com.pointcliki.event.Minion;
import com.pointcliki.grid.GridManager.GridEvent;
public class Cause extends InvisibleLogic {
/**
* Serial Key
*/
private static final long serialVersionUID = -6581217004990827025L;
public static final String[] MODES = new String[] {"Switch", "Timer"};
private static String[] ITEMS;
private int fMode = 0;
private String fGroup;
private String[] fSiblings = new String[]{};
private int fItem = 0;
private boolean fPressed = false;
private boolean fEnabled = true;
@Override
public void importFromWWD(String logic, String image, String animation, byte[] data) {
super.importFromWWD(logic, image, animation, data);
Sprite sprite = new Sprite(GruntzGame.resourceManager().spritesheet("editor/logics", 17, 17));
sprite.subimage(1, 1);
addChild(sprite);
// Get group
fGroup = "#" + MonolithWWD.readID(data);
// Get sibling groups
ArrayList<String> groups = new ArrayList<String>();
for (int i = 0; i < 24; i++) {
int r = MonolithWWD.readRect(data, i);
if (r > 0) groups.add("#" + r);
}
// Get item if any
fItem = MonolithWWD.readSmarts(data);
fSiblings = groups.toArray(new String[groups.size()]);
}
@Override
public byte[] exportToWWD() {
return null;
}
@Override
public void importFromJSON(JSONObject object) {
super.importFromJSON(object);
Sprite sprite = new Sprite(GruntzGame.resourceManager().spritesheet("editor/logics", 17, 17));
sprite.subimage(1, 1);
addChild(sprite);
fMode = object.optInt("mode");
fGroup = object.optString("group");
fItem = object.optInt("item", 0);
fSiblings = object.optString("siblings", "").split(" ");
}
private String siblingString() {
StringBuilder sb = new StringBuilder("");
for (String s: fSiblings) sb.append(s + " ");
if (sb.length() == 0) return sb.toString();
return sb.substring(0, sb.length() - 1);
}
@Override
public JSONObject exportToJSON() throws JSONException {
JSONObject obj = super.exportToJSON();
obj.put("mode", fMode);
obj.put("group", fGroup);
if (fSiblings.length > 0) obj.put("siblings", siblingString());
if (fItem > 0) obj.put("item", fItem);
return obj;
}
@Override
public void init(Map map) {
super.init(map);
if (ITEMS == null) {
ITEMS = new String[33];
for (int i = 0; i < 23; i++) ITEMS[i] = Grunt.TOOLS[i];
for (int i = 23; i < 33; i++) ITEMS[i] = Grunt.TOYS[i - 23];
}
// Check for switch
if (!map.editing() && fMode == 0) {
order(-1000);
AbstractSet<String> traits = map.traits(fTile);
// Check for initially pressed
if (traits.contains("lowSwitch"))
fPressed = true;
// Go up if sibling orange switch pressed
if (traits.contains("orangeSwitch")) {
Minion<TriggerEvent> minion = new Minion<TriggerEvent>() {
public long run(Dispatcher<TriggerEvent> dispatcher, String type, TriggerEvent event) {
// Go up
if (!event.on() && fPressed) {
// Toggle tile
map().tileToggle(fTile);
fPressed = false;
}
return Minion.CONTINUE;
};
};
effectManager().dispatcher().addMinion(fGroup, minion);
}
// Check for checkpoint
if (traits.contains("checkpointSwitch")) {
effectManager().setCheckpointGroup(fGroup);
if (fItem > 0) {
MonolithPID pid;
if (fItem == 20) pid = new MonolithPID(GruntzGame.resourceManager().rez().file("GAME/IMAGEZ/INGAMEICONZ/TOOLZ/WARPSTONEZ3/FRAME001", "pid"));
else if (fItem < 23) pid = new MonolithPID(GruntzGame.resourceManager().rez().file("GAME/IMAGEZ/INGAMEICONZ/TOOLZ/" + Grunt.TOOLS[fItem] + "/FRAME001", "pid"));
else pid = new MonolithPID(GruntzGame.resourceManager().rez().file("GAME/IMAGEZ/INGAMEICONZ/TOYZ/" + Grunt.TOYS[fItem - 23] + "/FRAME001", "pid"));
Sprite sp = new Sprite(pid.image());
sp.scale(0.5f).position(new Vector2f(10, 10));
addChild(sp);
}
}
// Add pressure change monitor
gridManager().dispatcher().addGridMinion(fTile, "pressure", new Minion<GridEvent>() {
@Override
public long run(Dispatcher<GridEvent> dispatcher, String type, GridEvent event) {
if (event instanceof PressureEvent) activity(((PressureEvent) event).pressure());
return Minion.CONTINUE;
}
});
// Mark as a stateful tile
map().markStatefulTile(fTile);
}
}
private void activity(int pressure) {
AbstractSet<String> traits = map().traits(fTile);
// Check for depressed
if (pressure > 0) {
if (fPressed) return;
// Check that the tile really is a switch
if (!traits.contains("switch")) return;
// Toggle tile
if (!map().tileToggle(fTile)) {
System.err.println("Couldn't toggle tile " + fTile);
return;
}
fPressed = true;
if (allowGrunt()) on();
if (traits.contains("timeSwitch")) {
int delay = effectManager().timeDelayForGroup(fGroup);
if (delay > 0) {
frameManager().queue(new Minion<FrameEvent>() {
public long run(Dispatcher<FrameEvent> dispatcher, String type, FrameEvent event) {
fEnabled = true;
// If walked off then flip up again
if (pressureManager().getTilePressureAt(fTile) == 0) {
// Toggle tile
map().tileToggle(fTile);
fPressed = false;
}
return Minion.FINISH;
};
}, (long) Math.ceil(timeManager().frameDuration(delay)));
fEnabled = false;
}
}
// Check for orange switch
if (traits.contains("orangeSwitch")) {
for (String group: fSiblings) {
if (!group.equals(fGroup)) effectManager().triggerOff(group);
}
}
// Check for secret switch
if (traits.contains("secretSwitch")) {
fEnabled = false;
GruntzGame.resourceManager().playSound("GAME/SOUNDZ/SECRETSWITCH");
}
} else if (fPressed) {
// Check that the tile really is a low switch
if (!traits.contains("lowSwitch")) return;
if (effectManager().checkpointReached(fGroup) || !fEnabled) return;
// Don't go up if an orange switch
if (traits.contains("orangeSwitch")) return;
// Toggle tile
if (!map().tileToggle(fTile)) return;
fPressed = false;
// Only trigger if grunt is allowed
if (allowGrunt()) {
// Check for many switch
if (traits.contains("manySwitch")) off();
else if (traits.contains("holdSwitch")) off();
}
}
}
protected boolean allowGrunt() {
if (fItem == 0) return true;
Grunt g = gridManager().getFirstEntityOfTypeAt(fTile, Grunt.class);
if (fItem < 23) {
return fItem == g.toolID();
} else {
return fItem == g.toyID();
}
}
protected void on() {
effectManager().triggerOn(fGroup);
}
protected void off() {
effectManager().triggerOff(fGroup);
}
@Override
public void initProperties() {
fProperties = new LogicProperty[] {
new StringLogicProperty("mode") {
@Override
public String description() {
return "The mode of the cause";
}
@Override
public String value() {
return MODES[fMode];
}
@Override
public String[] choices() {
return MODES;
}
@Override
public void choice(int i) {
fMode = i;
}
},
new StringLogicProperty("group") {
@Override
public String description() {
return "The group of the cause";
}
@Override
public String value() {
return fGroup;
}
@Override
public String[] choices() {
return null;
}
@Override
public void value(String s) {
fGroup = s;
}
},
new StringLogicProperty("siblings") {
@Override
public String description() {
return "The siblings of the cause";
}
@Override
public String value() {
return siblingString();
}
@Override
public String[] choices() {
return null;
}
@Override
public void value(String s) {
fSiblings = s.split(" ");
}
},
new StringLogicProperty("item") {
@Override
public String description() {
return "The requisite item for the cause";
}
@Override
public String value() {
return ITEMS[fItem];
}
@Override
public String[] choices() {
return ITEMS;
}
@Override
public void choice(int i) {
fItem = i;
}
}
};
}
@Override
public String name() {
return "Cause";
}
}