/** * Handle clicks on the Mentat widget. * @return True, always. */ bool GUI_Widget_Mentat_Click(Widget *w) { VARIABLE_NOT_USED(w); g_cursorSpriteID = 0; Sprites_SetMouseSprite(0, 0, g_sprites[0]); Sound_Output_Feedback(0xFFFE); Driver_Voice_Play(NULL, 0xFF); Music_Play(g_table_houseInfo[g_playerHouseID].musicBriefing); Sprites_UnloadTiles(); Timer_SetTimer(TIMER_GAME, false); GUI_Mentat_ShowHelpList(false); Timer_SetTimer(TIMER_GAME, true); Driver_Sound_Play(1, 0xFF); Sprites_LoadTiles(); g_textDisplayNeedsUpdate = true; GUI_DrawInterfaceAndRadar(0); Music_Play(Tools_RandomRange(0, 5) + 8); return true; }
void GUI_Widget_Mentat_Click_Close() { Timer_SetTimer(TIMER_GAME, true); Driver_Sound_Play(1, 0xFF); Sprites_LoadTiles(); g_textDisplayNeedsUpdate = true; GUI_DrawInterfaceAndRadar(0); Music_Play(Tools_RandomRange(0, 5) + 8); }
/** * Loop over all houses, preforming various of tasks. */ void GameLoop_House() { PoolFindStruct find; House *h = NULL; bool tickHouse = false; bool tickPowerMaintenance = false; bool tickStarport = false; bool tickReinforcement = false; bool tickMissileCountdown = false; bool tickStarportAvailability = false; if (g_debugScenario) return; if (s_tickHouseHouse <= g_timerGame) { tickHouse = true; s_tickHouseHouse = g_timerGame + 900; } if (g_tickHousePowerMaintenance <= g_timerGame) { tickPowerMaintenance = true; g_tickHousePowerMaintenance = g_timerGame + 10800; } if (s_tickHouseStarport <= g_timerGame) { tickStarport = true; s_tickHouseStarport = g_timerGame + 180; } if (s_tickHouseReinforcement <= g_timerGame) { tickReinforcement = true; s_tickHouseReinforcement = g_timerGame + (g_debugGame ? 60 : 600); } if (s_tickHouseMissileCountdown <= g_timerGame) { tickMissileCountdown = true; s_tickHouseMissileCountdown = g_timerGame + 60; } if (s_tickHouseStarportAvailability <= g_timerGame) { tickStarportAvailability = true; s_tickHouseStarportAvailability = g_timerGame + 1800; } if (tickMissileCountdown && g_houseMissileCountdown != 0) { g_houseMissileCountdown--; Sound_Output_Feedback(g_houseMissileCountdown + 41); if (g_houseMissileCountdown == 0) Unit_LaunchHouseMissile(Map_FindLocationTile(4, g_playerHouseID)); } if (tickStarportAvailability) { uint16 type; /* Pick a random unit to increase starport availability */ type = Tools_RandomRange(0, UNIT_MAX - 1); /* Increase how many of this unit is available via starport by one */ if (g_starportAvailable[type] != 0 && g_starportAvailable[type] < 10) { if (g_starportAvailable[type] == -1) { g_starportAvailable[type] = 1; } else { g_starportAvailable[type]++; } } } if (tickReinforcement) { Unit *nu = NULL; int i; for (i = 0; i < 16; i++) { uint16 locationID; bool deployed; Unit *u; if (g_scenario.reinforcement[i].unitID == UNIT_INDEX_INVALID) continue; if (g_scenario.reinforcement[i].timeLeft == 0) continue; if (--g_scenario.reinforcement[i].timeLeft != 0) continue; u = Unit_Get_ByIndex(g_scenario.reinforcement[i].unitID); locationID = g_scenario.reinforcement[i].locationID; deployed = false; if (locationID >= 4) { if (nu == NULL) { nu = Unit_Create(UNIT_INDEX_INVALID, UNIT_CARRYALL, u->o.houseID, Tile_UnpackTile(Map_FindLocationTile(Tools_Random_256() & 3, u->o.houseID)), 100); if (nu != NULL) { nu->o.flags.s.byScenario = true; Unit_SetDestination(nu, Tools_Index_Encode(Map_FindLocationTile(locationID, u->o.houseID), IT_TILE)); } } if (nu != NULL) { u->o.linkedID = nu->o.linkedID; nu->o.linkedID = (uint8)u->o.index; nu->o.flags.s.inTransport = true; g_scenario.reinforcement[i].unitID = UNIT_INDEX_INVALID; deployed = true; } else { /* Failed to create carry-all, try again in a short moment */ g_scenario.reinforcement[i].timeLeft = 1; } } else { deployed = Unit_SetPosition(u, Tile_UnpackTile(Map_FindLocationTile(locationID, u->o.houseID))); } if (deployed && g_scenario.reinforcement[i].repeat != 0) { tile32 tile; tile.tile = 0xFFFFFFFF; g_var_38BC++; u = Unit_Create(UNIT_INDEX_INVALID, u->o.type, u->o.houseID, tile, 0); g_var_38BC--; if (u != NULL) { g_scenario.reinforcement[i].unitID = u->o.index; g_scenario.reinforcement[i].timeLeft = g_scenario.reinforcement[i].timeBetween; } } } } find.houseID = HOUSE_INVALID; find.index = 0xFFFF; find.type = 0xFFFF; while (true) { h = House_Find(&find); if (h == NULL) break; if (tickHouse) { /* ENHANCEMENT -- Originally this code was outside the house loop, which seems very odd. * This problem is considered to be so bad, that the original code has been removed. */ if (h->index != g_playerHouseID) { if (h->creditsStorage < h->credits) { h->credits = h->creditsStorage; } } else { uint16 maxCredits = max(h->creditsStorage, g_playerCreditsNoSilo); if (h->credits > maxCredits) { h->credits = maxCredits; GUI_DisplayText(String_Get_ByIndex(STR_INSUFFICIENT_SPICE_STORAGE_AVAILABLE_SPICE_IS_LOST), 1); } } if (h->index == g_playerHouseID) { if (h->creditsStorage > g_playerCreditsNoSilo) { g_playerCreditsNoSilo = 0; } if (g_playerCreditsNoSilo == 0 && g_campaignID > 1 && h->credits != 0) { if (h->creditsStorage != 0 && ((h->credits * 256 / h->creditsStorage) > 200)) { GUI_DisplayText(String_Get_ByIndex(STR_SPICE_STORAGE_CAPACITY_LOW_BUILD_SILOS), 0); } } if (h->credits < 100 && g_playerCreditsNoSilo != 0) { GUI_DisplayText(String_Get_ByIndex(STR_CREDITS_ARE_LOW_HARVEST_SPICE_FOR_MORE_CREDITS), 0); } } } if (tickHouse) House_EnsureHarvesterAvailable((uint8)h->index); if (tickStarport && h->starportLinkedID != UNIT_INDEX_INVALID) { Unit *u = NULL; h->starportTimeLeft--; if ((int16)h->starportTimeLeft < 0) h->starportTimeLeft = 0; if (h->starportTimeLeft == 0) { Structure *s; s = Structure_Get_ByIndex(g_structureIndex); if (s->o.type == STRUCTURE_STARPORT && s->o.houseID == h->index) { u = Unit_CreateWrapper((uint8)h->index, UNIT_FRIGATE, Tools_Index_Encode(s->o.index, IT_STRUCTURE)); if (u != NULL) { u->o.linkedID = (uint8)h->starportLinkedID; h->starportLinkedID = UNIT_INDEX_INVALID; u->o.flags.s.inTransport = true; Sound_Output_Feedback(38); } } else { PoolFindStruct find2; find2.houseID = h->index; find2.index = 0xFFFF; find2.type = STRUCTURE_STARPORT; while (true) { s = Structure_Find(&find2); if (s == NULL) break; if (s->o.linkedID != 0xFF) continue; u = Unit_CreateWrapper((uint8)h->index, UNIT_FRIGATE, Tools_Index_Encode(s->o.index, IT_STRUCTURE)); if (u != NULL) { u->o.linkedID = (uint8)h->starportLinkedID; h->starportLinkedID = 0xFFFF; u->o.flags.s.inTransport = true; Sound_Output_Feedback(38); } } } h->starportTimeLeft = (u != NULL) ? g_table_houseInfo[h->index].starportDeliveryTime : 1; } } if (tickHouse) { House_CalculatePowerAndCredit(h); Structure_CalculateHitpointsMax(h); if (h->timerUnitAttack != 0) h->timerUnitAttack--; if (h->timerSandwormAttack != 0) h->timerSandwormAttack--; if (h->timerStructureAttack != 0) h->timerStructureAttack--; if (h->harvestersIncoming > 0 && Unit_CreateWrapper((uint8)h->index, UNIT_HARVESTER, 0) != NULL) h->harvestersIncoming--; } if (tickPowerMaintenance) { uint16 powerMaintenanceCost = (h->powerUsage / 32) + 1; h->credits -= min(h->credits, powerMaintenanceCost); } } }
/** * Draw sprites and handle mouse in a mentat screen. * @param speakingMode If \c 1, the mentat is speaking. */ void GUI_Mentat_Animation(uint16 speakingMode) { static uint32 movingEyesTimer = 0; /* Timer when to change the eyes sprite. */ static uint16 movingEyesSprite = 0; /* Index in _mentatSprites of the displayed moving eyes. */ static uint16 movingEyesNextSprite = 0; /* If not 0, it decides the movingEyesNextSprite */ static uint32 movingMouthTimer = 0; static uint16 movingMouthSprite = 0; static uint32 movingOtherTimer = 0; static int16 otherSprite = 0; bool partNeedsRedraw; uint16 i; if (movingOtherTimer < g_timerGUI && !g_disableOtherMovement) { if (movingOtherTimer != 0) { uint8 *sprite; if (s_mentatSprites[2][1 + abs(otherSprite)] == NULL) { otherSprite = 1 - otherSprite; } else { otherSprite++; } sprite = s_mentatSprites[2][abs(otherSprite)]; GUI_Mouse_Hide_InRegion(s_otherLeft, s_otherTop, s_otherLeft + Sprite_GetWidth(sprite), s_otherTop + Sprite_GetHeight(sprite)); GUI_DrawSprite(0, sprite, s_otherLeft, s_otherTop, 0, 0); GUI_Mouse_Show_InRegion(); } switch (g_playerHouseID) { case HOUSE_HARKONNEN: movingOtherTimer = g_timerGUI + 300 * 60; break; case HOUSE_ATREIDES: movingOtherTimer = g_timerGUI + 60 * Tools_RandomRange(1,3); break; case HOUSE_ORDOS: if (otherSprite != 0) { movingOtherTimer = g_timerGUI + 6; } else { movingOtherTimer = g_timerGUI + 60 * Tools_RandomRange(10, 19); } break; default: break; } } if (speakingMode == 1) { if (movingMouthTimer < g_timerGUI) { uint8 *sprite; movingMouthSprite = Tools_RandomRange(0, 4); sprite = s_mentatSprites[1][movingMouthSprite]; GUI_Mouse_Hide_InRegion(s_mouthLeft, s_mouthTop, s_mouthLeft + Sprite_GetWidth(sprite), s_mouthTop + Sprite_GetHeight(sprite)); GUI_DrawSprite(0, sprite, s_mouthLeft, s_mouthTop, 0, 0); GUI_Mouse_Show_InRegion(); switch (movingMouthSprite) { case 0: movingMouthTimer = g_timerGUI + Tools_RandomRange(7, 30); break; case 1: case 2: case 3: movingMouthTimer = g_timerGUI + Tools_RandomRange(6, 10); break; case 4: movingMouthTimer = g_timerGUI + Tools_RandomRange(5, 6); break; default: break; } } } else { partNeedsRedraw = false; if (Input_Test(0x41) == 0 && Input_Test(0x42) == 0) { if (movingMouthSprite != 0) { movingMouthSprite = 0; movingMouthTimer = 0; partNeedsRedraw = true; } } else if (Mouse_InsideRegion(s_mouthLeft, s_mouthTop, s_mouthRight, s_mouthBottom) != 0) { if (movingMouthTimer != 0xFFFFFFFF) { movingMouthTimer = 0xFFFFFFFF; movingMouthSprite = Tools_RandomRange(1, 4); partNeedsRedraw = true; } } else { if (movingMouthSprite != 0) { movingMouthSprite = 0; movingMouthTimer = 0; partNeedsRedraw = true; } } if (partNeedsRedraw) { uint8 *sprite; sprite = s_mentatSprites[1][movingMouthSprite]; GUI_Mouse_Hide_InRegion(s_mouthLeft, s_mouthTop, s_mouthLeft + Sprite_GetWidth(sprite), s_mouthTop + Sprite_GetHeight(sprite)); GUI_DrawSprite(0, sprite, s_mouthLeft, s_mouthTop, 0, 0); GUI_Mouse_Show_InRegion(); } } partNeedsRedraw = false; if (Input_Test(0x41) != 0 || Input_Test(0x42) != 0) { if (Mouse_InsideRegion(s_eyesLeft, s_eyesTop, s_eyesRight, s_eyesBottom) != 0) { if (movingEyesSprite != 0x4) { partNeedsRedraw = true; movingEyesSprite = (movingEyesSprite == 3) ? 4 : 3; movingEyesNextSprite = 0; movingEyesTimer = 0; } if (partNeedsRedraw) { uint8 *sprite; sprite = s_mentatSprites[0][movingEyesSprite]; GUI_Mouse_Hide_InRegion(s_eyesLeft, s_eyesTop, s_eyesLeft + Sprite_GetWidth(sprite), s_eyesTop + Sprite_GetHeight(sprite)); GUI_DrawSprite(0, sprite, s_eyesLeft, s_eyesTop, 0, 0); GUI_Mouse_Show_InRegion(); } return; } } if (Mouse_InsideRegion((int16)s_eyesLeft - 16, (int16)s_eyesTop - 8, s_eyesRight + 16, s_eyesBottom + 24) != 0) { if (Mouse_InsideRegion((int16)s_eyesLeft - 8, s_eyesBottom, s_eyesRight + 8, SCREEN_HEIGHT - 1) != 0) { i = 3; } else { if (Mouse_InsideRegion(s_eyesRight, (int16)s_eyesTop - 8, s_eyesRight + 16, s_eyesBottom + 8) != 0) { i = 2; } else { i = (Mouse_InsideRegion((int16)s_eyesLeft - 16, (int16)s_eyesTop - 8, s_eyesLeft, s_eyesBottom + 8) == 0) ? 0 : 1; } } if (i != movingEyesSprite) { partNeedsRedraw = true; movingEyesSprite = i; movingEyesNextSprite = 0; movingEyesTimer = g_timerGUI; } } else { if (movingEyesTimer >= g_timerGUI) return; partNeedsRedraw = true; if (movingEyesNextSprite != 0) { movingEyesSprite = movingEyesNextSprite; movingEyesNextSprite = 0; if (movingEyesSprite != 4) { movingEyesTimer = g_timerGUI + Tools_RandomRange(20, 180); } else { movingEyesTimer = g_timerGUI + Tools_RandomRange(12, 30); } } else { i = 0; switch (speakingMode) { case 0: i = Tools_RandomRange(0, 7); if (i > 5) { i = 1; } else { if (i == 5) { i = 4; } } break; case 1: if (movingEyesSprite != ((!g_interrogation) ? 0 : 3)) { i = 0; } else { i = Tools_RandomRange(0, 17); if (i > 9) { i = 0; } else { if (i >= 5) { i = 4; } } } break; default: i = Tools_RandomRange(0, 15); if (i > 10) { i = 2; } else { if (i >= 5) { i = 4; } } break; } if ((i == 2 && movingEyesSprite == 1) || (i == 1 && movingEyesSprite == 2)) { movingEyesNextSprite = i; movingEyesSprite = 0; movingEyesTimer = g_timerGUI + Tools_RandomRange(1, 5); } else { if (i != movingEyesSprite && (i == 4 || movingEyesSprite == 4)) { movingEyesNextSprite = i; movingEyesSprite = 3; movingEyesTimer = g_timerGUI; } else { movingEyesSprite = i; if (i != 4) { movingEyesTimer = g_timerGUI + Tools_RandomRange(15, 180); } else { movingEyesTimer = g_timerGUI + Tools_RandomRange(6, 60); } } } if (g_interrogation && movingEyesSprite == 0) movingEyesSprite = 3; } } if (partNeedsRedraw) { uint8 *sprite; sprite = s_mentatSprites[0][movingEyesSprite]; GUI_Mouse_Hide_InRegion(s_eyesLeft, s_eyesTop, s_eyesLeft + Sprite_GetWidth(sprite), s_eyesTop + Sprite_GetHeight(sprite)); GUI_DrawSprite(0, sprite, s_eyesLeft, s_eyesTop, 0, 0); GUI_Mouse_Show_InRegion(); } }