package snakemeleon.types;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.List;
import org.jbox2d.callbacks.ContactImpulse;
import org.jbox2d.callbacks.ContactListener;
import org.jbox2d.collision.Manifold;
import org.jbox2d.dynamics.contacts.Contact;
import org.jbox2d.dynamics.joints.Joint;
import snakemeleon.Snakemeleon;
import snakemeleon.SnakemeleonConstants;
import toritools.debug.Debug;
import toritools.entity.Entity;
import toritools.entity.Level;
import toritools.scripting.EntityScript.EntityScriptAdapter;
import toritools.scripting.ScriptUtils;
/**
* This script allows the chameleon to stick to things! Make sure to add it
* after the entity is added to the physics world, so it can apply the direction
* negation. It also has the necessary stuff to handle contact detection.
*
* @author toriscope
*
*/
public class ChameleonStickyScript extends EntityScriptAdapter {
public static boolean isGrabbing = false;
public static Entity grabbingEntity = null;
private List<Entity> touchQueue = new LinkedList<Entity>();
Joint weld = null;
@Override
public void onSpawn(Entity self, Level level) {
isGrabbing = false;
grabbingEntity = null;
Snakemeleon.uni.addContactListener(new ContactListener() {
@Override
public void beginContact(Contact c) {
Entity a = (Entity) c.m_fixtureA.m_userData, b = (Entity) c.m_fixtureB.m_userData;
boolean playerisA = ((Entity) c.m_fixtureA.m_userData).getType().equals("player");
boolean playerisB = ((Entity) c.m_fixtureB.m_userData).getType().equals("player");
if (playerisA && b.getType().equals(SnakemeleonConstants.dynamicPropType)) {
touchQueue.add(b);
} else if (playerisB && a.getType().equals(SnakemeleonConstants.dynamicPropType)) {
touchQueue.add(a);
}
}
@Override
public void endContact(Contact c) {
Entity a = (Entity) c.m_fixtureA.m_userData, b = (Entity) c.m_fixtureB.m_userData;
boolean playerisA = ((Entity) c.m_fixtureA.m_userData).getType().equals("player");
boolean playerisB = ((Entity) c.m_fixtureB.m_userData).getType().equals("player");
if (playerisA && b.getType().equals(SnakemeleonConstants.dynamicPropType)) {
touchQueue.remove(b);
} else if (playerisB && a.getType().equals(SnakemeleonConstants.dynamicPropType)) {
touchQueue.remove(a);
}
}
@Override
public void postSolve(Contact arg0, ContactImpulse arg1) {
}
@Override
public void preSolve(Contact arg0, Manifold arg1) {
}
});
self.addScript(new EntityScriptAdapter() {
@Override
public void onUpdate(Entity self, float time, Level level) {
if (!isGrabbing)
self.setDirection(0);
}
});
}
@Override
public void onUpdate(Entity self, float time, Level level) {
boolean grabKey = ScriptUtils.getKeyHolder().isPressed(KeyEvent.VK_SPACE) || Snakemeleon.rightSticking;
// Activate weld
if (grabKey && !isGrabbing && !touchQueue.isEmpty()) {
Snakemeleon.uni.setRotationDeg(self, 0);
weld = Snakemeleon.uni.addWeld(self, grabbingEntity = touchQueue.get(0));
isGrabbing = true;
Debug.print("Joint created");
}
// Destroy weld
if (!grabKey && isGrabbing && weld != null) {
Snakemeleon.uni.destroyJoint(weld);
isGrabbing = false;
Debug.print("Joint Destroyed");
grabbingEntity = null;
}
}
}