/** * Get a random tile around the Unit. * * Stack: 1 - An encoded index of a tile, completely ignored, as long as it is a tile. * * @param script The script engine to operate on. * @return An encoded tile, or 0. */ uint16 Script_Unit_GetRandomTile(ScriptEngine *script) { Unit *u; tile32 tile; u = g_scriptCurrentUnit; if (Tools_Index_GetType(STACK_PEEK(1)) != IT_TILE) return 0; tile = Tile_MoveByRandom(u->o.position, 80, true); return Tools_Index_Encode(Tile_PackTile(tile), IT_TILE); }
/** * Destroy a structure and spawn soldiers around the place. * * Stack: *none* * * @param script The script engine to operate on. * @return Always 0. */ uint16 Script_Structure_Destroy(ScriptEngine *script) { Structure *s; uint16 position; uint16 layout; uint16 i; VARIABLE_NOT_USED(script); s = g_scriptCurrentStructure; layout = g_table_structureInfo[s->o.type].layout; position = Tile_PackTile(s->o.position); Structure_Remove(s); for (i = 0; i < g_table_structure_layoutTileCount[layout]; i++) { tile32 tile; Unit *u; tile = Tile_UnpackTile(position + g_table_structure_layoutTiles[layout][i]); if (g_table_structureInfo[s->o.type].o.spawnChance < Tools_Random_256()) continue; u = Unit_Create(UNIT_INDEX_INVALID, UNIT_SOLDIER, s->o.houseID, tile, Tools_Random_256()); if (u == NULL) continue; u->o.hitpoints = g_table_unitInfo[UNIT_SOLDIER].o.hitpoints * (Tools_Random_256() & 3) / 256; if (s->o.houseID != g_playerHouseID) { Unit_SetAction(u, ACTION_ATTACK); continue; } Unit_SetAction(u, ACTION_MOVE); tile = Tile_MoveByRandom(u->o.position, 32, true); u->targetMove = Tools_Index_Encode(Tile_PackTile(tile), IT_TILE); } if (g_debugScenario) return 0; if (s->o.houseID != g_playerHouseID) return 0; if (g_config.language == LANGUAGE_FRENCH) { GUI_DisplayText("%s %s %s", 0, String_Get_ByIndex(g_table_structureInfo[s->o.type].o.stringID_full), g_table_houseInfo[s->o.houseID].name, String_Get_ByIndex(0x85)); } else { GUI_DisplayText("%s %s %s", 0, g_table_houseInfo[s->o.houseID].name, String_Get_ByIndex(g_table_structureInfo[s->o.type].o.stringID_full), String_Get_ByIndex(0x85)); } return 0; }
/** * Unknown function 0543. * * Stack: 1 - A distance. * * @param script The script engine to operate on. * @return The number of moving units. */ uint16 Script_Team_Unknown0543(ScriptEngine *script) { Team *t; uint16 count = 0; uint16 distance; PoolFindStruct find; t = g_scriptCurrentTeam; distance = STACK_PEEK(1); find.houseID = t->houseID; find.index = 0xFFFF; find.type = 0xFFFF; while (true) { Unit *u; tile32 tile; uint16 distanceUnitDest; uint16 distanceUnitTeam; uint16 distanceTeamDest; u = Unit_Find(&find); if (u == NULL) break; if (t->index != u->team - 1) continue; tile = Tools_Index_GetTile(u->targetMove); distanceUnitTeam = Tile_GetDistanceRoundedUp(u->o.position, t->position); if (u->targetMove != 0) { distanceUnitDest = Tile_GetDistanceRoundedUp(u->o.position, tile); distanceTeamDest = Tile_GetDistanceRoundedUp(t->position, tile); } else { distanceUnitDest = 64; distanceTeamDest = 64; } if ((distanceUnitDest < distanceTeamDest && (distance + 2) < distanceUnitTeam) || (distanceUnitDest >= distanceTeamDest && distanceUnitTeam > distance)) { Unit_SetAction(u, ACTION_MOVE); tile = Tile_MoveByRandom(t->position, distance << 4, true); Unit_SetDestination(u, Tools_Index_Encode(Tile_PackTile(tile), IT_TILE)); count++; continue; } Unit_SetAction(u, ACTION_GUARD); } return count; }
/** * Make 8 explosions: 1 at the unit, and 7 around him. * It does damage to the surrounding units with predefined damage, but * anonymous. * * Stack: 1 - The radius of the 7 explosions. * * @param script The script engine to operate on. * @return The value 0. Always. */ uint16 Script_Unit_ExplosionMultiple(ScriptEngine *script) { Unit *u; uint8 i; u = g_scriptCurrentUnit; Map_MakeExplosion(EXPLOSION_DEATH_HAND, u->o.position, Tools_RandomLCG_Range(25, 50), 0); for (i = 0; i < 7; i++) { Map_MakeExplosion(EXPLOSION_DEATH_HAND, Tile_MoveByRandom(u->o.position, STACK_PEEK(1), false), Tools_RandomLCG_Range(75, 150), 0); } return 0; }
/** * Create a new soldier unit. * * Stack: 1 - Action for the new Unit. * * @param script The script engine to operate on. * @return 1 if a new Unit has been created, 0 otherwise. */ uint16 Script_Unit_RandomSoldier(ScriptEngine *script) { Unit *u; Unit *nu; tile32 position; u = g_scriptCurrentUnit; if (Tools_Random_256() >= g_table_unitInfo[u->o.type].o.spawnChance) return 0; position = Tile_MoveByRandom(u->o.position, 20, true); nu = Unit_Create(UNIT_INDEX_INVALID, UNIT_SOLDIER, u->o.houseID, position, Tools_Random_256()); if (nu == NULL) return 0; nu->deviated = u->deviated; Unit_SetAction(nu, STACK_PEEK(1)); return 1; }