|
@@ -1,208 +1,225 @@
|
|
|
package me.hammerle.supersnuvi.entity.components.ai;
|
|
|
|
|
|
+import me.hammerle.snuviengine.api.Shader;
|
|
|
+import me.hammerle.snuviengine.api.Texture;
|
|
|
import me.hammerle.supersnuvi.entity.Entity;
|
|
|
import me.hammerle.supersnuvi.tiles.Location;
|
|
|
-import me.hammerle.supersnuvi.tiles.Tile;
|
|
|
import me.hammerle.supersnuvi.util.Face;
|
|
|
-import me.hammerle.supersnuvi.util.SoundUtils;
|
|
|
+import me.hammerle.supersnuvi.util.Utils;
|
|
|
|
|
|
public class LondonerController extends Controller
|
|
|
{
|
|
|
- private boolean combatMode = false;
|
|
|
- private int combatTimer = 0;
|
|
|
- private int attackTimer = -1;
|
|
|
- private int attackCooldown = -1;
|
|
|
- private int dashTimer = -1;
|
|
|
-
|
|
|
- private final float motion = 1.5f;
|
|
|
+ private final static Texture LONDONER = new Texture("resources/londoner.png");
|
|
|
|
|
|
private final boolean evil;
|
|
|
|
|
|
- private boolean jump = false;
|
|
|
+ private float ox = 0.0f;
|
|
|
+ private float tx = 0.0f;
|
|
|
+ private float ty = 0.0f;
|
|
|
+
|
|
|
+ private int walkFrame = 0;
|
|
|
+ private int transformFrame = -1;
|
|
|
+ private int deathCounter = 0;
|
|
|
+ private int deathFrame = 0;
|
|
|
|
|
|
+ private Face direction = Face.LEFT;
|
|
|
+
|
|
|
public LondonerController(Entity ent, boolean evil)
|
|
|
{
|
|
|
super(ent);
|
|
|
this.evil = evil;
|
|
|
}
|
|
|
- /*
|
|
|
- @Override
|
|
|
- public boolean isInCombatMode()
|
|
|
- {
|
|
|
- return combatMode || combatTimer < 0;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean isEvil()
|
|
|
- {
|
|
|
- return isInCombatMode();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int getCombatTimer()
|
|
|
- {
|
|
|
- return combatTimer;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean isAttacking()
|
|
|
+
|
|
|
+ private boolean hasRedEyes()
|
|
|
{
|
|
|
- return attackTimer >= 0;
|
|
|
+ return transformFrame >= 3;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@Override
|
|
|
- public boolean isDashing()
|
|
|
+ public boolean isAnimated()
|
|
|
{
|
|
|
- return dashTimer != -1;
|
|
|
+ return deathFrame < 7;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@Override
|
|
|
public void tick()
|
|
|
{
|
|
|
- if(ent.getHealth().isDead())
|
|
|
+ if(evil)
|
|
|
{
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if(!combatMode)
|
|
|
- {
|
|
|
- if(evil)
|
|
|
+ if(transformFrame != -1)
|
|
|
{
|
|
|
- Entity hero = ent.getLevel().getHero();
|
|
|
- if(hero.squaredDistance(ent) <= 65536)
|
|
|
+ if(transformFrame < 3)
|
|
|
{
|
|
|
- ent.setMotionX(0.0f);
|
|
|
- combatMode = true;
|
|
|
- combatTimer = ent.getAnimator().getCombatStartTicks() - 1;
|
|
|
+ ox = ent.getFace() == Face.RIGHT ? 0.0f: -36.0f;
|
|
|
+ tx = transformFrame * 0.125f + 0.125f;
|
|
|
+ ty = 0.375f;
|
|
|
+ transformFrame++;
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
- applyMotion();
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if(combatTimer > 0)
|
|
|
- {
|
|
|
- combatTimer--;
|
|
|
- return;
|
|
|
+ else if(ent.getLevel().getHero().getSquaredDistance(ent) <= 16384) // 4 Tiles
|
|
|
+ {
|
|
|
+ transformFrame = 0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- if(attackCooldown > 0)
|
|
|
+ if(ent.getHealth().isDead())
|
|
|
{
|
|
|
- attackCooldown--;
|
|
|
+ ox = ent.getFace() == Face.RIGHT ? -32.0f: -4.0f;
|
|
|
+
|
|
|
+ tx = deathFrame * 0.125f;
|
|
|
+ ty = hasRedEyes() ? 0.125f : 0.25f;
|
|
|
+
|
|
|
+ walkFrame = 0;
|
|
|
+ deathCounter++;
|
|
|
+ if(deathCounter >= 3)
|
|
|
+ {
|
|
|
+ deathCounter = 0;
|
|
|
+ deathFrame++;
|
|
|
+ }
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- if(attackTimer != -1)
|
|
|
+ if(hasRedEyes())
|
|
|
{
|
|
|
- attackTimer++;
|
|
|
- if(attackTimer >= ent.getAnimator().getAttackTicks())
|
|
|
+ float hx = ent.getLevel().getHero().getCenterX();
|
|
|
+ if(hx < ent.getCenterX())
|
|
|
{
|
|
|
- attackTimer = -1;
|
|
|
- float sign = ent.getAnimator().drawImageFlipped() ? -1 : 1;
|
|
|
- float extend = sign * Tile.SIZE;
|
|
|
- boolean once = true;
|
|
|
- for(Entity e : ent.getLevel().getEntitiesCollidingWith(ent, ent.getBox().expand(extend, 0)))
|
|
|
- {
|
|
|
- if(e.getController().isAttacking() && once)
|
|
|
- {
|
|
|
- once = false;
|
|
|
- ent.setMotionX(-sign * 7);
|
|
|
- e.setMotionX(sign * 7);
|
|
|
- }
|
|
|
- else if(!e.getController().isBlocking())
|
|
|
- {
|
|
|
- e.getHealth().addHealth(-14.2857);
|
|
|
- }
|
|
|
- }
|
|
|
+ ent.setMotionX(-ent.getMovement().getVelocityX());
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ent.setMotionX(ent.getMovement().getVelocityX());
|
|
|
}
|
|
|
- return;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- Entity hero = ent.getLevel().getHero();
|
|
|
- float distance = hero.signedDistanceX(ent);
|
|
|
- if(Math.abs(distance) < (Tile.SIZE >> 1))
|
|
|
+ if(direction == Face.LEFT)
|
|
|
{
|
|
|
- if(attackCooldown > 0)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- attackTimer = 0;
|
|
|
- attackCooldown = ent.getAnimator().getAttackTicks() * 4;
|
|
|
- ent.getAnimator().setFlipped(distance < 0);
|
|
|
- return;
|
|
|
+ ent.setMotionX(-ent.getMovement().getVelocityX());
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ent.setMotionX(ent.getMovement().getVelocityX());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if(dashTimer != -1)
|
|
|
+ ox = ent.getFace() == Face.RIGHT ? 0.0f: -36.0f;
|
|
|
+
|
|
|
+ if(ent.isOnGround())
|
|
|
{
|
|
|
- dashTimer++;
|
|
|
- if(dashTimer > 15)
|
|
|
+ if(ent.getMotionX() == 0.0f)
|
|
|
{
|
|
|
- dashTimer = -1;
|
|
|
- ent.setMotionX(0.0f);
|
|
|
+ tx = 0.875f;
|
|
|
+ ty = hasRedEyes() ? 0.25f : 0.375f;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- ent.setMotionX(ent.getAnimator().drawImageFlipped() ? -15 : 15);
|
|
|
+ deathFrame = 0;
|
|
|
+ walkFrame = (walkFrame + 1) % 6;
|
|
|
+ tx = walkFrame * 0.125f;
|
|
|
+ ty = hasRedEyes() ? 0.5f : 0.625f;
|
|
|
}
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- applyMotion();
|
|
|
- }
|
|
|
-
|
|
|
- private void applyMotion()
|
|
|
- {
|
|
|
- if(motion > Math.abs(ent.getMotionX()))
|
|
|
- {
|
|
|
- ent.setMotionX(ent.getAnimator().drawImageFlipped() ? -motion : motion);
|
|
|
}
|
|
|
- if(jump)
|
|
|
+ else
|
|
|
{
|
|
|
- SoundUtils.playSound(SoundUtils.Sound.LONDONER_JUMP);
|
|
|
- ent.getMovement().jump();
|
|
|
- jump = false;
|
|
|
+ deathFrame = 0;
|
|
|
+ walkFrame = 0;
|
|
|
+ tx = 0.125f;
|
|
|
+ ty = hasRedEyes() ? 0.5f : 0.625f;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public void onCollideWithEntity(Entity ent, Face face)
|
|
|
+ public void renderTick(float lag)
|
|
|
{
|
|
|
- if(ent.getMovement().useCollisionBox())
|
|
|
+ if(ent.getHealth().wasHurt())
|
|
|
{
|
|
|
- switchDirection(face);
|
|
|
+ Shader.setColorEnabled(true);
|
|
|
+ Shader.setMixColorEnabled(true);
|
|
|
+ Shader.setMixColor(1.0f, 0.0f, 0.0f, 1.0f);
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onCollideWithTile(Location loc, Face face)
|
|
|
- {
|
|
|
- if(loc.getTile().shouldAiUseCollisionBox(loc.getX(), loc.getY()))
|
|
|
+ if(ent.getHealth().wasHealed())
|
|
|
+ {
|
|
|
+ Shader.setColorEnabled(true);
|
|
|
+ Shader.setMixColorEnabled(true);
|
|
|
+ Shader.setMixColor(0.0f, 1.0f, 0.0f, 1.0f);
|
|
|
+ }
|
|
|
+
|
|
|
+ LONDONER.bind();
|
|
|
+ float x = Utils.interpolate(ent.getLastX(), ent.getX(), lag);
|
|
|
+ float y = Utils.interpolate(ent.getLastY(), ent.getY(), lag);
|
|
|
+
|
|
|
+ float m1;
|
|
|
+ float m2;
|
|
|
+ if(ent.getFace() == Face.LEFT)
|
|
|
+ {
|
|
|
+ m1 = 64.0f;
|
|
|
+ m2 = 0.0f;
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- switchDirection(face);
|
|
|
+ m1 = 0.0f;
|
|
|
+ m2 = 64.0f;
|
|
|
+ }
|
|
|
+ Shader.getTextureRenderer().drawRectangle(
|
|
|
+ x + ox + m1, y,
|
|
|
+ x + ox + m2, y + 64.0f,
|
|
|
+ tx, ty,
|
|
|
+ tx + 0.125f, ty + 0.125f);
|
|
|
+
|
|
|
+ if(ent.getHealth().wasHurt() || ent.getHealth().wasHealed())
|
|
|
+ {
|
|
|
+ Shader.setColorEnabled(false);
|
|
|
+ Shader.setMixColorEnabled(false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void switchDirection(Face face)
|
|
|
+ @Override
|
|
|
+ public void onCollideWithTile(Location loc, Face face)
|
|
|
{
|
|
|
- if(isEvil())
|
|
|
+ if(hasRedEyes())
|
|
|
{
|
|
|
- if(face == Face.LEFT || face == Face.RIGHT)
|
|
|
+ if(face.getOpposite() == ent.getFace() && ent.getMotionX() == 0.0f)
|
|
|
{
|
|
|
- jump = true;
|
|
|
+ ent.getMovement().jump();
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- if(face == Face.LEFT)
|
|
|
+ if(loc.getTile().shouldAiUseCollisionBox(loc.getX(), loc.getY()))
|
|
|
+ {
|
|
|
+ switch(face)
|
|
|
+ {
|
|
|
+ case LEFT:
|
|
|
+ direction = Face.LEFT;
|
|
|
+ break;
|
|
|
+ case RIGHT:
|
|
|
+ direction = Face.RIGHT;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onCollideWithEntity(Entity ent, Face face)
|
|
|
+ {
|
|
|
+ if(ent.getItemCollector().isHero() && hasRedEyes())
|
|
|
+ {
|
|
|
+ ent.getHealth().addHealthPercent(-0.1f);
|
|
|
+
|
|
|
+ ent.setMotionY(ent.getMotionY() - 20.0f);
|
|
|
+
|
|
|
+ float hx = ent.getLevel().getHero().getCenterX();
|
|
|
+ if(hx < ent.getCenterX())
|
|
|
{
|
|
|
- ent.getAnimator().setFlipped(true);
|
|
|
+ ent.setMotionX(ent.getMotionX() - 10.0f);
|
|
|
}
|
|
|
- else if(face == Face.RIGHT)
|
|
|
+ else
|
|
|
{
|
|
|
- ent.getAnimator().setFlipped(false);
|
|
|
+ ent.setMotionX(ent.getMotionX() + 10.0f);
|
|
|
}
|
|
|
}
|
|
|
- }*/
|
|
|
+ }
|
|
|
}
|