87#define TRA_GROOVE_X -39 
   89#define BUS_GROOVE_X -39 
  146    sprite->soundCount = 0;
 
  151    sprite->control = -1;
 
  156    if (globalSprites[sprite->
type] == NULL) {
 
  157        globalSprites[sprite->
type] = sprite;
 
  160    switch (sprite->
type) {
 
  165            sprite->xOffset = 32;
 
  166            sprite->yOffset = -16;
 
  176            sprite->xOffset = 32;
 
  177            sprite->yOffset = -16;
 
  183            } 
else if (x >= ((
WORLD_W - 4) <<4)) {
 
  185            } 
else if (y < (4 <<4)) {
 
  187            } 
else if (y >= ((
WORLD_H - 4) <<4)) {
 
  193            sprite->newDir = sprite->
frame;
 
  201            sprite->xOffset = 24;
 
  212            } 
else if (y > ((
WORLD_H <<4) / 2)) {
 
  218            sprite->count = 1000;
 
  221            sprite->origX = sprite->
x;
 
  222            sprite->origY = sprite->
y;
 
  228            sprite->xOffset = 32;
 
  229            sprite->yOffset = -16;
 
  233            sprite->count = 1500;
 
  236            sprite->origX = x - 30;
 
  243            sprite->xOffset = 24;
 
  247            if (x > ((
WORLD_W - 20) <<4)) {
 
  248                sprite->
x -= 100 + 48;
 
  249                sprite->
destX = sprite->
x - 200;
 
  252                sprite->
destX = sprite->
x + 200;
 
  255            sprite->
destY = sprite->
y;
 
  261            sprite->xOffset = 24;
 
  272            sprite->xOffset = 24;
 
  282            sprite->xOffset = 30;
 
  283            sprite->yOffset = -18;
 
 
  302    for (sprite = 
spriteList; sprite != NULL; sprite = sprite->
next) {
 
 
  317    if (globalSprites[sprite->
type] == sprite) {
 
  321    for (sp = &
spriteList; *sp != NULL; sp = &((*sp)->next)) {
 
  322        if (sprite == (*sp)) {
 
 
  341    if (sprite == NULL || sprite->
frame == 0) {
 
 
  359    sprite = globalSprites[type];
 
  360    if (sprite == NULL) {
 
 
  445    if (Tpoo == POWERBASE || Tpoo == POWERBASE + 1
 
  446          || Tpoo == RAILBASE || Tpoo == RAILBASE + 1) {
 
 
  461    int x = sprite->
x + sprite->
xHot;
 
  462    int y = sprite->
y + sprite->
yHot;
 
  464    return x < 0 || y < 0 || x >= (WORLD_W <<4) || y >= (
WORLD_H <<4);
 
 
  479    static const short Gdtab[13] = { 0, 3, 2, 1, 3, 4, 5, 7, 6, 5, 7, 8, 1 };
 
  501    absDist = dispX + dispY;
 
  503    if (dispX * 2 < dispY) {
 
  505    } 
else if (dispY * 2 < dispY) {  
 
  509    if (z < 0 || z > 12) {
 
 
  564        if (sprite->
frame > 0) {
 
  565            switch (sprite->
type) {
 
  601            sprite = sprite->
next;
 
  605            if (sprite->
name[0] == 
'\0') {
 
  607                sprite = sprite->
next;
 
  610                sprite = sprite->
next;
 
 
  626    static const short Cx[4] = {   0,  16,   0, -16 };
 
  627    static const short Cy[4] = { -16,   0,  16,   0 };
 
  629    static const short Dx[5] = {   0,   4,   0,  -4,   0 };
 
  630    static const short Dy[5] = {  -4,   0,   4,   0,   0 };
 
  632    static const short TrainPic2[5] = { 1, 2, 1, 2, 5 };
 
  636    if (sprite->
frame == 3 || sprite->
frame == 4) {
 
  637        sprite->
frame = TrainPic2[sprite->dir];
 
  640    sprite->
x += Dx[sprite->dir];
 
  641    sprite->
y += Dy[sprite->dir];
 
  643    if ((spriteCycle & 3) == 0) {
 
  646        for (z = dir; z < dir + 4; z++) {
 
  649            if (sprite->dir != 4) {
 
  650                if (dir2 == ((sprite->dir + 2) & 3)) {
 
  655            c = 
getChar(sprite->
x + Cx[dir2] + 48, sprite->
y + Cy[dir2]);
 
  657            if ((c >= RAILBASE && c <= LASTRAIL) 
 
  660                if (sprite->dir != dir2 && sprite->dir != 4) {
 
  662                    if (sprite->dir + dir2 == 3) {
 
  669                    sprite->
frame = TrainPic2[dir2];
 
  672                if (c == HRAIL || c == VRAIL) {
 
  681        if (sprite->dir == 4) {
 
 
  698    static const short CDx[9] = { 0,  0,  3,  5,  3,  0, -3, -5, -3 };
 
  699    static const short CDy[9] = { 0, -5, -3,  0,  3,  5,  3,  0, -3 };
 
  701    if (sprite->soundCount > 0) {
 
  702        sprite->soundCount--;
 
  705    if (sprite->control < 0) {
 
  707        if (sprite->count > 0) {
 
  711        if (sprite->count == 0) {
 
  728                    sprite->
destX = sprite->origX;
 
  729                    sprite->
destY = sprite->origY;
 
  735        if (sprite->count == 0) { 
 
  736            getDir(sprite->
x, sprite->
y, sprite->origX, sprite->origY);
 
  750            sprite->
destX = sprite->origX;
 
  751            sprite->
destY = sprite->origY;
 
  752            sprite->control = -1;
 
  757    if (sprite->soundCount == 0) { 
 
  760        short x = (sprite->
x + 48) / 16;
 
  761        short y = sprite->
y / 16;
 
  763        if (x >= 0 && x < WORLD_W && y >= 0 && y < 
WORLD_H) {
 
  767            int chopperX = x + 1;
 
  768            int chopperY = y + 1;
 
  771                makeSound(
"city", 
"HeavyTraffic", chopperX, chopperY); 
 
  772                sprite->soundCount = 200;
 
  779    short z = sprite->
frame;
 
  781    if ((spriteCycle & 3) == 0) {
 
 
  803    static const short CDx[12] = { 0,  0,  6, 8, 6, 0, -6, -8, -6, 8, 8, 8 };
 
  804    static const short CDy[12] = { 0, -8, -6, 0, 6, 8,  6,  0, -6, 0, 0, 0 };
 
  806    short z = sprite->
frame;
 
  808    if ((spriteCycle % 5) == 0) {
 
  832        bool explode = 
false;
 
  836            if (s->
frame == 0 || s == sprite) {
 
 
  869    static const short BDx[9] = { 0,  0,  1,  1,  1,  0, -1, -1, -1 };
 
  870    static const short BDy[9] = { 0, -1, -1,  0,  1,  1,  1,  0, -1 };
 
  871    static const short BPx[9] = { 0,  0,  2,  2,  2,  0, -2, -2, -2 };
 
  872    static const short BPy[9] = { 0, -2, -2,  0,  2,  2,  2,  0, -2 };
 
  873    static const short BtClrTab[8] = { RIVER, CHANNEL, POWERBASE, POWERBASE + 1,
 
  874                                       RAILBASE, RAILBASE + 1, BRWH, BRWV };
 
  875    short x, y, z, t = RIVER;
 
  878    if (sprite->soundCount > 0) {
 
  879        sprite->soundCount--;
 
  882    if (!sprite->soundCount) {
 
  887            int shipX = sprite->
x >>4;
 
  888            int shipY = sprite->
y >>4;
 
  891                makeSound(
"city", 
"FogHornLow", shipX, shipY);
 
  893                makeSound(
"city", 
"HonkHonkLow", shipX, shipY);
 
  898        sprite->soundCount = 200;
 
  901    if (sprite->count > 0) {
 
  905    if (sprite->count == 0) {
 
  909        if (sprite->
frame != sprite->newDir) {
 
  916        for (pem = tem; pem < (tem + 8); pem++) {
 
  920            if (z == sprite->dir) {
 
  924            x = ((sprite->
x + (48 - 1)) >>4) + BDx[z];
 
  925            y = (sprite->
y >>4) + BDy[z];
 
  931                if (t == CHANNEL || t == BRWH || t == BRWV
 
  938                    if (sprite->dir > 8) {
 
  947        if (pem == (tem + 8)) {
 
  956        if (z == sprite->newDir)  {
 
  967    for (z = 0; z < 8; z++) {
 
  969        if (t == BtClrTab[z]) {
 
 
 1009    static const short Gx[5] = {  2,  2, -2, -2,  0 };
 
 1010    static const short Gy[5] = { -2,  2,  2, -2,  0 };
 
 1011    static const short ND1[4] = {  0,  1,  2,  3 };
 
 1012    static const short ND2[4] = {  1,  2,  3,  0 };
 
 1013    static const short nn1[4] = {  2,  5,  8, 11 };
 
 1014    static const short nn2[4] = { 11,  2,  5,  8 };
 
 1017    if (sprite->soundCount > 0) {
 
 1018        sprite->soundCount--;
 
 1021    if (sprite->control < 0) {
 
 1024        if (sprite->control == -2) {
 
 1026            d = (sprite->
frame - 1) / 3;
 
 1027            z = (sprite->
frame - 1) % 3;
 
 1047                sprite->control = -1;
 
 1048                sprite->count = 1000;
 
 1050                sprite->
destX = sprite->origX;
 
 1051                sprite->
destY = sprite->origY;
 
 1059                    int diff = (c - d) & 3;
 
 1061                    if (diff == 1 || diff == 3) {
 
 1089            d = (sprite->
frame - 1) / 3;
 
 1093                z = (sprite->
frame - 1) % 3;
 
 1113                    if (sprite->flag == 0) {
 
 1116                        sprite->
destX = sprite->origX;
 
 1117                        sprite->
destY = sprite->origY;
 
 1141                    if (!sprite->soundCount) {
 
 1143                        int monsterX = sprite->
x >>4;
 
 1144                        int monsterY = sprite->
y >>4;
 
 1145                        makeSound(
"city", 
"Monster", monsterX, monsterY); 
 
 1146                        sprite->soundCount = 50 + 
getRandom(100);
 
 1178          d = sprite->control;
 
 1179          z = (sprite->
frame - 1) % 3;
 
 1208    if (sprite->count > 0) {
 
 1215          || (c == RIVER && sprite->count != 0 && sprite->control == -1)) {
 
 1222            if (s->
frame != 0 &&
 
 
 1241    static const short CDx[9] = {  2,  3,  2,  0, -2, -3 };
 
 1242    static const short CDy[9] = { -2,  0,  2,  3,  2,  0 };
 
 1268    if (sprite->count > 0) {
 
 1277            if (s->
frame != 0 &&
 
 1287    sprite->
x += CDx[z];
 
 1288    sprite->
y += CDy[z];
 
 1294    if (sprite->count != 0 && 
getRandom(500) == 0) {
 
 
 1310    if ((spriteCycle & 1) == 0) {
 
 1312        if (sprite->
frame == 1) {
 
 1314            int explosionX = sprite->
x >>4;
 
 1315            int explosionY = sprite->
y >>4;
 
 1316            makeSound(
"city", 
"ExplosionHigh", explosionX, explosionY); 
 
 1317            x = (sprite->
x >>4) + 3;
 
 1318            y = (sprite->
y >>4);
 
 1325    if (sprite->
frame > 6) {
 
 
 1344    static const short Dx[5] = {   0,   1,   0,  -1,   0 };
 
 1345    static const short Dy[5] = {  -1,   0,   1,   0,   0 };
 
 1346    static const short Dir2Frame[4] = { 1, 2, 1, 2 };
 
 1347    int dx, dy, tx, ty, otx, oty;
 
 1353    printf(
"Bus dir %d turn %d frame %d\n",
 
 1354           sprite->dir, sprite->turn, sprite->
frame);
 
 1359        if (sprite->turn < 0) { 
 
 1361            if (sprite->dir & 1) { 
 
 1368            sprite->dir = (sprite->dir - 1) & 3;
 
 1372            if (sprite->dir & 1) { 
 
 1379            sprite->dir = (sprite->dir + 1) & 3;
 
 1388        if ((sprite->
frame == 3) ||
 
 1389            (sprite->
frame == 4)) {
 
 1391            sprite->
frame = Dir2Frame[sprite->dir];
 
 1395    if (sprite->speed == 0) {
 
 1402        tx = (sprite->
x + sprite->
xHot) >>5;
 
 1403        ty = (sprite->
y + sprite->
yHot) >>5;
 
 1405        if (tx >= 0 && tx < WORLD_W_2 && ty >= 0 && ty < 
WORLD_H_2) {
 
 1436        if (speed > sprite->speed) {
 
 1437            speed = sprite->speed;
 
 1450            dx = Dx[sprite->dir] * speed;
 
 1451            dy = Dy[sprite->dir] * speed;
 
 1455            dx = Dx[sprite->dir] * speed;
 
 1456            dy = Dy[sprite->dir] * speed;
 
 1458            tx = (sprite->
x + sprite->
xHot) >>4;
 
 1459            ty = (sprite->
y + sprite->
yHot) >>4;
 
 1462            switch (sprite->dir) {
 
 1466                    z = ((tx <<4) + 4) - (sprite->
x + sprite->
xHot);
 
 1475                    printf(
"moving up x %x z %d dx %d\n", sprite->
x + sprite->
xHot, z, dx);
 
 1482                    z = ((ty <<4) + 4) - (sprite->
y + sprite->
yHot);
 
 1491                    printf(
"moving right y %x z %d dy %d\n", sprite->
y + sprite->
yHot, z, dy);
 
 1498                    z = (tx <<4) - (sprite->
x + sprite->
xHot);
 
 1507                    printf(
"moving down x %x z %d dx %d\n", sprite->
x + sprite->
xHot, z, dx);
 
 1514                    z = (ty <<4) - (sprite->
y + sprite->
yHot);
 
 1523                    printf(
"moving left y %x z %d dy %d\n", sprite->
y + sprite->
yHot, z, dy);
 
 1532    printf(
"speed dx %d dy %d\n", dx, dy);
 
 1537    otx = (sprite->
x + sprite->
xHot + (Dx[sprite->dir] * AHEAD)) >>4;
 
 1538    oty = (sprite->
y + sprite->
yHot + (Dy[sprite->dir] * AHEAD)) >>4;
 
 1543    tx = (sprite->
x + sprite->
xHot + dx + (Dx[sprite->dir] * AHEAD)) >>4;
 
 1544    ty = (sprite->
y + sprite->
yHot + dy + (Dy[sprite->dir] * AHEAD)) >>4;
 
 1549    if (tx != otx || ty != oty) {
 
 1552        printf(
"drive from tile %d %d to %d %d\n",
 
 1562                bulldozerTool(tx, ty);
 
 1580    tx = (sprite->
x + sprite->
xHot + dx) >>4;
 
 1581    ty = (sprite->
y + sprite->
yHot + dy) >>4;
 
 1603            if (sprite != s && s->
frame != 0
 
 
 1636    if ((tile >= ROADBASE && tile <= LASTROAD && tile != BRWH && tile != BRWV)
 
 1637              || tile == HRAILROAD || tile == VRAILROAD) {
 
 
 1660    x = sprite->
x + sprite->
xHot;
 
 1661    y = sprite->
y + sprite->
yHot;
 
 1667    switch (sprite->
type) {
 
 1692    makeSound(
"city", 
"ExplosionHigh", x, y); 
 
 
 1698bool Micropolis::checkWet(
int x)
 
 1700    if (x == HPOWER || x == VPOWER || x == HRAIL || x == VRAIL
 
 1701              || x == BRWH || x == BRWV) {
 
 1728    if (t >= TREEBASE) {
 
 1731          if (t >= ROADBASE && t <= LASTROAD) {
 
 
 1770    value = 
clamp(value - 20, -200, 200);
 
 1778        if (ch == AIRPORT) {
 
 1785    for (x = -1; x < XYmax; x++) {
 
 1786        for (y = -1; y < XYmax; y++) {
 
 
 1863        for (x = 4; x < 
WORLD_W - 2; x++) {
 
 1864            if (
map[x][0] == CHANNEL)  {
 
 1872        for (y = 1; y < 
WORLD_H - 2; y++) {
 
 1873            if (
map[0][y] == CHANNEL)  {
 
 1881        for (x = 4; x < 
WORLD_W - 2; x++) {
 
 1890        for (y = 1; y < 
WORLD_H - 2; y++) {
 
 
 1919    int x, y, z, done = 0;
 
 1923    if (sprite != NULL) {
 
 1924        sprite->soundCount = 1;
 
 1925        sprite->count = 1000;
 
 1931    for (z = 0; z < 300; z++)  {
 
 
 2002    if (sprite != NULL) {
 
 2003        sprite->count = 200;
 
 
DATA worldGet(int x, int y) const
void worldSet(int x, int y, DATA val)
void doCopterSprite(SimSprite *sprite)
SimSprite * spriteList
List of active sprites.
void generateCopter(const Position &pos)
void explodeSprite(SimSprite *sprite)
void doTornadoSprite(SimSprite *sprite)
void doAirplaneSprite(SimSprite *sprite)
bool checkSpriteCollision(SimSprite *s1, SimSprite *s2)
void startFireInZone(int Xloc, int Yloc, int ch)
short turnTo(int p, int d)
bool tally(short tileValue)
void initSprite(SimSprite *sprite, int x, int y)
Scenario scenario
Scenario being played.
void makeExplosion(int x, int y)
void destroySprite(SimSprite *sprite)
SimSprite * freeSprites
Pool of free SimSprite objects.
short getDir(int orgX, int orgY, int desX, int desY)
void makeMonsterAt(int x, int y)
void startFire(int x, int y)
short getRandom(short range)
short pollutionMaxY
Y coordinate of most polluted area.
bool enableDisasters
Enable disasters.
void generatePlane(const Position &pos)
int canDriveOn(int x, int y)
short pollutionMaxX
X coordinate of most polluted area.
void doShipSprite(SimSprite *sprite)
void doExplosionSprite(SimSprite *sprite)
void doTrainSprite(SimSprite *sprite)
SimSprite * getSprite(int type)
bool tryOther(int Tpoo, int Told, int Tnew)
int getDistance(int x1, int y1, int x2, int y2)
unsigned short * map[WORLD_W]
void doBusSprite(SimSprite *sprite)
void generateTrain(int x, int y)
void sendMessage(short Mnum, short x=NOWHERE, short y=NOWHERE, bool picture=false, bool important=false)
void makeSound(const std::string &channel, const std::string &sound, int x=-1, int y=-1)
short getChar(int x, int y)
void generateBus(int x, int y)
SimSprite * newSprite(const std::string &name, int type, int x, int y)
MapByte2 trafficDensityMap
Traffic density map.
static bool testBounds(int wx, int wy)
void doMonsterSprite(SimSprite *sprite)
void makeExplosionAt(int x, int y)
SimSprite * makeSprite(int type, int x, int y)
MapShort8 rateOfGrowthMap
void makeShipHere(int x, int y)
bool spriteNotInBounds(SimSprite *sprite)
void destroyMapTile(int ox, int oy)
int posY
Vertical coordnate of the position.
int posX
Horizontal coordinate of the position.
int x
X coordinate of the sprite in pixels?
int destX
Destination X coordinate of the sprite.
int yHot
Offset of the hot-spot relative to SimSprite::y?
int type
Type of the sprite (TRA – BUS).
int destY
Destination Y coordinate of the sprite.
SimSprite * next
Pointer to next SimSprite object in the list.
std::string name
Name of the sprite.
int y
Y coordinate of the sprite in pixels?
int frame
Frame (0 means non-active sprite)
int xHot
Offset of the hot-spot relative to SimSprite::x?
Header file for Micropolis game engine.
@ SC_SAN_FRANCISCO
San francisco (earthquake)
@ RAILHPOWERV
Horizontal rail, vertical power.
@ PORTBASE
Top-left tile of the seaport.
@ RAILVPOWERH
Vertical rail, horizontal power.
static const int WORLD_H_2
@ SPRITE_AIRPLANE
Airplane sprite.
@ SPRITE_TORNADO
Tornado sprite.
@ SPRITE_MONSTER
Scary monster.
@ SPRITE_TRAIN
Train sprite.
@ SPRITE_HELICOPTER
Helicopter sprite.
@ SPRITE_EXPLOSION
Explosion sprite.
static T clamp(const T val, const T lower, const T upper)
static T absoluteValue(const T val)
Defines string identification numbers for texts used in the Micropolis game engine.
@ MESSAGE_SHIP_CRASHED
25: Shipwreck reported !
@ MESSAGE_PLANE_CRASHED
A plane has crashed !
@ MESSAGE_TRAIN_CRASHED
A train crashed !
@ MESSAGE_HELICOPTER_CRASHED
A helicopter crashed !
@ MESSAGE_MONSTER_SIGHTED
A Monster has been sighted !!
@ MESSAGE_EXPLOSION_REPORTED
Explosion detected !
@ MESSAGE_TORNADO_SIGHTED
Tornado reported !!
@ MESSAGE_HEAVY_TRAFFIC
Heavy Traffic reported.