package com.mygame;
import loon.utils.RefObject;
public class Train extends Entity {
public int angle;
public static int CARRIAGE_GAP = 0x44c;
private int crashAngle;
public boolean crashed;
private int crashTargetAngle;
public boolean crashToLava;
private int crashx;
private int crashy;
private EDirections enterDir;
public boolean enteredWorld;
private EDirections exitDir;
public boolean finished;
public int levelset;
public static int MIN_TRAIN_SPEED = 40;
public int pos;
public boolean shouldStop;
public static int SOFT_CRASH_TICKS = 30;
public int softcrashticks;
public int speed;
private boolean stopped;
public Tile tile;
public static int TILE_CORNER_LENGTH = 0x514;
public static int TILE_LENGTH = 0x5dc;
private int tilelength;
private Train trail;
public static int TRAIN_DESCEND_CHANGE_TIME = 4;
public static int TRAIN_INSIDE_TILE = 0x270f;
private int yoffs;
public Train(int aLevelset) {
this.levelset = aLevelset;
this.crashed = false;
this.pos = 0;
this.tile = null;
this.speed = MIN_TRAIN_SPEED;
this.trail = null;
this.softcrashticks = -1;
this.enteredWorld = false;
this.finished = false;
this.stopped = false;
this.shouldStop = false;
this.yoffs = 0;
}
public EEntityClass getEntityType() {
return EEntityClass.EEntityTrain;
}
public static void getPos(RefObject<Integer> x,
RefObject<Integer> y, RefObject<Integer> angle,
int tilex, int tiley, ETileTypes tiletype, int drawpos, int tilew,
int tileh, int tilelength, EDirections enterDir) {
x.argvalue = tilex;
y.argvalue = tiley;
if (tiletype == ETileTypes.ETileCross) {
if ((enterDir == EDirections.EDirTop)
|| (enterDir == EDirections.EDirDown)) {
tiletype = ETileTypes.ETileTopDown;
} else {
tiletype = ETileTypes.ETileLeftRight;
}
}
switch (tiletype) {
case ETileLeftRight:
case ETileBridgeHorizontal:
case ECaveLeft:
case ECaveRight:
y.argvalue += tileh / 2;
if (enterDir == EDirections.EDirLeft) {
drawpos = tilelength - drawpos;
angle.argvalue = 180;
} else {
angle.argvalue = 0;
}
x.argvalue += (tilew * drawpos) / tilelength;
return;
case ETileTopDown:
case ETileBridgeVertical:
case ECaveBottom:
case ECaveTop:
x.argvalue += tilew / 2;
if (enterDir == EDirections.EDirTop) {
drawpos = tilelength - drawpos;
angle.argvalue = 90;
} else {
angle.argvalue = 270;
}
y.argvalue += (tileh * drawpos) / tilelength;
return;
case ETileTopRight:
if (enterDir != EDirections.EDirLeft) {
angle.argvalue = 270 + ((90 * drawpos) / tilelength);
break;
}
angle.argvalue = 180 - ((90 * drawpos) / tilelength);
drawpos = tilelength - drawpos;
x.argvalue += tilew;
y.argvalue += (GameUtils.sin((drawpos * 90) / tilelength) * tileh) >> 14;
x.argvalue -= (GameUtils.cos((drawpos * 90) / tilelength) * tilew) >> 14;
return;
case ETileRightDown:
if (enterDir != EDirections.EDirLeft) {
angle.argvalue = 90 - ((90 * drawpos) / tilelength);
} else {
angle.argvalue = 180 + ((90 * drawpos) / tilelength);
drawpos = tilelength - drawpos;
}
x.argvalue += tilew;
y.argvalue += tileh;
y.argvalue -= (GameUtils.sin((drawpos * 90) / tilelength) * tileh) >> 14;
x.argvalue -= (GameUtils.cos((drawpos * 90) / tilelength) * tilew) >> 14;
return;
case ETileDownLeft:
if (enterDir != EDirections.EDirRight) {
angle.argvalue = 90 + ((90 * drawpos) / tilelength);
} else {
angle.argvalue = 360 - ((90 * drawpos) / tilelength);
drawpos = tilelength - drawpos;
}
y.argvalue += tileh;
y.argvalue -= (GameUtils.sin((drawpos * 90) / tilelength) * tileh) >> 14;
x.argvalue += (GameUtils.cos((drawpos * 90) / tilelength) * tilew) >> 14;
return;
case ETileLeftTop:
if (enterDir != EDirections.EDirRight) {
angle.argvalue = 270 - ((90 * drawpos) / tilelength);
} else {
angle.argvalue = (90 * drawpos) / tilelength;
drawpos = tilelength - drawpos;
}
y.argvalue += (GameUtils.sin((drawpos * 90) / tilelength) * tileh) >> 14;
x.argvalue += (GameUtils.cos((drawpos * 90) / tilelength) * tilew) >> 14;
return;
default:
x.argvalue += tilew / 2;
y.argvalue += tileh / 2;
return;
}
x.argvalue += tilew;
y.argvalue += (GameUtils.sin((drawpos * 90) / tilelength) * tileh) >> 14;
x.argvalue -= (GameUtils.cos((drawpos * 90) / tilelength) * tilew) >> 14;
}
public Tile GetTile() {
return this.tile;
}
public boolean isFinished() {
return this.finished;
}
public void setCrashed(boolean soft) {
this.crashed = true;
if (soft) {
this.softcrashticks = 0;
this.pos = 0;
this.crashx = super.x;
this.crashy = super.y;
this.crashAngle = this.angle;
GameUtils
.initRandom((int) ((0xe25beaceL) ^ (super.x + (super.y * 0xe246a))));
this.crashTargetAngle = ((GameUtils.getRandom() >> 3) % 70) - 0x23;
if (this.trail != null) {
if (this.trail.stopped) {
this.trail.start();
this.trail.updatePos();
}
this.trail.setCrashed(true);
}
} else {
this.stop(true);
}
}
public void setFinished() {
this.finished = true;
}
public int SetTile(Tile aTile) {
if ((aTile.whereGoesFromDir(this.exitDir) == EDirections.TRAIN_CRASH)
|| ((super.type == 0) && aTile.isLocked())) {
if ((aTile.isLocked() && (aTile.type != ETileTypes.ETileBridgeHorizontal))
&& (aTile.type != ETileTypes.ETileBridgeVertical)) {
this.setCrashed(false);
return -1;
}
this.enterDir = this.exitDir;
if (this.tile.bridgeDropped()) {
this.crashToLava = true;
} else {
this.crashToLava = false;
}
this.setCrashed(true);
return -2;
}
if (((this.trail == null) && (this.tile != null))
&& !this.tile.IsCave()) {
this.tile.setLocked(false);
}
if (this.pos > 0) {
this.pos -= this.tilelength;
}
this.tile = aTile;
if (!this.tile.IsCave()) {
this.tile.setLocked(true);
this.enteredWorld = true;
}
if (this.tile.IsCave() && !this.enteredWorld) {
switch (tile.type) {
case ECaveBottom:
this.enterDir = EDirections.EDirTop;
this.exitDir = this.enterDir;
switch (this.tile.type) {
case ETileLeftTop:
case ETileTopRight:
case ETileRightDown:
case ETileDownLeft:
this.tilelength = TILE_CORNER_LENGTH;
break;
default:
this.tilelength = TILE_LENGTH;
break;
}
this.updatePos();
break;
case ECaveLeft:
this.enterDir = EDirections.EDirRight;
this.exitDir = this.enterDir;
switch (this.tile.type) {
case ETileLeftTop:
case ETileTopRight:
case ETileRightDown:
case ETileDownLeft:
this.tilelength = TILE_CORNER_LENGTH;
break;
default:
this.tilelength = TILE_LENGTH;
break;
}
this.updatePos();
break;
case ECaveRight:
this.enterDir = EDirections.EDirLeft;
this.exitDir = this.enterDir;
switch (this.tile.type) {
case ETileLeftTop:
case ETileTopRight:
case ETileRightDown:
case ETileDownLeft:
this.tilelength = TILE_CORNER_LENGTH;
break;
default:
this.tilelength = TILE_LENGTH;
break;
}
this.updatePos();
break;
case ECaveTop:
this.enterDir = EDirections.EDirDown;
this.exitDir = this.enterDir;
switch (this.tile.type) {
case ETileLeftTop:
case ETileTopRight:
case ETileRightDown:
case ETileDownLeft:
this.tilelength = TILE_CORNER_LENGTH;
break;
default:
this.tilelength = TILE_LENGTH;
break;
}
this.updatePos();
break;
default:
break;
}
} else {
this.enterDir = this.exitDir;
this.exitDir = this.tile.whereGoesFromDir(this.enterDir);
}
return 0;
}
public void setTrail(Train aTrail) {
this.trail = aTrail;
}
public void start() {
this.stopped = false;
}
public void stop() {
this.stop(false);
}
public void stop(boolean recursive) {
this.stopped = true;
if (recursive && (this.trail != null)) {
this.trail.stop(true);
}
}
public int Tick() {
if ((this.tile != null) && !this.stopped) {
if (this.crashed) {
this.updateCrashPos();
} else {
if (this.shouldStop) {
this.speed -= 4;
if (this.speed < 0) {
this.speed = 0;
}
}
this.pos += this.speed;
if ((this.tile.IsCave() && (this.trail != null))
&& ((this.pos > CARRIAGE_GAP) && this.trail.stopped)) {
this.trail.start();
}
this.updatePos();
if (this.pos >= this.tilelength) {
return this.exitDir.getValue();
}
}
}
return TRAIN_INSIDE_TILE;
}
private void updateCrashPos() {
this.softcrashticks++;
if (this.softcrashticks < SOFT_CRASH_TICKS) {
int num = (this.speed * (SOFT_CRASH_TICKS - this.softcrashticks))
/ SOFT_CRASH_TICKS;
this.pos += num;
int num2 = (((GameUtils.cos(this.crashAngle) * this.pos) * Tile
.getTileWReal()) >> 13) / TILE_LENGTH;
int num3 = -(((GameUtils.sin(this.crashAngle) * this.pos) * Tile
.getTileHReal()) >> 13) / TILE_LENGTH;
super.x = this.crashx + num2;
super.y = this.crashy + num3;
if (this.crashToLava && (super.type == 0)) {
super.y += (this.softcrashticks * Tile.getTileHReal())
/ (SOFT_CRASH_TICKS * 6);
} else if (this.softcrashticks < (SOFT_CRASH_TICKS / 2)) {
this.angle = this.crashAngle
+ (((this.crashTargetAngle * this.softcrashticks) * 2) / SOFT_CRASH_TICKS);
} else {
this.angle = this.crashAngle + this.crashTargetAngle;
}
}
}
private void updatePos() {
if (this.tile != null) {
int tilew = Tile.getTileWReal();
int tileh = Tile.getTileHReal();
RefObject<Integer> tempRef_x = new RefObject<Integer>(
this.x);
RefObject<Integer> tempRef_y = new RefObject<Integer>(
this.y);
RefObject<Integer> tempRef_angle = new RefObject<Integer>(
this.angle);
getPos(tempRef_x, tempRef_y, tempRef_angle, this.tile.x,
this.tile.y, this.tile.type, this.pos, tilew, tileh,
this.tilelength, this.enterDir);
super.x = tempRef_x.argvalue;
super.y = tempRef_y.argvalue;
this.angle = tempRef_angle.argvalue;
if (((this.tile.type != ETileTypes.ECaveBottom) && (this.tile.type != ETileTypes.ECaveTop))
&& ((this.tile.type != ETileTypes.ECaveLeft) && (this.tile.type != ETileTypes.ECaveRight))) {
this.yoffs++;
if (this.yoffs > TRAIN_DESCEND_CHANGE_TIME) {
this.yoffs = TRAIN_DESCEND_CHANGE_TIME;
}
} else if (this.yoffs > 0) {
this.yoffs--;
}
super.y += (tileh * this.yoffs) / (TRAIN_DESCEND_CHANGE_TIME * 15);
super.x++;
}
}
}