int getMapRight(int x, int y) { int maxX = getMapMaxX() / TILE_SIZE; int tileID; x /= TILE_SIZE; y /= TILE_SIZE; tileID = mapTileAt(x, y); while (tileID == BLANK_TILE || (tileID >= BACKGROUND_TILE_START && tileID <= BACKGROUND_TILE_END)) { x++; if (x >= maxX) { break; } tileID = mapTileAt(x, y); } x *= TILE_SIZE; return x; }
int getWaterTop(int x, int y) { int tileID; x /= TILE_SIZE; y /= TILE_SIZE; tileID = mapTileAt(x, y); while (tileID == WATER_TILE_START) { y--; if (y < 0) { break; } tileID = mapTileAt(x, y); } y++; y *= TILE_SIZE; return y; }
int getMapCeiling(int x, int y) { int tileID; x /= TILE_SIZE; y /= TILE_SIZE; tileID = mapTileAt(x, y); while (tileID == BLANK_TILE || (tileID >= BACKGROUND_TILE_START && tileID <= BACKGROUND_TILE_END)) { y--; if (y < 0) { break; } tileID = mapTileAt(x, y); } y = y * TILE_SIZE + TILE_SIZE; return y; }
int getMapLeft(int x, int y) { int tileID; x /= TILE_SIZE; y /= TILE_SIZE; tileID = mapTileAt(x, y); while (tileID == BLANK_TILE || (tileID >= BACKGROUND_TILE_START && tileID <= BACKGROUND_TILE_END)) { x--; if (x <= 0) { break; } tileID = mapTileAt(x, y); } x *= TILE_SIZE; return x; }
static int isGapJumpable() { int tile1, tile2; int x = self->face == LEFT ? floor(self->x) : ceil(self->x) + self->w; int y = self->y + self->h - 1; x /= TILE_SIZE; y /= TILE_SIZE; y++; x += self->face == LEFT ? -3 : 3; tile1 = mapTileAt(x, y); if (tile1 != BLANK_TILE && tile1 < BACKGROUND_TILE_START) { y--; tile2 = mapTileAt(x, y); if (tile2 == BLANK_TILE || (tile2 >= BACKGROUND_TILE_START && tile2 <= BACKGROUND_TILE_END)) { return TRUE; } } return FALSE; }
int getMapFloor(int x, int y) { int maxY = getMapMaxY() / TILE_SIZE; int tileID; x /= TILE_SIZE; y /= TILE_SIZE; tileID = mapTileAt(x, y); while (tileID == BLANK_TILE || (tileID >= BACKGROUND_TILE_START && tileID <= BACKGROUND_TILE_END)) { y++; if (y >= maxY) { break; } tileID = mapTileAt(x, y); } y *= TILE_SIZE; return y; }
static int canJumpUp() { int tile, tile2, i; int x = self->face == LEFT ? floor(self->x) : ceil(self->x) + self->w; int y = self->y + self->h - 1; x /= TILE_SIZE; y /= TILE_SIZE; x += self->face == LEFT ? -1 : 0; for (i=0;i<4;i++) { tile = mapTileAt(x, y - (i + 1)); tile2 = mapTileAt(x, y - i); if (!(tile != BLANK_TILE && tile < BACKGROUND_TILE_START) && (tile2 != BLANK_TILE && tile2 < BACKGROUND_TILE_START)) { return TRUE; } } return FALSE; }
static int safeToDrop() { int x, y, i, tile; x = self->x + self->w / 2; y = self->y + self->h - 1; x /= TILE_SIZE; y /= TILE_SIZE; y++; for (i=0;i<30;i++) { tile = mapTileAt(x, y); if (tile != BLANK_TILE && (tile < BACKGROUND_TILE_START || tile > FOREGROUND_TILE_START)) { return tile < BACKGROUND_TILE_START ? TRUE : FALSE; } y++; } return FALSE; }
static int canDropDown() { int tile, i, j, width; int x = self->face == LEFT ? floor(self->x) : ceil(self->x) + self->w; int y = self->y + self->h - 1; x /= TILE_SIZE; y /= TILE_SIZE; width = self->w / TILE_SIZE; for (j=0;j<width;j++) { for (i=0;i<8;i++) { tile = mapTileAt(x + (self->face == LEFT ? -j : j), y + i); if (tile >= WATER_TILE_START) { break; } if (tile != BLANK_TILE && tile < BACKGROUND_TILE_START) { x = (x + (self->face == LEFT ? -j : j)) * TILE_SIZE; y = (y + i) * TILE_SIZE; return TRUE; } } } return FALSE; }
int onSingleTile(Entity *e) { int leftTile, rightTile, midTile, wallLeft, wallRight; int x = e->x + e->w / 2; int y = e->y + e->h - 1; x /= TILE_SIZE; y /= TILE_SIZE; y++; midTile = mapTileAt(x, y); leftTile = mapTileAt(x - 1, y); rightTile = mapTileAt(x + 1, y); wallLeft = mapTileAt(x - 1, y - 1); wallRight = mapTileAt(x + 1, y - 1); /* On a tile with nothing either side */ if ((midTile != BLANK_TILE && midTile < BACKGROUND_TILE_START) && leftTile == BLANK_TILE && rightTile == BLANK_TILE) { return TRUE; } /* On a tile with nothing on the left and a wall on the right */ if ((midTile != BLANK_TILE && midTile < BACKGROUND_TILE_START) && leftTile == BLANK_TILE && (wallRight != BLANK_TILE && wallRight < BACKGROUND_TILE_START)) { return TRUE; } /* On a tile with nothing on the right and a wall on the left */ if ((midTile != BLANK_TILE && midTile < BACKGROUND_TILE_START) && rightTile == BLANK_TILE && (wallLeft != BLANK_TILE && wallLeft < BACKGROUND_TILE_START)) { return TRUE; } return FALSE; }
void checkToMap(Entity *e) { int i, x1, x2, y1, y2, previousEnvironment; int topLeft, topRight, bottomLeft, bottomRight, previousY2, previous; int tempX, tempY, wasOnGround; wasOnGround = (e->flags & ON_GROUND); /* Remove the entity from the ground */ e->flags &= ~ON_GROUND; /* Set environment to air */ previousEnvironment = e->environment; e->environment = AIR; /* Test the horizontal movement first */ i = e->h > TILE_SIZE ? TILE_SIZE : e->h; for (;;) { x1 = (e->x + e->dirX) / TILE_SIZE; x2 = (e->x + e->dirX + e->w - 1) / TILE_SIZE; y1 = (e->y) / TILE_SIZE; y2 = (e->y + i - 1) / TILE_SIZE; if (x1 >= 0 && x2 < MAX_MAP_X && y1 >= 0 && y2 < MAX_MAP_Y) { topLeft = mapTileAt(x1, y1); topRight = mapTileAt(x2, y1); bottomLeft = mapTileAt(x1, y2); bottomRight = mapTileAt(x2, y2); if (e->dirX > 0) { /* Trying to move right */ previous = (e->x + e->w - 1) / TILE_SIZE; previous = mapTileAt(previous, y2); if (previous >= SLOPE_UP_START && previous <= SLOPE_UP_END) { if (i == e->h) { if (bottomRight >= SLOPE_UP_START && bottomRight <= SLOPE_UP_END) { e->y -= e->dirX; e->dirY = 0; e->flags |= ON_GROUND; } else if (bottomRight != BLANK_TILE && bottomRight < BACKGROUND_TILE_START) { e->y = (int)((e->y + e->h - 1) / TILE_SIZE); e->y *= TILE_SIZE; e->y -= e->h + 0.5; e->dirY = 0; e->flags |= ON_GROUND; previous = mapTileAt(x2, (e->y + e->h - 1) / TILE_SIZE); if (previous >= SLOPE_UP_START && previous <= SLOPE_UP_END) { e->y -= e->dirX; e->dirY = 0; e->flags |= ON_GROUND; } } } } else if (bottomRight >= SLOPE_UP_START && bottomRight <= SLOPE_UP_END) { if (i == e->h) { if (!(e->flags & FLY)) { if ((e->flags & BOUNCES) && e->dirY > 4) { e->dirY = -e->dirY * 2 / 3; } else { e->dirY = 0; e->flags |= ON_GROUND; } } else { e->x = x2 * TILE_SIZE; e->x -= e->w; e->dirX = 0; } if (e->type == PROJECTILE) { e->die(); return; } } } else if ((previous >= SLOPE_UP_START && previous <= SLOPE_UP_END) && !(bottomRight >= SLOPE_UP_START && bottomRight <= SLOPE_UP_END)) { } else if (bottomLeft >= SLOPE_DOWN_START && bottomLeft <= SLOPE_DOWN_END) { e->flags |= ON_GROUND; } else if ((topRight >= JUMP_THROUGH_TILE_START && topRight <= JUMP_THROUGH_TILE_END) || ((bottomRight >= JUMP_THROUGH_TILE_START && bottomRight <= JUMP_THROUGH_TILE_END))) { } else if ((topRight != BLANK_TILE && topRight < BACKGROUND_TILE_START) || (bottomRight != BLANK_TILE && bottomRight < BACKGROUND_TILE_START)) { /* Place the player as close to the solid tile as possible */ e->x = x2 * TILE_SIZE; e->x -= e->w; e->dirX = (e->flags & BOUNCES) ? -e->dirX : 0; if ((e->flags & GRABBING) && e->target != NULL) { e->target->dirX = 0; } if (e->type == PROJECTILE) { e->die(); return; } } } else if (e->dirX < 0) { /* Trying to move left */ previous = (e->x) / TILE_SIZE; previous = mapTileAt(previous, y2); if (previous >= SLOPE_DOWN_START && previous <= SLOPE_DOWN_END) { if (i == e->h) { if (bottomLeft >= SLOPE_DOWN_START && bottomLeft <= SLOPE_DOWN_END) { e->y += e->dirX; e->dirY = 0; e->flags |= ON_GROUND; } else if (bottomLeft != BLANK_TILE && bottomLeft < BACKGROUND_TILE_START) { e->y = (int)((e->y + e->h - 1) / TILE_SIZE); e->y *= TILE_SIZE; e->y -= e->h + 0.5; e->dirY = 0; e->flags |= ON_GROUND; previous = mapTileAt(x1, (e->y + e->h - 1) / TILE_SIZE); if (previous >= SLOPE_DOWN_START && previous <= SLOPE_DOWN_END) { e->y += e->dirX; e->dirY = 0; e->flags |= ON_GROUND; } } } } else if (bottomLeft >= SLOPE_DOWN_START && bottomLeft <= SLOPE_DOWN_END) { if (i == e->h) { if (!(e->flags & FLY)) { if ((e->flags & BOUNCES) && e->dirY > 4) { e->dirY = -e->dirY * 2 / 3; } else { e->dirY = 0; e->flags |= ON_GROUND; } } else { e->x = (x1 + 1) * TILE_SIZE; e->dirX = 0; } if (e->type == PROJECTILE) { e->die(); return; } } } else if ((previous >= SLOPE_DOWN_START && previous <= SLOPE_DOWN_END) && !(bottomLeft >= SLOPE_DOWN_START && bottomLeft <= SLOPE_DOWN_END)) { } else if (bottomRight >= SLOPE_UP_START && bottomRight <= SLOPE_UP_END) { e->flags |= ON_GROUND; } else if ((topLeft >= JUMP_THROUGH_TILE_START && topLeft <= JUMP_THROUGH_TILE_END) || ((bottomLeft >= JUMP_THROUGH_TILE_START && bottomLeft <= JUMP_THROUGH_TILE_END))) { } else if ((topLeft != BLANK_TILE && topLeft < BACKGROUND_TILE_START) || (bottomLeft != BLANK_TILE && bottomLeft < BACKGROUND_TILE_START)) { /* Place the player as close to the solid tile as possible */ e->x = (x1 + 1) * TILE_SIZE; e->dirX = (e->flags & BOUNCES) ? -e->dirX : 0; if ((e->flags & GRABBING) && e->target != NULL) { e->target->dirX = 0; } if (e->type == PROJECTILE) { e->die(); return; } } } } /* Exit this loop if we have tested all of the body */ if (i == e->h || e->h <= TILE_SIZE) { break; } /* Test the next block */ i += TILE_SIZE; if (i > e->h) { i = e->h; } } /* Now test the vertical movement */ i = e->w > TILE_SIZE ? TILE_SIZE : e->w; for (;;) { x1 = (e->x) / TILE_SIZE; x2 = (e->x + i - 1) / TILE_SIZE; y1 = (e->y + e->dirY) / TILE_SIZE; y2 = (e->y + e->dirY + e->h - 1) / TILE_SIZE; if (x1 >= 0 && x2 < MAX_MAP_X && y1 >= 0 && y2 < MAX_MAP_Y) { topLeft = mapTileAt(x1, y1); topRight = mapTileAt(x2, y1); bottomLeft = mapTileAt(x1, y2); bottomRight = mapTileAt(x2, y2); if (e->dirY > 0) { /* Trying to move down */ if (bottomRight >= SLOPE_UP_START && bottomRight <= SLOPE_UP_END) { if (i == e->w) { tempX = (int)(e->x + i - 1) % TILE_SIZE; tempY = (int)(e->y + e->dirY + e->h - 1) % TILE_SIZE; tempX = TILE_SIZE - tempX; if (tempY > tempX || wasOnGround != 0) { e->y = y2 * TILE_SIZE; e->y -= e->h; e->y += tempX + 1; if ((e->flags & BOUNCES) && e->dirY > 4) { e->dirY = -e->dirY * 2 / 3; } else { e->dirY = 0; e->flags |= ON_GROUND; } } } if (e->type == PROJECTILE) { e->die(); return; } } else if (bottomLeft >= SLOPE_DOWN_START && bottomLeft <= SLOPE_DOWN_END) { if (i == (e->w > TILE_SIZE ? TILE_SIZE : e->w)) { tempX = (int)(e->x) % TILE_SIZE; tempY = (int)(e->y + e->dirY + e->h - 1) % TILE_SIZE; if (tempY > tempX || wasOnGround != 0) { e->y = y2 * TILE_SIZE; e->y -= e->h; e->y += tempX + 1; if ((e->flags & BOUNCES) && e->dirY > 4) { e->dirY = -e->dirY * 2 / 3; } else { e->dirY = 0; e->flags |= ON_GROUND; } } } if (e->type == PROJECTILE) { e->die(); return; } } else if ((bottomLeft >= JUMP_THROUGH_TILE_START && bottomLeft <= JUMP_THROUGH_TILE_END) || ((bottomRight >= JUMP_THROUGH_TILE_START && bottomRight <= JUMP_THROUGH_TILE_END))) { previousY2 = y2; x1 = (e->x) / TILE_SIZE; x2 = (e->x + i - 1) / TILE_SIZE; y2 = (e->y + e->h - 1) / TILE_SIZE; bottomLeft = mapTileAt(x1, y2); bottomRight = mapTileAt(x2, y2); if (!((bottomLeft >= JUMP_THROUGH_TILE_START && bottomLeft <= JUMP_THROUGH_TILE_END) || ((bottomRight >= JUMP_THROUGH_TILE_START && bottomRight <= JUMP_THROUGH_TILE_END)))) { y2 = previousY2; /* Place the player as close to the solid tile as possible */ e->y = y2 * TILE_SIZE; e->y -= e->h; if ((e->flags & BOUNCES) && e->dirY > 4) { e->dirY = -e->dirY * 2 / 3; } else { e->dirY = 0; e->flags |= ON_GROUND; } } if (e->type == PROJECTILE) { e->die(); return; } } else if ((bottomLeft != BLANK_TILE && bottomLeft < BACKGROUND_TILE_START) || (bottomRight != BLANK_TILE && bottomRight < BACKGROUND_TILE_START)) { /* Place the player as close to the solid tile as possible */ e->y = y2 * TILE_SIZE; e->y -= e->h; if ((e->flags & BOUNCES) && e->dirY > 4) { e->dirY = -e->dirY * 2 / 3; } else { e->dirY = 0; e->flags |= ON_GROUND; } if (e->type == PROJECTILE) { e->die(); return; } } } else if (e->dirY < 0) { /* Trying to move up */ if ((topLeft >= JUMP_THROUGH_TILE_START && topLeft <= JUMP_THROUGH_TILE_END) || ((topRight >= JUMP_THROUGH_TILE_START && topRight <= JUMP_THROUGH_TILE_END))) { } else if ((topLeft != BLANK_TILE && topLeft < BACKGROUND_TILE_START) || (topRight != BLANK_TILE && topRight < BACKGROUND_TILE_START)) { /* Place the player as close to the solid tile as possible */ e->y = (y1 + 1) * TILE_SIZE; e->dirY = (e->flags & BOUNCES) ? -e->dirY : 0; if (e->type == PROJECTILE) { e->die(); return; } } } } if (i == e->w || e->w <= TILE_SIZE) { break; } i += TILE_SIZE; if (i > e->w) { i = e->w; } } /* Now apply the movement */ e->x += e->dirX; e->y += e->dirY; x1 = (e->type == PLAYER || (e->flags & LIMIT_TO_SCREEN)) ? getPlayerMinX() : getMapMinX(); x2 = (e->type == PLAYER || (e->flags & LIMIT_TO_SCREEN)) ? getPlayerMaxX() : getMapMaxX(); y1 = (e->flags & LIMIT_TO_SCREEN) ? getMapStartY() : getMapMinY() - 300; if (e->x < x1) { e->x = x1; e->dirX = 0; if ((e->flags & GRABBING) && e->target != NULL) { e->target->dirX = 0; } if (e->type == PROJECTILE) { e->die(); } } else if (e->x + e->w >= x2) { e->x = x2 - e->w - 1; e->dirX = 0; if ((e->flags & GRABBING) && e->target != NULL) { e->target->dirX = 0; } if (e->type == PROJECTILE) { e->die(); } } if (e->y > getMapMaxY() && e->y - e->dirY <= getMapMaxY()) { e->flags &= ~(HELPLESS|INVULNERABLE); if (e->fallout == NULL) { printf("%s has no fallout defined. Removing\n", e->name); e->inUse = FALSE; return; } else { e->fallout(); } } else if (e->y < y1) { /* Way too high... */ e->y = y1; e->dirY = 0; } x1 = (e->x) / TILE_SIZE; x2 = (e->x + e->w - 1) / TILE_SIZE; y1 = (e->y) / TILE_SIZE; y2 = (e->y + e->h - 1) / TILE_SIZE; topLeft = mapTileAt(x1, y1); topRight = mapTileAt(x2, y1); bottomLeft = mapTileAt(x1, y2); bottomRight = mapTileAt(x2, y2); if ((topLeft >= LAVA_TILE_START && topLeft <= LAVA_TILE_END) || (bottomLeft >= LAVA_TILE_START && bottomLeft <= LAVA_TILE_END) || (topRight >= LAVA_TILE_START && topRight <= LAVA_TILE_END) || (bottomRight >= LAVA_TILE_START && bottomRight <= LAVA_TILE_END)) { e->environment = LAVA; if (previousEnvironment != LAVA && e->fallout != NULL) { /* Fire based entities won't die */ if (e->element != FIRE) { if (e->type != TEMP_ITEM) { playSoundToMap("sound/common/lava", -1, e->x, e->y, 0); } e->flags &= ~(HELPLESS|INVULNERABLE); e->fallout(); } } } else if ((topLeft >= SLIME_TILE_START && topLeft <= SLIME_TILE_BLEND) || (bottomLeft >= SLIME_TILE_START && bottomLeft <= SLIME_TILE_BLEND) || (topRight >= SLIME_TILE_START && topRight <= SLIME_TILE_BLEND) || (bottomRight >= SLIME_TILE_START && bottomRight <= SLIME_TILE_BLEND)) { e->environment = SLIME; if (previousEnvironment != SLIME && e->fallout != NULL) { /* Slime based entities won't die */ if (e->element != SLIME) { if (e->type != TEMP_ITEM) { playSoundToMap("sound/common/slime", -1, e->x, e->y, 0); } e->flags &= ~(HELPLESS|INVULNERABLE); e->fallout(); } } } else { y2 = (e->y + (e->h / 2)) / TILE_SIZE; bottomLeft = mapTileAt(x1, y2); bottomRight = mapTileAt(x2, y2); if ((topLeft >= WATER_TILE_START && topLeft <= WATER_TILE_END) && (bottomLeft >= WATER_TILE_START && bottomLeft <= WATER_TILE_END) && (topRight >= WATER_TILE_START && topRight <= WATER_TILE_END) && (bottomRight >= WATER_TILE_START && bottomRight <= WATER_TILE_END)) { e->environment = WATER; if (previousEnvironment != WATER && e->fallout != NULL) { if (e->type != TEMP_ITEM) { playSoundToMap("sound/common/splash", -1, e->x, e->y, 0); } if (!(e->flags & FLOATS)) { e->flags &= ~(HELPLESS|INVULNERABLE); e->fallout(); } } } } }
int isValidOnMap(Entity *e) { int i, x1, x2, y1, y2; if (e->x < getMapMinX() || e->x + e->w > getMapMaxX() || e->h < 0 || e->y + e->h > getMapMaxY()) { return FALSE; } i = e->w > TILE_SIZE ? TILE_SIZE : e->w; for (;;) { x1 = (e->x) / TILE_SIZE; x2 = (e->x + i - 1) / TILE_SIZE; y1 = (e->y) / TILE_SIZE; y2 = (e->y + e->h - 1) / TILE_SIZE; if ((mapTileAt(x1, y1) < BACKGROUND_TILE_START && mapTileAt(x1, y1) > BLANK_TILE) || (mapTileAt(x2, y1) < BACKGROUND_TILE_START && mapTileAt(x2, y1) > BLANK_TILE) || (mapTileAt(x1, y2) < BACKGROUND_TILE_START && mapTileAt(x1, y2) > BLANK_TILE) || (mapTileAt(x2, y2) < BACKGROUND_TILE_START && mapTileAt(x2, y2) > BLANK_TILE)) { return FALSE; } if (i == e->w) { break; } i += e->w; if (i > e->w) { i = e->w; } } i = e->h > TILE_SIZE ? TILE_SIZE : e->h; for (;;) { x1 = (e->x) / TILE_SIZE; x2 = (e->x + e->w - 1) / TILE_SIZE; y1 = (e->y) / TILE_SIZE; y2 = (e->y + i - 1) / TILE_SIZE; if ((mapTileAt(x1, y1) < BACKGROUND_TILE_START && mapTileAt(x1, y1) > BLANK_TILE) || (mapTileAt(x2, y1) < BACKGROUND_TILE_START && mapTileAt(x2, y1) > BLANK_TILE) || (mapTileAt(x1, y2) < BACKGROUND_TILE_START && mapTileAt(x1, y2) > BLANK_TILE) || (mapTileAt(x2, y2) < BACKGROUND_TILE_START && mapTileAt(x2, y2) > BLANK_TILE)) { return FALSE; } if (i == e->h) { break; } i += e->h; if (i > e->h) { i = e->h; } } return TRUE; }
int isAtCeilingEdge(Entity *e) { int i, tile; int x = e->x + (e->dirX > 0 ? e->w : 0); int y = e->y; x /= TILE_SIZE; y /= TILE_SIZE; y--; tile = mapTileAt(x, y); /* Return immediately if the tile isn't blank */ if (tile != BLANK_TILE && tile < BACKGROUND_TILE_START) { return FALSE; } if (e->w > TILE_SIZE) { if (e->dirX > 0) { for (i=0;;) { x = e->x + i; x /= TILE_SIZE; tile = mapTileAt(x, y); if (tile >= SLOPE_DOWN_START && tile <= SLOPE_DOWN_END) { return FALSE; } if (i == e->w) { break; } i += TILE_SIZE; if (i > e->w) { i = e->w; } } } else { for (i=e->w;;) { x = e->x + i; x /= TILE_SIZE; tile = mapTileAt(x, y); if (tile >= SLOPE_UP_START && tile <= SLOPE_UP_END) { return FALSE; } if (i == 0) { break; } i -= TILE_SIZE; if (i < 0) { i = 0; } } } } return TRUE; }
int isAtEdge(Entity *e) { int i, tile; int x = e->face == LEFT ? floor(e->x) : ceil(e->x) + e->w; int y = e->y + e->h - 1; EntityList *el, *entities; entities = getEntities(); x /= TILE_SIZE; y /= TILE_SIZE; y++; tile = mapTileAt(x, y); /* Return immediately if the tile isn't blank */ if (!(e->flags & ON_GROUND) || (tile != BLANK_TILE && tile < BACKGROUND_TILE_START)) { return FALSE; } if (e->w > TILE_SIZE) { if (e->dirX > 0) { for (i=0;;) { x = e->x + i; x /= TILE_SIZE; tile = mapTileAt(x, y); if (tile >= SLOPE_DOWN_START && tile <= SLOPE_DOWN_END) { return FALSE; } if (i == e->w) { break; } i += TILE_SIZE; if (i > e->w) { i = e->w; } } } else { for (i=e->w;;) { x = e->x + i; x /= TILE_SIZE; tile = mapTileAt(x, y); if (tile >= SLOPE_UP_START && tile <= SLOPE_UP_END) { return FALSE; } if (i == 0) { break; } i -= TILE_SIZE; if (i < 0) { i = 0; } } } } x = e->face == LEFT ? floor(e->x) : ceil(e->x); if (e->face == RIGHT) { x += e->w; } /* There might still be Entities that can be walked on */ for (el=entities->next;el!=NULL;el=el->next) { if (e != el->entity && el->entity->inUse == TRUE && el->entity->touch != NULL && ((el->entity->flags & (PUSHABLE|OBSTACLE)) || (el->entity->type == WEAK_WALL) || (el->entity->type == PRESSURE_PLATE) || (el->entity->type == ANTI_GRAVITY))) { if (collision(x, e->y, 1, e->h + 10, el->entity->x, el->entity->y, el->entity->w, el->entity->h) == TRUE) { return FALSE; } } } return TRUE; }
void doCursor() { char name[MAX_VALUE_LENGTH]; int x, y; cursor.x = input.mouseX; cursor.y = input.mouseY; if (cursor.type == TILES || cursor.snapToGrid == 1) { cursor.x /= TILE_SIZE; cursor.y /= TILE_SIZE; cursor.x *= TILE_SIZE; cursor.y *= TILE_SIZE; } if (cursor.y >= SCREEN_HEIGHT - TILE_SIZE) { cursor.y = SCREEN_HEIGHT - TILE_SIZE * 2; } if (input.left == 1) { mapStartXNext(-TILE_SIZE); } else if (input.right == 1) { mapStartXNext(TILE_SIZE); } if (input.up == 1) { mapStartYNext(-TILE_SIZE); } else if (input.down == 1) { mapStartYNext(TILE_SIZE); } if (input.snap == 1) { cursor.snapToGrid = 1 - cursor.snapToGrid; input.snap = 0; } if (input.activate == 1) { cursor.entity.face = (cursor.entity.face == RIGHT ? LEFT : RIGHT); input.activate = 0; } if (input.block == 1) { if (cursor.type == TILES) { x = (getMapStartX() + cursor.x) / TILE_SIZE; y = (getMapStartY() + cursor.y) / TILE_SIZE; while (mapTileAt(x, y) == BLANK_TILE && x >= 0) { setTileAt(x, y, cursor.tileID); x--; } x = (getMapStartX() + cursor.x) / TILE_SIZE; x++; while (mapTileAt(x, y) == BLANK_TILE && x < MAX_MAP_X) { setTileAt(x, y, cursor.tileID); x++; } } } if (input.add == 1) { if (cursor.type == TILES) { setTileAt((getMapStartX() + cursor.x) / TILE_SIZE, (getMapStartY() + cursor.y) / TILE_SIZE, cursor.tileID); } else { /* Entities can only be placed in blank spaces */ if (isValidOnMap(&cursor.entity) == 1 && isSpaceEmpty(&cursor.entity) == NULL) { if (cursor.entityType == 0) { setPlayerLocation(getMapStartX() + cursor.x, getMapStartY() + cursor.y); } else { if (strcmpignorecase(cursor.entity.name, "lift/lift_target") == 0) { snprintf(name, sizeof(name), "NEW_TARGET_%03d", targetID); addTarget(getMapStartX() + cursor.x, getMapStartY() + cursor.y, name); targetID++; } else { cursor.entity.startX = getMapStartX() + cursor.x; cursor.entity.startY = getMapStartY() + cursor.y; cursor.entity.endX = getMapStartX() + cursor.x; cursor.entity.endY = getMapStartY() + cursor.y; addEntity(cursor.entity, getMapStartX() + cursor.x, getMapStartY() + cursor.y); } } } input.add = 0; } } else if (input.remove == 1) { if (cursor.type == TILES) { setTileAt((getMapStartX() + cursor.x) / TILE_SIZE, (getMapStartY() + cursor.y) / TILE_SIZE, BLANK_TILE); } else { self = isSpaceEmpty(&cursor.entity); if (self != NULL) { self->inUse = FALSE; } } } if (input.cut == 1) { if (cursor.type != TILES) { self = isSpaceEmpty(&cursor.entity); if (self != NULL) { cursor.entity = *self; self->inUse = FALSE; } } input.cut = 0; } if (input.previous == 1) { if (cursor.type == TILES) { cursor.tileID = prevTile(cursor.tileID); } else { cursor.entityType--; if (cursor.entityType < 0) { cursor.entityType = entityNamesLength - 1; } memset(&cursor.entity, 0, sizeof(Entity)); cursor.entity.draw = &drawLoopingAnimationToMap; cursor.entity.weight = 0; cursor.entity.originalWeight = 0; cursor.entity.inUse = TRUE; loadProperties(entityNames[cursor.entityType], &cursor.entity); cursor.entity.active = TRUE; cursor.entity.alpha = 255; if (cursor.entity.weight == 0) { cursor.entity.weight = 1; cursor.entity.originalWeight = 1; } } input.previous = 0; } else if (input.next == 1) { if (cursor.type == TILES) { cursor.tileID = nextTile(cursor.tileID); } else { cursor.entityType++; if (cursor.entityType >= entityNamesLength) { cursor.entityType = 0; } memset(&cursor.entity, 0, sizeof(Entity)); cursor.entity.draw = &drawLoopingAnimationToMap; cursor.entity.weight = 0; cursor.entity.originalWeight = 1; cursor.entity.inUse = TRUE; loadProperties(entityNames[cursor.entityType], &cursor.entity); cursor.entity.active = TRUE; cursor.entity.alpha = 255; if (cursor.entity.weight == 0) { cursor.entity.weight = 1; cursor.entity.originalWeight = 1; } } input.next = 0; } if (input.save == 1) { if (saveMap() == TRUE) { setStatusPanelMessage("Saved"); } else { setStatusPanelMessage("Saving Failed"); } input.save = 0; } /* if (input.load == 1) { loadMap(map.filename); printf("Loaded\n"); input.load = 0; } */ if (input.left == 1 || input.right == 1 || input.up == 1 || input.down == 1) { SDL_Delay(30); } if (input.toggle == 1) { if (cursor.type == TILES) { cursor.type = ENTITIES; } else { cursor.type = TILES; } input.toggle = 0; } centerMapOnEntity(NULL); }