예제 #1
0
/**
 * 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;
}
예제 #2
0
파일: mentat.c 프로젝트: damajor/play-dune
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);
}
예제 #3
0
파일: house.c 프로젝트: damajor/play-dune
/**
 * 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);
		}
	}
}
예제 #4
0
파일: mentat.c 프로젝트: damajor/play-dune
/**
 * 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();
	}
}