142 lines
3.2 KiB
Java
142 lines
3.2 KiB
Java
// This file is part of MicropolisJ.
|
|
// Copyright (C) 2013 Jason Long
|
|
// Portions Copyright (C) 1989-2007 Electronic Arts Inc.
|
|
//
|
|
// MicropolisJ is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU GPLv3, with additional terms.
|
|
// See the README file, included in this distribution, for details.
|
|
|
|
package micropolisj.engine;
|
|
|
|
import static micropolisj.engine.TileConstants.*;
|
|
|
|
/**
|
|
* Implements the cargo ship.
|
|
* The cargo ship is created if the city contains a sea port.
|
|
* It follows the river "channel" that was originally generated.
|
|
* It frequently turns around.
|
|
*/
|
|
public class ShipSprite extends Sprite
|
|
{
|
|
static int [] BDx = { 0, 0, 1, 1, 1, 0, -1, -1, -1 };
|
|
static int [] BDy = { 0, -1, -1, 0, 1, 1, 1, 0, -1 };
|
|
static int [] BPx = { 0, 0, 2, 2, 2, 0, -2, -2, -2 };
|
|
static int [] BPy = { 0, -2, -2, 0, 2, 2, 2, 0, -2 };
|
|
static int [] BtClrTab = { RIVER, CHANNEL, POWERBASE, POWERBASE+1,
|
|
RAILBASE, RAILBASE+1, BRWH, BRWV };
|
|
|
|
int newDir;
|
|
int count;
|
|
int soundCount;
|
|
|
|
public static final int NORTH_EDGE = 5;
|
|
public static final int EAST_EDGE = 7;
|
|
public static final int SOUTH_EDGE = 1;
|
|
public static final int WEST_EDGE = 3;
|
|
|
|
public ShipSprite(Micropolis engine, int xpos, int ypos, int edge)
|
|
{
|
|
super(engine, SpriteKind.SHI);
|
|
this.x = xpos * 16 + 8;
|
|
this.y = ypos * 16 + 8;
|
|
this.width = 48;
|
|
this.height = 48;
|
|
this.offx = -24;
|
|
this.offy = -24;
|
|
this.frame = edge;
|
|
this.newDir = edge;
|
|
this.dir = 10;
|
|
this.count = 1;
|
|
}
|
|
|
|
@Override
|
|
public void moveImpl()
|
|
{
|
|
int t = RIVER;
|
|
|
|
this.soundCount--;
|
|
if (this.soundCount <= 0) {
|
|
if (city.PRNG.nextInt(4) == 0) {
|
|
city.makeSound(x/16,y/16,Sound.HONKHONK_LOW);
|
|
}
|
|
this.soundCount = 200;
|
|
}
|
|
|
|
this.count--;
|
|
if (this.count <= 0) {
|
|
this.count = 9;
|
|
if (this.newDir != this.frame) {
|
|
this.frame = turnTo(this.frame, this.newDir);
|
|
return;
|
|
}
|
|
int tem = city.PRNG.nextInt(8);
|
|
int pem;
|
|
for (pem = tem; pem < (tem + 8); pem++) {
|
|
int z = (pem % 8) + 1;
|
|
if (z == this.dir)
|
|
continue;
|
|
|
|
int xpos = this.x / 16 + BDx[z];
|
|
int ypos = this.y / 16 + BDy[z];
|
|
|
|
if (city.testBounds(xpos, ypos)) {
|
|
t = city.getTile(xpos, ypos);
|
|
if ((t == CHANNEL) || (t == BRWH) || (t == BRWV) ||
|
|
tryOther(t, this.dir, z))
|
|
{
|
|
this.newDir = z;
|
|
this.frame = turnTo(this.frame, this.newDir);
|
|
this.dir = z + 4;
|
|
if (this.dir > 8) { this.dir -= 8; }
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pem == (tem + 8)) {
|
|
this.dir = 10;
|
|
this.newDir = city.PRNG.nextInt(8)+1;
|
|
}
|
|
}
|
|
else {
|
|
int z = this.frame;
|
|
if (z == this.newDir) {
|
|
this.x += BPx[z];
|
|
this.y += BPy[z];
|
|
}
|
|
}
|
|
|
|
if (!spriteInBounds()) {
|
|
this.frame = 0;
|
|
return;
|
|
}
|
|
|
|
boolean found = false;
|
|
for (int z : BtClrTab) {
|
|
if (t == z) {
|
|
found = true;
|
|
}
|
|
}
|
|
if (!found) {
|
|
//explodeSprite();
|
|
//destroyTile(x/16, y/16);
|
|
}
|
|
}
|
|
|
|
boolean tryOther(int tile, int oldDir, int newDir)
|
|
{
|
|
int z = oldDir + 4;
|
|
if (z > 8) z -= 8;
|
|
if (newDir != z) return false;
|
|
|
|
return (tile == POWERBASE || tile == POWERBASE+1 ||
|
|
tile == RAILBASE || tile == RAILBASE+1);
|
|
}
|
|
|
|
boolean spriteInBounds()
|
|
{
|
|
int xpos = x / 16;
|
|
int ypos = y / 16;
|
|
return city.testBounds(xpos, ypos);
|
|
}
|
|
}
|