/** * Handle damage to a tile, removing spice, removing concrete, stuff like that. * @param e The Explosion to handle damage on. * @param parameter Unused parameter. */ static void Explosion_Func_TileDamage(Explosion *e, uint16 parameter) { static const int16 craterIconMapIndex[] = { -1, 2, 1 }; uint16 packed; uint16 type; Tile *t; int16 iconMapIndex; uint16 overlaySpriteID; uint16 *iconMap; VARIABLE_NOT_USED(parameter); packed = Tile_PackTile(e->position); if (!Map_IsPositionUnveiled(packed)) return; type = Map_GetLandscapeType(packed); if (type == LST_STRUCTURE || type == LST_DESTROYED_WALL) return; t = &g_map[packed]; if (type == LST_CONCRETE_SLAB) { t->groundSpriteID = g_mapSpriteID[packed]; Map_Update(packed, 0, false); } if (g_table_landscapeInfo[type].craterType == 0) return; /* You cannot damage veiled tiles */ overlaySpriteID = t->overlaySpriteID; if (!Sprite_IsUnveiled(overlaySpriteID)) return; iconMapIndex = craterIconMapIndex[g_table_landscapeInfo[type].craterType]; iconMap = &g_iconMap[g_iconMap[iconMapIndex]]; if (iconMap[0] <= overlaySpriteID && overlaySpriteID <= iconMap[10]) { /* There already is a crater; make it bigger */ overlaySpriteID -= iconMap[0]; if (overlaySpriteID < 4) overlaySpriteID += 2; } else { /* Randomly pick 1 of the 2 possible craters */ overlaySpriteID = Tools_Random_256() & 1; } /* Reduce spice if there is any */ Map_ChangeSpiceAmount(packed, -1); /* Boom a bloom if there is one */ if (t->groundSpriteID == g_bloomSpriteID) { Map_Bloom_ExplodeSpice(packed, g_playerHouseID); return; } /* Update the tile with the crater */ t->overlaySpriteID = overlaySpriteID + iconMap[0]; Map_Update(packed, 0, false); }
/** * Stop with this Animation. * @param animation The Animation to stop. * @param parameter Not used. */ static void Animation_Func_Stop(Animation *animation, int16 parameter) { const uint16 *layout = g_table_structure_layoutTiles[animation->tileLayout]; uint16 packed = Tile_PackTile(animation->tile); Tile *t = &g_map[packed]; int i; VARIABLE_NOT_USED(parameter); t->hasAnimation = false; animation->commands = NULL; for (i = 0; i < g_table_structure_layoutTileCount[animation->tileLayout]; i++) { uint16 position = packed + (*layout++); if (animation->tileLayout != 0) { g_map[position].groundSpriteID = g_mapSpriteID[position]; } if (Map_IsPositionUnveiled(position)) { g_map[position].overlaySpriteID = 0; } Map_Update(position, 0, false); } }
int main() { ClearVram(); SetTileTable(graphicsTiles); Screen.overlayTileTable = overlayTiles; for(int y=0;y<32;y++){ for(int x=0;x<32;x++){ SetTile(x,y,0); } } Screen.scrollHeight = SCREEN_SCROLL_HEIGHT; Screen.overlayHeight = SCREEN_OVERLAY_HEIGHT; Map_Init(); int cameraSpeed = 1; while(1) { uint16_t joypad = ReadJoypad(0); if((joypad & BTN_A)) { cameraSpeed = 4; } else { cameraSpeed = 1; } if((joypad & BTN_LEFT) && Camera_Position.x > cameraSpeed) { Camera_Position.x -= cameraSpeed; } if((joypad & BTN_RIGHT) && Camera_Position.x < (Map_Header.width - MAP_TILE_SCROLL_WRAP_X - 1) * MAP_TILE_PIXEL_SIZE - cameraSpeed) { Camera_Position.x += cameraSpeed; } if((joypad & BTN_UP) && Camera_Position.y > cameraSpeed) { Camera_Position.y -= cameraSpeed; } if((joypad & BTN_DOWN) && Camera_Position.y < (Map_Header.height - MAP_TILE_SCROLL_WRAP_Y - 1) * MAP_TILE_PIXEL_SIZE - cameraSpeed) { Camera_Position.y += cameraSpeed; } Map_Update(); // Screen.scrollX = Camera_Position.x; // Screen.scrollY = Camera_Position.y; WaitVsync(1); } return 0; }
/** * Rotate the turret to look at a tile. * * Stack: 1 - Tile to look at. * * @param script The script engine to operate on. * @return 0 if looking at target, otherwise 1. */ uint16 Script_Structure_RotateTurret(ScriptEngine *script) { Structure *s; tile32 lookAt; Tile *tile; uint16 baseSpriteID; uint16 encoded; int16 rotation; int16 rotationNeeded; int16 rotateDiff; encoded = STACK_PEEK(1); if (encoded == 0) return 0; s = g_scriptCurrentStructure; lookAt = Tools_Index_GetTile(encoded); tile = &g_map[Tile_PackTile(s->o.position)]; /* Find the base sprite of the structure */ if (s->o.type == STRUCTURE_ROCKET_TURRET) { baseSpriteID = g_iconMap[g_iconMap[ICM_ICONGROUP_BASE_ROCKET_TURRET] + 2]; } else { baseSpriteID = g_iconMap[g_iconMap[ICM_ICONGROUP_BASE_DEFENSE_TURRET] + 2]; } rotation = tile->groundSpriteID - baseSpriteID; if (rotation < 0 || rotation > 7) return 1; /* Find what rotation we should have to look at the target */ rotationNeeded = Orientation_Orientation256ToOrientation8(Tile_GetDirection(s->o.position, lookAt)); /* Do we need to rotate */ if (rotationNeeded == rotation) return 0; /* Find the fastest way to rotate to the correct rotation */ rotateDiff = rotationNeeded - rotation; if (rotateDiff < 0) rotateDiff += 8; if (rotateDiff < 4) { rotation++; } else { rotation--; } rotation &= 0x7; /* Set the new sprites */ tile->groundSpriteID = baseSpriteID + rotation; s->rotationSpriteDiff = rotation; Map_Update(Tile_PackTile(s->o.position), 0, false); return 1; }
/** * Abort this Animation. * @param animation The Animation to abort. * @param parameter Not used. */ static void Animation_Func_Abort(Animation *animation, int16 parameter) { uint16 packed = Tile_PackTile(animation->tile); Tile *t = &g_map[packed]; VARIABLE_NOT_USED(parameter); t->hasAnimation = false; animation->commands = NULL; Map_Update(packed, 0, false); }
/** * Set the overlay sprite of the tile. * @param animation The Animation for which we change the overlay sprite. * @param parameter The SpriteID to which the overlay sprite is set. */ static void Animation_Func_SetOverlaySprite(Animation *animation, int16 parameter) { uint16 packed = Tile_PackTile(animation->tile); Tile *t = &g_map[packed]; assert(parameter >= 0); if (!Map_IsPositionUnveiled(packed)) return; t->overlaySpriteID = g_iconMap[g_iconMap[animation->iconGroup] + parameter]; t->houseID = animation->houseID; Map_Update(packed, 0, false); }
/** * Set the ground sprite of the tile. * @param animation The Animation for which we change the ground sprite. * @param parameter The offset in the iconGroup to which the ground sprite is set. */ static void Animation_Func_SetGroundSprite(Animation *animation, int16 parameter) { uint16 specialMap[1]; uint16 *iconMap; const uint16 *layout = g_table_structure_layoutTiles[animation->tileLayout]; uint16 packed = Tile_PackTile(animation->tile); uint16 layoutTileCount; int i; layoutTileCount = g_table_structure_layoutTileCount[animation->tileLayout]; iconMap = &g_iconMap[g_iconMap[animation->iconGroup] + layoutTileCount * parameter]; /* Some special case for turrets */ if (parameter > 1 && (animation->iconGroup == 23 || animation->iconGroup == 24)) { Structure *s = Structure_Get_ByPackedTile(packed); assert(s != NULL); assert(layoutTileCount == 1); specialMap[0] = s->rotationSpriteDiff + g_iconMap[g_iconMap[animation->iconGroup]] + 2; iconMap = &specialMap[0]; } for (i = 0; i < layoutTileCount; i++) { uint16 position = packed + (*layout++); uint16 spriteID = *iconMap++; Tile *t = &g_map[position]; if (t->groundSpriteID == spriteID) continue; t->groundSpriteID = spriteID; t->houseID = animation->houseID; if (Map_IsPositionUnveiled(position)) { t->overlaySpriteID = 0; } Map_Update(position, 0, false); Map_MarkTileDirty(position); } }