diff --git a/sc2/src/msvc++/UrQuanMasters.dsp b/sc2/src/msvc++/UrQuanMasters.dsp index 03e1b3f9b..ccead8ab7 100644 --- a/sc2/src/msvc++/UrQuanMasters.dsp +++ b/sc2/src/msvc++/UrQuanMasters.dsp @@ -4048,6 +4048,10 @@ SOURCE=..\sc2code\grpinfo.c # End Source File # Begin Source File +SOURCE=..\sc2code\grpinfo.h +# End Source File +# Begin Source File + SOURCE=..\sc2code\hyper.c # End Source File # Begin Source File diff --git a/sc2/src/sc2code/build.c b/sc2/src/sc2code/build.c index 229d9e4fc..7f3838d5b 100644 --- a/sc2/src/sc2code/build.c +++ b/sc2/src/sc2code/build.c @@ -136,7 +136,7 @@ ActivateStarShip (COUNT which_ship, SIZE state) which_ship = 0; } else if (FleetPtr->known_strength == 0 - && FleetPtr->actual_strength != (COUNT)~0) + && FleetPtr->actual_strength != INFINITE_RADIUS) { FleetPtr->known_strength = 1; FleetPtr->known_loc = FleetPtr->loc; @@ -160,7 +160,7 @@ ActivateStarShip (COUNT which_ship, SIZE state) StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); hNextShip = _GetSuccLink (StarShipPtr); - total += ShipCost[GET_RACE_ID (StarShipPtr)]; + total += ShipCost[StarShipPtr->race_id]; UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); } return total; @@ -177,7 +177,7 @@ ActivateStarShip (COUNT which_ship, SIZE state) StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); hNextShip = _GetSuccLink (StarShipPtr); - ship_type = GET_RACE_ID (StarShipPtr); + ship_type = StarShipPtr->race_id; UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); if (ship_type == which_ship) @@ -232,7 +232,7 @@ ActivateStarShip (COUNT which_ship, SIZE state) StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); hNextShip = _GetSuccLink (StarShipPtr); - RemoveShip = (GET_RACE_ID (StarShipPtr) == which_ship); + RemoveShip = (StarShipPtr->race_id == which_ship); UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); if (RemoveShip) @@ -282,14 +282,14 @@ ActivateStarShip (COUNT which_ship, SIZE state) StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hOldShip); - win_loc = StarShipPtr->var2; + win_loc = StarShipPtr->index; UnlockShipFrag (&GLOBAL (built_ship_q), hOldShip); if (which_window <= win_loc) break; } StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); - StarShipPtr->var2 = which_window - 1; + StarShipPtr->index = which_window - 1; UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); InsertQueue (&GLOBAL (built_ship_q), hStarShip, hOldShip); @@ -417,12 +417,8 @@ CloneShipFragment (COUNT shipIndex, QUEUE *pDstQueue, COUNT crew_level) ShipFragPtr->max_crew = TemplatePtr->max_crew; ShipFragPtr->energy_level = 0; ShipFragPtr->max_energy = TemplatePtr->max_energy; - ShipFragPtr->ship_flags = 0; - ShipFragPtr->var1 = 0; - ShipFragPtr->var2 = 0; - ShipFragPtr->loc.x = 0; - ShipFragPtr->loc.y = 0; - SET_RACE_ID (ShipFragPtr, (BYTE)shipIndex); + ShipFragPtr->race_id = (BYTE)shipIndex; + ShipFragPtr->index = 0; UnlockShipFrag (pDstQueue, hBuiltShip); } UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet); @@ -452,7 +448,7 @@ SetEscortCrewComplement (COUNT which_ship, COUNT crew_level, BYTE captain) { StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); hNextShip = _GetSuccLink (StarShipPtr); - if (which_ship == GET_RACE_ID (StarShipPtr) && + if (which_ship == StarShipPtr->race_id && StarShipPtr->crew_level == TemplatePtr->crew_level) break; /* found one */ UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); diff --git a/sc2/src/sc2code/comm.c b/sc2/src/sc2code/comm.c index 35b8b9ae4..2e1d59170 100644 --- a/sc2/src/sc2code/comm.c +++ b/sc2/src/sc2code/comm.c @@ -1678,7 +1678,7 @@ RaceCommunication (void) // the player will be talking to hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)); FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - i = GET_RACE_ID (FragPtr); + i = FragPtr->race_id; UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); status = InitCommunication (RaceComm[i]); @@ -1713,17 +1713,17 @@ RaceCommunication (void) for (i = 0; i < NumShips; ++i) { HSHIPFRAG hStarShip; - SHIP_FRAGMENT *TemplatePtr; + SHIP_FRAGMENT *FragPtr; BRIEF_SHIP_INFO *BSIPtr; hStarShip = GetStarShipFromIndex (&GLOBAL (npc_built_ship_q), i); - TemplatePtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); // XXX: SHIP_INFO struct copy BSIPtr = &EncounterPtr->ShipList[i]; - BSIPtr->race_id = GET_RACE_ID (TemplatePtr); - BSIPtr->crew_level = TemplatePtr->crew_level; - BSIPtr->max_crew = TemplatePtr->max_crew; - BSIPtr->max_energy = TemplatePtr->max_energy; + BSIPtr->race_id = FragPtr->race_id; + BSIPtr->crew_level = FragPtr->crew_level; + BSIPtr->max_crew = FragPtr->max_crew; + BSIPtr->max_energy = FragPtr->max_energy; UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); } diff --git a/sc2/src/sc2code/element.h b/sc2/src/sc2code/element.h index e0faaecd2..503e6a96b 100644 --- a/sc2/src/sc2code/element.h +++ b/sc2/src/sc2code/element.h @@ -125,7 +125,10 @@ struct element COUNT life_span; COUNT crew_level; BYTE mass_points; - BYTE turn_wait, thrust_wait; + /* Also: system loc for IP flagship */ + BYTE turn_wait; + /* Also: group_id for IP groups */ + BYTE thrust_wait; VELOCITY_DESC velocity; INTERSECT_CONTROL IntersectControl; COUNT PrimIndex; @@ -148,9 +151,12 @@ extern PRIMITIVE DisplayArray[MAX_DISPLAY_PRIMS]; #define GetElementStarShip(e,ppsd) do { *(ppsd) = (e)->pParent; } while (0) #define SetElementStarShip(e,psd) do { (e)->pParent = psd; } while (0) +// XXX: Would be nice to clean these up! +// Should make them into a union for now. #define blast_offset thrust_wait #define hit_points crew_level #define next_turn thrust_wait + #define MAX_CREW_SIZE 42 #define MAX_ENERGY_SIZE 42 #define MAX_SHIP_MASS 10 diff --git a/sc2/src/sc2code/encount.c b/sc2/src/sc2code/encount.c index c18f5736e..8e5f9c197 100644 --- a/sc2/src/sc2code/encount.c +++ b/sc2/src/sc2code/encount.c @@ -130,7 +130,7 @@ BuildBattle (COUNT which_player) hNextShip = _GetSuccLink (FragPtr); hBuiltShip = Build (&race_q[which_player], - GET_RACE_ID (FragPtr) == SAMATRA_SHIP ? + FragPtr->race_id == SAMATRA_SHIP ? SAMATRA_RES_INDEX : FragPtr->RaceResIndex); if (hBuiltShip) { @@ -144,9 +144,8 @@ BuildBattle (COUNT which_player) BuiltShipPtr->max_crew = FragPtr->max_crew; BuiltShipPtr->race_strings = FragPtr->race_strings; BuiltShipPtr->icons = FragPtr->icons; - BuiltShipPtr->index = FragPtr->var2; - /* This is not technically necessary, but still */ - //BuiltShipPtr->ship_cost = FragPtr->ship_cost; + BuiltShipPtr->index = FragPtr->index; + BuiltShipPtr->ship_cost = 0; BuiltShipPtr->RaceDescPtr = 0; UnlockStarShip (&race_q[which_player], hBuiltShip); @@ -476,7 +475,7 @@ UninitEncounter (void) hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)); FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - EncounterRace = GET_RACE_ID (FragPtr); + EncounterRace = FragPtr->race_id; if (GetStarShipFromIndex (&GLOBAL (avail_race_q), EncounterRace) == 0) { /* Suppress the final tally and salvage info */ diff --git a/sc2/src/sc2code/gameev.c b/sc2/src/sc2code/gameev.c index 266a315be..110f87479 100644 --- a/sc2/src/sc2code/gameev.c +++ b/sc2/src/sc2code/gameev.c @@ -265,11 +265,11 @@ check_race_growth (void) hNextShip = _GetSuccLink (FleetPtr); if (FleetPtr->actual_strength - && FleetPtr->actual_strength != (COUNT)~0) + && FleetPtr->actual_strength != INFINITE_RADIUS) { SIZE delta_strength; - delta_strength = (SBYTE)FleetPtr->energy_level; + delta_strength = (SBYTE)FleetPtr->growth; if (FleetPtr->growth_err_term <= FleetPtr->growth_fract) { if (delta_strength <= 0) @@ -333,7 +333,7 @@ black_urquan_genocide (void) if (Index != BLACK_URQUAN_SHIP && Index != URQUAN_SHIP - && FleetPtr->actual_strength != (COUNT)~0) + && FleetPtr->actual_strength != INFINITE_RADIUS) { SIZE dx, dy; @@ -497,7 +497,7 @@ thradd_mission (void) SIZE strength_loss; strength_loss = (SIZE)(ThraddPtr->actual_strength >> 1); - ThraddPtr->energy_level = (BYTE)(-strength_loss / 14); + ThraddPtr->growth = (BYTE)(-strength_loss / 14); ThraddPtr->growth_fract = (BYTE)(((strength_loss % 14) << 8) / 14); ThraddPtr->growth_err_term = 255 >> 1; } @@ -505,7 +505,7 @@ thradd_mission (void) { if (MissionState != 0) { /* stop losses */ - ThraddPtr->energy_level = 0; + ThraddPtr->growth = 0; ThraddPtr->growth_fract = 0; } } @@ -562,8 +562,7 @@ ilwrath_mission (void) SET_GAME_STATE (ILWRATH_FIGHT_THRADDASH, 1); SET_GAME_STATE (HELIX_UNPROTECTED, 1); strength_loss = (SIZE)IlwrathPtr->actual_strength; - IlwrathPtr->energy_level = - (BYTE)(-strength_loss / MADD_LENGTH); + IlwrathPtr->growth = (BYTE)(-strength_loss / MADD_LENGTH); IlwrathPtr->growth_fract = (BYTE)(((strength_loss % MADD_LENGTH) << 8) / MADD_LENGTH); SetRaceDest (ILWRATH_SHIP, @@ -571,8 +570,7 @@ ilwrath_mission (void) MADD_LENGTH - 1, ADVANCE_ILWRATH_MISSION); strength_loss = (SIZE)ThraddPtr->actual_strength; - ThraddPtr->energy_level = - (BYTE)(-strength_loss / MADD_LENGTH); + ThraddPtr->growth = (BYTE)(-strength_loss / MADD_LENGTH); ThraddPtr->growth_fract = (BYTE)(((strength_loss % MADD_LENGTH) << 8) / MADD_LENGTH); @@ -625,7 +623,7 @@ utwig_supox_mission (void) ADVANCE_UTWIG_SUPOX_MISSION); strength_loss = (SIZE)(UtwigPtr->actual_strength >> 1); - UtwigPtr->energy_level = (BYTE)(-strength_loss / 160); + UtwigPtr->growth = (BYTE)(-strength_loss / 160); UtwigPtr->growth_fract = (BYTE)(((strength_loss % 160) << 8) / 160); UtwigPtr->growth_err_term = 255 >> 1; @@ -633,7 +631,7 @@ utwig_supox_mission (void) strength_loss = (SIZE)(SupoxPtr->actual_strength >> 1); if (strength_loss) { - SupoxPtr->energy_level = (BYTE)(-strength_loss / 160); + SupoxPtr->growth = (BYTE)(-strength_loss / 160); SupoxPtr->growth_fract = (BYTE)(((strength_loss % 160) << 8) / 160); SupoxPtr->growth_err_term = 255 >> 1; @@ -668,9 +666,9 @@ utwig_supox_mission (void) sx = 7468; sy = 9246; - UtwigPtr->energy_level = 0; + UtwigPtr->growth = 0; UtwigPtr->growth_fract = 0; - SupoxPtr->energy_level = 0; + SupoxPtr->growth = 0; SupoxPtr->growth_fract = 0; SET_GAME_STATE (UTWIG_WAR_NEWS, 0); @@ -701,13 +699,13 @@ mycon_mission (void) if (MyconPtr->actual_strength) { - if (MyconPtr->energy_level) + if (MyconPtr->growth) { // Head back. SET_GAME_STATE (MYCON_KNOW_AMBUSH, 1); SetRaceDest (MYCON_SHIP, 6392, 2200, 30, (BYTE)~0); - MyconPtr->energy_level = 0; + MyconPtr->growth = 0; MyconPtr->growth_fract = 0; } else if (MyconPtr->loc.x != 6858 || MyconPtr->loc.y != 577) @@ -720,7 +718,7 @@ mycon_mission (void) AddEvent (RELATIVE_EVENT, 0, 14, 0, ADVANCE_MYCON_MISSION); strength_loss = (SIZE)(MyconPtr->actual_strength >> 1); - MyconPtr->energy_level = (BYTE)(-strength_loss / 14); + MyconPtr->growth = (BYTE)(-strength_loss / 14); MyconPtr->growth_fract = (BYTE)(((strength_loss % 14) << 8) / 14); MyconPtr->growth_err_term = 255 >> 1; } diff --git a/sc2/src/sc2code/globdata.c b/sc2/src/sc2code/globdata.c index 194b47644..7b1f0884b 100644 --- a/sc2/src/sc2code/globdata.c +++ b/sc2/src/sc2code/globdata.c @@ -26,6 +26,7 @@ #include "nameref.h" #include "build.h" #include "state.h" +#include "grpinfo.h" #include "gamestr.h" #include @@ -173,23 +174,19 @@ LoadSC2Data (void) } static void -copyFleetInfo (FLEET_INFO *dst, SHIP_INFO *src) +copyFleetInfo (FLEET_INFO *dst, SHIP_INFO *src, FLEET_STUFF *fleet) { - if (src->var2 == (BYTE)~0) - dst->actual_strength = (COUNT)~0; - else - dst->actual_strength = (COUNT)src->var2 << 1; - // other leading fields are irrelevant dst->crew_level = src->crew_level; dst->max_crew = src->max_crew; - dst->energy_level = src->energy_level; dst->max_energy = src->max_energy; - dst->loc = src->loc; dst->race_strings = src->race_strings; dst->icons = src->icons; dst->melee_icon = src->melee_icon; + + dst->actual_strength = fleet->strength; + dst->known_loc = fleet->known_loc; } BOOLEAN @@ -237,13 +234,14 @@ InitSIS (void) if (i < num_ships - 1) { HMASTERSHIP hMasterShip; - MASTER_SHIP_INFO *MasterShipPtr; + MASTER_SHIP_INFO *MasterPtr; hMasterShip = FindMasterShip (ship_ref); - MasterShipPtr = LockMasterShip (&master_q, hMasterShip); + MasterPtr = LockMasterShip (&master_q, hMasterShip); // Grab a copy of loaded icons and strings (not owned) // XXX: SHIP_INFO struct copy - copyFleetInfo (FleetPtr, &MasterShipPtr->ShipInfo); + copyFleetInfo (FleetPtr, &MasterPtr->ShipInfo, + &MasterPtr->Fleet); UnlockMasterShip (&master_q, hMasterShip); } else @@ -254,7 +252,8 @@ InitSIS (void) if (RDPtr) { // Grab a copy of loaded icons and strings // XXX: SHIP_INFO struct copy - copyFleetInfo (FleetPtr, &RDPtr->ship_info); + copyFleetInfo (FleetPtr, &RDPtr->ship_info, + &RDPtr->fleet); // avail_race_q owns these resources now free_ship (RDPtr, FALSE, FALSE); } @@ -262,13 +261,13 @@ InitSIS (void) FleetPtr->ship_flags = BAD_GUY; FleetPtr->known_strength = 0; - FleetPtr->known_loc = FleetPtr->loc; - // XXX: Rebel special case + FleetPtr->loc = FleetPtr->known_loc; + // XXX: Hack: Rebel special case if (i == YEHAT_REBEL_SHIP) FleetPtr->actual_strength = 0; + FleetPtr->growth = 0; FleetPtr->growth_fract = 0; FleetPtr->growth_err_term = 255 >> 1; - FleetPtr->energy_level = 0; FleetPtr->days_left = 0; FleetPtr->func_index = ~0; @@ -321,8 +320,10 @@ InitSIS (void) InitQueue (&GLOBAL (built_ship_q), MAX_BUILT_SHIPS, sizeof (SHIP_FRAGMENT)); - InitQueue (&GLOBAL (npc_built_ship_q), - (MAX_BATTLE_GROUPS >> 1), sizeof (SHIP_FRAGMENT)); + InitQueue (&GLOBAL (npc_built_ship_q), MAX_SHIPS_PER_SIDE, + sizeof (SHIP_FRAGMENT)); + InitQueue (&GLOBAL (ip_group_q), MAX_BATTLE_GROUPS, + sizeof (IP_GROUP)); InitQueue (&GLOBAL (encounter_q), MAX_ENCOUNTERS, sizeof (ENCOUNTER)); GLOBAL (CurrentActivity) = IN_INTERPLANETARY | START_INTERPLANETARY; @@ -391,6 +392,7 @@ UninitSIS (void) return; UninitQueue (&GLOBAL (encounter_q)); + UninitQueue (&GLOBAL (ip_group_q)); UninitQueue (&GLOBAL (npc_built_ship_q)); UninitQueue (&GLOBAL (built_ship_q)); UninitGroupInfo (); diff --git a/sc2/src/sc2code/globdata.h b/sc2/src/sc2code/globdata.h index ca8a0d4be..2a5e5eb23 100644 --- a/sc2/src/sc2code/globdata.h +++ b/sc2/src/sc2code/globdata.h @@ -948,8 +948,10 @@ typedef struct * queue element is FLEET_INFO */ QUEUE npc_built_ship_q; /* Non-player-character list of ships (during encounter) - * or list of groups present in solarsys (during IP); * queue element is SHIP_FRAGMENT */ + QUEUE ip_group_q; + /* List of groups present in solarsys (during IP); + * queue element is IP_GROUP */ QUEUE encounter_q; /* List of HyperSpace encounters (black globes); * queue element is ENCOUNTER */ diff --git a/sc2/src/sc2code/grpinfo.c b/sc2/src/sc2code/grpinfo.c index 29cf485a5..851745daf 100644 --- a/sc2/src/sc2code/grpinfo.c +++ b/sc2/src/sc2code/grpinfo.c @@ -23,6 +23,7 @@ #include "intel.h" #include "sis.h" #include "state.h" +#include "grpinfo.h" #include "libs/mathlib.h" #include "libs/log.h" @@ -36,6 +37,13 @@ static BYTE LastEncGroup; //#define DEBUG_GROUPS +// A group header describes battle groups present in a star system. There is +// at most 1 group header per system. +// 'Random' group info file (RANDGRPINFO_FILE) always contains only one +// group header record, which describes the last-visited star system, +// (which may be the current system). Thus the randomly generated groups +// are valid for 7 days (set in PutGroupInfo) after the player leaves +// the system, or until the player enters another star system. typedef struct { BYTE NumGroups; @@ -46,15 +54,15 @@ typedef struct // by going to HSpace and stay there till such time) // star_index is the index of a star this group header // applies to; ~0 means uninited - DWORD GroupOffset[MAX_BATTLE_GROUPS + 1]; + DWORD GroupOffset[NUM_SAVED_BATTLE_GROUPS + 1]; // Absolute offsets of group definitions in a state file - // Group 0 is actually a list of groups present in solarsys + // Group 0 is a list of groups present in solarsys // Groups 1..max are definitions of actual battle groups - // containing ships composition and status + // containing ship makeup and status // Each group has the following format: // 1 byte, RaceType (LastEncGroup in Group 0) - // 1 byte, NumShips + // 1 byte, NumShips (NumGroups in Group 0) // Ships follow: // 1 byte, RaceType // 16 bytes, part of SHIP_FRAGMENT struct @@ -70,7 +78,7 @@ ReadGroupHeader (void *fp, GROUP_HEADER *pGH) sread_8 (fp, NULL); /* padding */ sread_16 (fp, &pGH->star_index); sread_16 (fp, &pGH->year_index); - sread_a32 (fp, pGH->GroupOffset, MAX_BATTLE_GROUPS + 1); + sread_a32 (fp, pGH->GroupOffset, NUM_SAVED_BATTLE_GROUPS + 1); } static void @@ -82,7 +90,7 @@ WriteGroupHeader (void *fp, const GROUP_HEADER *pGH) swrite_8 (fp, 0); /* padding */ swrite_16 (fp, pGH->star_index); swrite_16 (fp, pGH->year_index); - swrite_a32 (fp, pGH->GroupOffset, MAX_BATTLE_GROUPS + 1); + swrite_a32 (fp, pGH->GroupOffset, NUM_SAVED_BATTLE_GROUPS + 1); } static void @@ -90,13 +98,12 @@ ReadShipFragment (void *fp, SHIP_FRAGMENT *FragPtr) { BYTE tmpb; - // Read SHIP_FRAGMENT elements sread_16 (fp, &FragPtr->which_side); sread_8 (fp, &FragPtr->captains_name_index); - sread_8 (fp, NULL); /* padding */ - sread_16 (fp, &FragPtr->ship_flags); - sread_8 (fp, &FragPtr->var1); - sread_8 (fp, &FragPtr->var2); + sread_8 (fp, NULL); /* padding; for savegame compat */ + sread_16 (fp, NULL); /* unused: was ship_flags */ + sread_8 (fp, &FragPtr->race_id); + sread_8 (fp, &FragPtr->index); // XXX: reading crew as BYTE to maintain savegame compatibility sread_8 (fp, &tmpb); FragPtr->crew_level = tmpb; @@ -104,27 +111,70 @@ ReadShipFragment (void *fp, SHIP_FRAGMENT *FragPtr) FragPtr->max_crew = tmpb; sread_8 (fp, &FragPtr->energy_level); sread_8 (fp, &FragPtr->max_energy); - sread_16 (fp, &FragPtr->loc.x); - sread_16 (fp, &FragPtr->loc.y); + sread_16 (fp, NULL); /* unused; was loc.x */ + sread_16 (fp, NULL); /* unused; was loc.y */ } static void WriteShipFragment (void *fp, const SHIP_FRAGMENT *FragPtr) { - // Write SHIP_FRAGMENT elements swrite_16 (fp, FragPtr->which_side); swrite_8 (fp, FragPtr->captains_name_index); - swrite_8 (fp, 0); /* padding */ - swrite_16 (fp, FragPtr->ship_flags); - swrite_8 (fp, FragPtr->var1); - swrite_8 (fp, FragPtr->var2); + swrite_8 (fp, 0); /* padding; for savegame compat */ + swrite_16 (fp, 0); /* unused: was ship_flags */ + swrite_8 (fp, FragPtr->race_id); + swrite_8 (fp, FragPtr->index); // XXX: writing crew as BYTE to maintain savegame compatibility swrite_8 (fp, FragPtr->crew_level); swrite_8 (fp, FragPtr->max_crew); swrite_8 (fp, FragPtr->energy_level); swrite_8 (fp, FragPtr->max_energy); - swrite_16 (fp, FragPtr->loc.x); - swrite_16 (fp, FragPtr->loc.y); + swrite_16 (fp, 0); /* unused; was loc.x */ + swrite_16 (fp, 0); /* unused; was loc.y */ +} + +static void +ReadIpGroup (void *fp, IP_GROUP *GroupPtr) +{ + BYTE tmpb; + + sread_16 (fp, NULL); /* unused; was which_side */ + sread_8 (fp, NULL); /* unused; was captains_name_index */ + sread_8 (fp, NULL); /* padding; for savegame compat */ + sread_16 (fp, &GroupPtr->group_counter); + sread_8 (fp, &GroupPtr->race_id); + sread_8 (fp, &tmpb); /* was var2 */ + GroupPtr->sys_loc = LONIBBLE (tmpb); + GroupPtr->task = HINIBBLE (tmpb); + sread_8 (fp, &GroupPtr->in_system); /* was crew_level */ + sread_8 (fp, NULL); /* unused; was max_crew */ + sread_8 (fp, &tmpb); /* was energy_level */ + GroupPtr->dest_loc = LONIBBLE (tmpb); + GroupPtr->orbit_pos = HINIBBLE (tmpb); + sread_8 (fp, &GroupPtr->group_id); /* was max_energy */ + sread_16 (fp, &GroupPtr->loc.x); + sread_16 (fp, &GroupPtr->loc.y); +} + +static void +WriteIpGroup (void *fp, const IP_GROUP *GroupPtr) +{ + swrite_16 (fp, 0); /* unused; was which_side */ + swrite_8 (fp, 0); /* unused; was captains_name_index */ + swrite_8 (fp, 0); /* padding; for savegame compat */ + swrite_16 (fp, GroupPtr->group_counter); + swrite_8 (fp, GroupPtr->race_id); + assert (GroupPtr->sys_loc < 0x10 && GroupPtr->task < 0x10); + swrite_8 (fp, MAKE_BYTE (GroupPtr->sys_loc, GroupPtr->task)); + /* was var2 */ + swrite_8 (fp, GroupPtr->in_system); /* was crew_level */ + swrite_8 (fp, 0); /* unused; was max_crew */ + assert (GroupPtr->dest_loc < 0x10 && GroupPtr->orbit_pos < 0x10); + swrite_8 (fp, MAKE_BYTE (GroupPtr->dest_loc, GroupPtr->orbit_pos)); + /* was energy_level */ + swrite_8 (fp, GroupPtr->group_id); /* was max_energy */ + swrite_16 (fp, GroupPtr->loc.x); + swrite_16 (fp, GroupPtr->loc.y); } void @@ -132,25 +182,25 @@ InitGroupInfo (BOOLEAN FirstTime) { void *fp; + assert (NUM_SAVED_BATTLE_GROUPS >= MAX_BATTLE_GROUPS); + fp = OpenStateFile (RANDGRPINFO_FILE, "wb"); if (fp) { GROUP_HEADER GH; - GH.NumGroups = 0; + memset (&GH, 0, sizeof (GH)); GH.star_index = (COUNT)~0; - GH.GroupOffset[0] = 0; WriteGroupHeader (fp, &GH); - CloseStateFile (fp); } if (FirstTime && (fp = OpenStateFile (DEFGRPINFO_FILE, "wb"))) { - // Group headers cannot start with offset 0 in - // defined group info file, so bump it + // Group headers cannot start with offset 0 in 'defined' group + // info file, so bump it (because offset 0 is reserved to + // indicate the 'random' group info file). swrite_8 (fp, 0); - CloseStateFile (fp); } } @@ -162,6 +212,36 @@ UninitGroupInfo (void) DeleteStateFile (RANDGRPINFO_FILE); } +HIPGROUP +BuildGroup (QUEUE *pDstQueue, BYTE race_id) +{ + HFLEETINFO hFleet; + FLEET_INFO *TemplatePtr; + HLINK hGroup; + IP_GROUP *GroupPtr; + + assert (GetLinkSize (pDstQueue) == sizeof (IP_GROUP)); + + hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), race_id); + if (!hFleet) + return 0; + + hGroup = AllocLink (pDstQueue); + if (!hGroup) + return 0; + + TemplatePtr = LockFleetInfo (&GLOBAL (avail_race_q), hFleet); + GroupPtr = LockIpGroup (pDstQueue, hGroup); + memset (GroupPtr, 0, GetLinkSize (pDstQueue)); + GroupPtr->race_id = race_id; + GroupPtr->melee_icon = TemplatePtr->melee_icon; + UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet); + UnlockIpGroup (pDstQueue, hGroup); + PutQueue (pDstQueue, hGroup); + + return hGroup; +} + void BuildGroups (void) { @@ -238,7 +318,7 @@ BuildGroups (void) goto FoundHome; } - if (encounter_radius == (COUNT)~0) + if (encounter_radius == INFINITE_RADIUS) encounter_radius = (MAX_X_UNIVERSE + 1) << 1; else encounter_radius = @@ -259,7 +339,7 @@ BuildGroups (void) // EncounterPercent is only used in practice for the Slylandro // Probes, for the rest of races the chance of encounter is // calced directly below from the distance to the Homeworld - if (FleetPtr->actual_strength != (COUNT)~0) + if (FleetPtr->actual_strength != INFINITE_RADIUS) { i = 70 - (COUNT)((DWORD)square_root (d_squared) * 60L / encounter_radius); @@ -270,7 +350,7 @@ BuildGroups (void) && (BestPercent == 0 || (HIWORD (rand_val) % (i + BestPercent)) < i)) { - if (FleetPtr->actual_strength == (COUNT)~0) + if (FleetPtr->actual_strength == INFINITE_RADIUS) { // The prevailing encounter chance is hereby limitted // to 4% for races with infinite SoI (currently, it // is only the Slylandro Probes) @@ -297,8 +377,8 @@ FoundHome: which_group = 0; num_groups = ((COUNT)TFB_Random () % (BestPercent >> 1)) + 1; - if (num_groups > (MAX_BATTLE_GROUPS >> 1)) - num_groups = (MAX_BATTLE_GROUPS >> 1); + if (num_groups > MAX_BATTLE_GROUPS) + num_groups = MAX_BATTLE_GROUPS; else if (num_groups < 5 && (Index = HomeWorld[BestIndex]) && CurStarDescPtr->Index == Index) @@ -325,106 +405,131 @@ FoundHome: static void FlushGroupInfo (GROUP_HEADER* pGH, DWORD offset, BYTE which_group, void *fp) { - BYTE RaceType, NumShips; - HSHIPFRAG hStarShip; - SHIP_FRAGMENT *FragPtr; - if (which_group == GROUP_LIST) { QUEUE temp_q; - HSHIPFRAG hNextShip; + HIPGROUP hGroup, hNextGroup; + /* If the group list was never written before, add it */ if (pGH->GroupOffset[0] == 0) pGH->GroupOffset[0] = LengthStateFile (fp); - /* Weed out the dead groups first */ - temp_q = GLOBAL (npc_built_ship_q); - SetHeadLink (&GLOBAL (npc_built_ship_q), 0); - SetTailLink (&GLOBAL (npc_built_ship_q), 0); - for (hStarShip = GetHeadLink (&temp_q); - hStarShip; hStarShip = hNextShip) + /* Weed out the groups that left the system first */ + // XXX: QUEUE struct copy! + temp_q = GLOBAL (ip_group_q); + SetHeadLink (&GLOBAL (ip_group_q), 0); + SetTailLink (&GLOBAL (ip_group_q), 0); + for (hGroup = GetHeadLink (&temp_q); + hGroup; hGroup = hNextGroup) { - COUNT crew_level; + BYTE in_system; + BYTE group_id; + IP_GROUP *GroupPtr; - FragPtr = LockShipFrag (&temp_q, hStarShip); - hNextShip = _GetSuccLink (FragPtr); - crew_level = FragPtr->crew_level; - which_group = GET_GROUP_ID (FragPtr); - UnlockShipFrag (&temp_q, hStarShip); + GroupPtr = LockIpGroup (&temp_q, hGroup); + hNextGroup = _GetSuccLink (GroupPtr); + in_system = GroupPtr->in_system; + group_id = GroupPtr->group_id; + UnlockIpGroup (&temp_q, hGroup); - if (crew_level == 0) - { /* This group is dead -- remove it */ + if (!in_system) + { if (GLOBAL (BattleGroupRef)) - PutGroupInfo (GLOBAL (BattleGroupRef), which_group); + PutGroupInfo (GLOBAL (BattleGroupRef), group_id); else - FlushGroupInfo (pGH, GROUPS_RANDOM, which_group, fp); - pGH->GroupOffset[which_group] = 0; - RemoveQueue (&temp_q, hStarShip); - FreeShipFrag (&temp_q, hStarShip); + FlushGroupInfo (pGH, GROUPS_RANDOM, group_id, fp); + pGH->GroupOffset[group_id] = 0; + RemoveQueue (&temp_q, hGroup); + FreeIpGroup (&temp_q, hGroup); } } - GLOBAL (npc_built_ship_q) = temp_q; - - which_group = GROUP_LIST; + // XXX: QUEUE struct copy! + GLOBAL (ip_group_q) = temp_q; } else if (which_group > pGH->NumGroups) { /* Group not present yet -- add it */ + HSHIPFRAG hStarShip; + SHIP_FRAGMENT *FragPtr; + pGH->NumGroups = which_group; pGH->GroupOffset[which_group] = LengthStateFile (fp); /* The first ship in a group defines the alien race */ hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)); FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - RaceType = GET_RACE_ID (FragPtr); SeekStateFile (fp, pGH->GroupOffset[which_group], SEEK_SET); - swrite_8 (fp, RaceType); + swrite_8 (fp, FragPtr->race_id); UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); } + SeekStateFile (fp, offset, SEEK_SET); WriteGroupHeader (fp, pGH); + #ifdef DEBUG_GROUPS log_add (log_Debug, "1)FlushGroupInfo(%lu): WG = %u(%lu), NG = %u, " "SI = %u", offset, which_group, pGH->GroupOffset[which_group], pGH->NumGroups, pGH->star_index); #endif /* DEBUG_GROUPS */ - NumShips = (BYTE)CountLinks (&GLOBAL (npc_built_ship_q)); + if (which_group == GROUP_LIST) + { + /* Write out ip_group_q as group 0 */ + HIPGROUP hGroup, hNextGroup; + // XXX: will use ip_group_q here + BYTE NumGroups = CountLinks (&GLOBAL (ip_group_q)); - if (which_group != GROUP_LIST) - { /* Do not change RaceType (skip it) */ - SeekStateFile (fp, pGH->GroupOffset[which_group] + 1, SEEK_SET); + SeekStateFile (fp, pGH->GroupOffset[0], SEEK_SET); + swrite_8 (fp, LastEncGroup); + swrite_8 (fp, NumGroups); + + hGroup = GetHeadLink (&GLOBAL (ip_group_q)); + for ( ; NumGroups; --NumGroups, hGroup = hNextGroup) + { + IP_GROUP *GroupPtr; + + GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup); + hNextGroup = _GetSuccLink (GroupPtr); + + swrite_8 (fp, GroupPtr->race_id); + +#ifdef DEBUG_GROUPS + log_add (log_Debug, "F) type %u, loc %u<%d, %d>, task 0x%02x:%u", + GroupPtr->race_id, + GET_GROUP_LOC (GroupPtr), + GroupPtr->loc.x, + GroupPtr->loc.y, + GET_GROUP_MISSION (GroupPtr), + GET_GROUP_DEST (GroupPtr)); +#endif /* DEBUG_GROUPS */ + + WriteIpGroup (fp, GroupPtr); + + UnlockIpGroup (&GLOBAL (ip_group_q), hGroup); + } } else { - SeekStateFile (fp, pGH->GroupOffset[0], SEEK_SET); - swrite_8 (fp, LastEncGroup); - } - swrite_8 (fp, NumShips); + /* Write out npc_built_ship_q as 'which_group' group */ + HSHIPFRAG hStarShip, hNextShip; + BYTE NumShips = CountLinks (&GLOBAL (npc_built_ship_q)); - hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)); - while (NumShips--) - { - HSHIPFRAG hNextShip; + /* Do not change RaceType of the group (skip it) */ + SeekStateFile (fp, pGH->GroupOffset[which_group] + 1, SEEK_SET); + swrite_8 (fp, NumShips); - FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - hNextShip = _GetSuccLink (FragPtr); + hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)); + for ( ; NumShips; --NumShips, hStarShip = hNextShip) + { + SHIP_FRAGMENT *FragPtr; - RaceType = GET_RACE_ID (FragPtr); - swrite_8 (fp, RaceType); + FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + hNextShip = _GetSuccLink (FragPtr); -#ifdef DEBUG_GROUPS - if (which_group == GROUP_LIST) - log_add (log_Debug, "F) type %u, loc %u<%d, %d>, task 0x%02x:%u", - RaceType, - GET_GROUP_LOC (FragPtr), - FragPtr->loc.x, - FragPtr->loc.y, - GET_GROUP_MISSION (FragPtr), - GET_GROUP_DEST (FragPtr)); -#endif /* DEBUG_GROUPS */ - WriteShipFragment (fp, FragPtr); - UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - hStarShip = hNextShip; + swrite_8 (fp, FragPtr->race_id); + WriteShipFragment (fp, FragPtr); + + UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + } } } @@ -432,308 +537,340 @@ BOOLEAN GetGroupInfo (DWORD offset, BYTE which_group) { void *fp; + GROUP_HEADER GH; if (offset != GROUPS_RANDOM && which_group != GROUP_LIST) fp = OpenStateFile (DEFGRPINFO_FILE, "r+b"); else fp = OpenStateFile (RANDGRPINFO_FILE, "r+b"); - if (fp) + if (!fp) + return FALSE; + + SeekStateFile (fp, offset, SEEK_SET); + ReadGroupHeader (fp, &GH); +#ifdef DEBUG_GROUPS + log_add (log_Debug, "GetGroupInfo(%lu): %u(%lu) out of %u", offset, + which_group, GH.GroupOffset[which_group], GH.NumGroups); +#endif /* DEBUG_GROUPS */ + + if (which_group == GROUP_INIT_IP) { - BYTE RaceType, NumShips; - GROUP_HEADER GH; - HSHIPFRAG hStarShip; - SHIP_FRAGMENT *FragPtr; + COUNT month_index, day_index, year_index; - SeekStateFile (fp, offset, SEEK_SET); - ReadGroupHeader (fp, &GH); + ReinitQueue (&GLOBAL (ip_group_q)); #ifdef DEBUG_GROUPS - log_add (log_Debug, "GetGroupInfo(%lu): %u(%lu) out of %u", offset, - which_group, GH.GroupOffset[which_group], GH.NumGroups); + log_add (log_Debug, "%u == %u", GH.star_index, + (COUNT)(CurStarDescPtr - star_array)); #endif /* DEBUG_GROUPS */ - if (which_group == GROUP_INIT_IP) + + /* Check if the requested groups are valid for this star system + * and if they are still current (not expired) */ + day_index = GH.day_index; + month_index = GH.month_index; + year_index = GH.year_index; + if (offset == GROUPS_RANDOM + && (GH.star_index != (COUNT)(CurStarDescPtr - star_array) + || !ValidateEvent (ABSOLUTE_EVENT, &month_index, &day_index, + &year_index))) { - COUNT month_index, day_index, year_index; - - ReinitQueue (&GLOBAL (npc_built_ship_q)); #ifdef DEBUG_GROUPS - log_add (log_Debug, "%u == %u", GH.star_index, - (COUNT)(CurStarDescPtr - star_array)); + if (GH.star_index == CurStarDescPtr - star_array) + log_add (log_Debug, "GetGroupInfo: battle groups out of " + "date %u/%u/%u!", month_index, day_index, + year_index); #endif /* DEBUG_GROUPS */ - day_index = GH.day_index; - month_index = GH.month_index; - year_index = GH.year_index; - if (offset == GROUPS_RANDOM - && (GH.star_index != (COUNT)(CurStarDescPtr - star_array) - || !ValidateEvent (ABSOLUTE_EVENT, - &month_index, &day_index, &year_index))) - { - CloseStateFile (fp); -#ifdef DEBUG_GROUPS - if (GH.star_index == (COUNT)(CurStarDescPtr - star_array)) - log_add (log_Debug, "GetGroupInfo: battle groups out of " - "date %u/%u/%u!", month_index, day_index, - year_index); -#endif /* DEBUG_GROUPS */ - // Erase random groups (out of date) - fp = OpenStateFile (RANDGRPINFO_FILE, "wb"); - GH.NumGroups = 0; - GH.star_index = (COUNT)~0; - GH.GroupOffset[0] = 0; - WriteGroupHeader (fp, &GH); - } - else - { - /* Read IP groups into npc_built_ship_q */ - for (which_group = 1; which_group <= GH.NumGroups; - ++which_group) - { - if (GH.GroupOffset[which_group] == 0) - continue; - - SeekStateFile (fp, GH.GroupOffset[which_group], SEEK_SET); - sread_8 (fp, &RaceType); - sread_8 (fp, &NumShips); - - if (NumShips) - { - BYTE task, group_loc; - DWORD rand_val; - - hStarShip = CloneShipFragment (RaceType, - &GLOBAL (npc_built_ship_q), 0); - FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), - hStarShip); - // XXX: STARSHIP refactor; Cannot find what might be - // using this info. Looks unused. - FragPtr->which_side = BAD_GUY; - FragPtr->captains_name_index = 0; - // XXX: CloneShipFragment() may set ship_flags in the - // future, and it will collide with group_counter, - // but it is reset a few lines below - SET_GROUP_ID (FragPtr, which_group); - - rand_val = TFB_Random (); - task = (BYTE)(LOBYTE (LOWORD (rand_val)) - % ON_STATION); - if (task == FLEE) - task = ON_STATION; - SET_ORBIT_LOC (FragPtr, NORMALIZE_FACING ( - LOBYTE (HIWORD (rand_val)))); - - group_loc = pSolarSysState->SunDesc[0].NumPlanets; - if (group_loc == 1 && task == EXPLORE) - task = IN_ORBIT; - else - group_loc = (BYTE)(( - HIBYTE (LOWORD (rand_val)) % group_loc - ) + 1); - SET_GROUP_DEST (FragPtr, group_loc); - rand_val = TFB_Random (); - FragPtr->loc.x = (LOWORD (rand_val) % 10000) - 5000; - FragPtr->loc.y = (HIWORD (rand_val) % 10000) - 5000; - if (task == EXPLORE) - FragPtr->group_counter = - ((COUNT)TFB_Random () % MAX_REVOLUTIONS) - << FACING_SHIFT; - else - { - FragPtr->group_counter = 0; - if (task == ON_STATION) - { - COUNT angle; - POINT org; - - XFormIPLoc (&pSolarSysState->PlanetDesc[ - group_loc - 1].image.origin, &org, - FALSE); - angle = FACING_TO_ANGLE (GET_ORBIT_LOC ( - FragPtr) + 1); - FragPtr->loc.x = org.x - + COSINE (angle, STATION_RADIUS); - FragPtr->loc.y = org.y - + SINE (angle, STATION_RADIUS); - group_loc = 0; - } - } - - SET_GROUP_MISSION (FragPtr, task); - SET_GROUP_LOC (FragPtr, group_loc); - -#ifdef DEBUG_GROUPS - log_add (log_Debug, "battle group %u(0x%04x) strength " - "%u, type %u, loc %u<%d, %d>, task %u", - which_group, - hStarShip, - NumShips, - RaceType, - group_loc, - FragPtr->loc.x, - FragPtr->loc.y, - task); -#endif /* DEBUG_GROUPS */ - UnlockShipFrag (&GLOBAL (npc_built_ship_q), - hStarShip); - } - } - - if (offset != GROUPS_RANDOM) - InitGroupInfo (FALSE); /* Wipe out random battle groups */ - else if (ValidateEvent (ABSOLUTE_EVENT, /* still fresh */ - &month_index, &day_index, &year_index)) - { - CloseStateFile (fp); - return (TRUE); - } - } - } - else if (GH.GroupOffset[which_group]) - { - COUNT ShipsLeft; - - ShipsLeft = CountLinks (&GLOBAL (npc_built_ship_q)); - if (which_group == GROUP_LIST) - { - SeekStateFile (fp, GH.GroupOffset[0], SEEK_SET); - sread_8 (fp, &LastEncGroup); - - if (LastEncGroup) - { - if (GLOBAL (BattleGroupRef)) - PutGroupInfo (GLOBAL (BattleGroupRef), LastEncGroup); - else - FlushGroupInfo (&GH, offset, LastEncGroup, fp); - } - } - else - { - LastEncGroup = which_group; - if (offset != GROUPS_RANDOM) - PutGroupInfo (GROUPS_RANDOM, GROUP_LIST); - else - FlushGroupInfo (&GH, GROUPS_RANDOM, GROUP_LIST, fp); - } - ReinitQueue (&GLOBAL (npc_built_ship_q)); - - // skip RaceType - SeekStateFile (fp, GH.GroupOffset[which_group] + 1, SEEK_SET); + CloseStateFile (fp); + /* Erase random groups (out of date) */ + fp = OpenStateFile (RANDGRPINFO_FILE, "wb"); + memset (&GH, 0, sizeof (GH)); + GH.star_index = (COUNT)~0; + WriteGroupHeader (fp, &GH); + CloseStateFile (fp); + return FALSE; + } + + /* Read IP groups into ip_group_q and send them on their missions */ + for (which_group = 1; which_group <= GH.NumGroups; ++which_group) + { + BYTE task, group_loc; + DWORD rand_val; + BYTE RaceType; + BYTE NumShips; + HIPGROUP hGroup; + IP_GROUP *GroupPtr; + + if (GH.GroupOffset[which_group] == 0) + continue; + + SeekStateFile (fp, GH.GroupOffset[which_group], SEEK_SET); + sread_8 (fp, &RaceType); sread_8 (fp, &NumShips); - while (NumShips--) + if (!NumShips) + continue; /* group is dead */ + + hGroup = BuildGroup (&GLOBAL (ip_group_q), RaceType); + GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup); + // XXX: which_side is unused, other than this assign + //GroupPtr->which_side = BAD_GUY; + GroupPtr->group_id = which_group; + GroupPtr->in_system = 1; + + rand_val = TFB_Random (); + task = (BYTE)(LOBYTE (LOWORD (rand_val)) % ON_STATION); + if (task == FLEE) + task = ON_STATION; + GroupPtr->orbit_pos = NORMALIZE_FACING ( + LOBYTE (HIWORD (rand_val))); + + group_loc = pSolarSysState->SunDesc[0].NumPlanets; + if (group_loc == 1 && task == EXPLORE) + task = IN_ORBIT; + else + group_loc = (BYTE)((HIBYTE (LOWORD (rand_val)) % group_loc) + 1); + GroupPtr->dest_loc = group_loc; + rand_val = TFB_Random (); + GroupPtr->loc.x = (LOWORD (rand_val) % 10000) - 5000; + GroupPtr->loc.y = (HIWORD (rand_val) % 10000) - 5000; + GroupPtr->group_counter = 0; + if (task == EXPLORE) { - sread_8 (fp, &RaceType); + GroupPtr->group_counter = ((COUNT)TFB_Random () % + MAX_REVOLUTIONS) << FACING_SHIFT; + } + else if (task == ON_STATION) + { + COUNT angle; + POINT org; - hStarShip = CloneShipFragment (RaceType, - &GLOBAL (npc_built_ship_q), 0); + XFormIPLoc (&pSolarSysState->PlanetDesc[group_loc - 1] + .image.origin, &org, FALSE); + angle = FACING_TO_ANGLE (GroupPtr->orbit_pos + 1); + GroupPtr->loc.x = org.x + COSINE (angle, STATION_RADIUS); + GroupPtr->loc.y = org.y + SINE (angle, STATION_RADIUS); + group_loc = 0; + } - FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - ReadShipFragment (fp, FragPtr); + GroupPtr->task = task; + GroupPtr->sys_loc = group_loc; #ifdef DEBUG_GROUPS - if (which_group == GROUP_LIST) - log_add (log_Debug, "G) type %u, loc %u<%d, %d>, " - "task 0x%02x:%u", - RaceType, - GET_GROUP_LOC (FragPtr), - FragPtr->loc.x, - FragPtr->loc.y, - GET_GROUP_MISSION (FragPtr), - GET_GROUP_DEST (FragPtr)); + log_add (log_Debug, "battle group %u(0x%04x) strength " + "%u, type %u, loc %u<%d, %d>, task %u", + which_group, + hGroup, + NumShips, + RaceType, + group_loc, + GroupPtr->loc.x, + GroupPtr->loc.y, + task); #endif /* DEBUG_GROUPS */ - if (GET_GROUP_ID (FragPtr) != LastEncGroup - || which_group != GROUP_LIST - || ShipsLeft) - { + + UnlockIpGroup (&GLOBAL (ip_group_q), hGroup); + } + + if (offset != GROUPS_RANDOM) + InitGroupInfo (FALSE); /* Wipe out random battle groups */ + else if (ValidateEvent (ABSOLUTE_EVENT, /* still fresh */ + &month_index, &day_index, &year_index)) + { + CloseStateFile (fp); + return TRUE; + } + + CloseStateFile (fp); + return (GetHeadLink (&GLOBAL (ip_group_q)) != 0); + } + + if (!GH.GroupOffset[which_group]) + { + /* Group not present */ + CloseStateFile (fp); + return FALSE; + } + + + if (which_group == GROUP_LIST) + { + BYTE NumGroups; + COUNT ShipsLeftInLEG; + + // XXX: Hack: First, save the state of last encountered group, if any. + // The assumption here is that we read the group list immediately + // after an IP encounter, and npc_built_ship_q contains whatever + // ships are left in the encountered group (can be none). + ShipsLeftInLEG = CountLinks (&GLOBAL (npc_built_ship_q)); + + SeekStateFile (fp, GH.GroupOffset[0], SEEK_SET); + sread_8 (fp, &LastEncGroup); + + if (LastEncGroup) + { + if (GLOBAL (BattleGroupRef)) + PutGroupInfo (GLOBAL (BattleGroupRef), LastEncGroup); + else + FlushGroupInfo (&GH, offset, LastEncGroup, fp); + } + ReinitQueue (&GLOBAL (npc_built_ship_q)); + + /* Read group 0 into ip_group_q */ + ReinitQueue (&GLOBAL (ip_group_q)); + /* Need a seek because Put/Flush has moved the file ptr */ + SeekStateFile (fp, GH.GroupOffset[0] + 1, SEEK_SET); + sread_8 (fp, &NumGroups); + + while (NumGroups--) + { + BYTE group_id; + BYTE RaceType; + HSHIPFRAG hGroup; + IP_GROUP *GroupPtr; + + sread_8 (fp, &RaceType); + + hGroup = BuildGroup (&GLOBAL (ip_group_q), RaceType); + GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup); + ReadIpGroup (fp, GroupPtr); + group_id = GroupPtr->group_id; + #ifdef DEBUG_GROUPS - log_add (log_Debug, "\n"); + log_add (log_Debug, "G) type %u, loc %u<%d, %d>, task 0x%02x:%u", + RaceType, + GroupPtr->sys_loc, + GroupPtr->loc.x, + GroupPtr->loc.y, + GroupPtr->task, + GroupPtr->dest_loc); #endif /* DEBUG_GROUPS */ - UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - } - else - { + + UnlockIpGroup (&GLOBAL (ip_group_q), hGroup); + + if (group_id == LastEncGroup && !ShipsLeftInLEG) + { + /* No ships left in the last encountered group, remove it */ #ifdef DEBUG_GROUPS - log_add (log_Debug, " -- REMOVING"); + log_add (log_Debug, " -- REMOVING"); #endif /* DEBUG_GROUPS */ - UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - RemoveQueue (&GLOBAL (npc_built_ship_q), hStarShip); - FreeShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - } + RemoveQueue (&GLOBAL (ip_group_q), hGroup); + FreeIpGroup (&GLOBAL (ip_group_q), hGroup); } } CloseStateFile (fp); + return (GetHeadLink (&GLOBAL (ip_group_q)) != 0); } + else + { + /* Read 'which_group' group into npc_built_ship_q */ + BYTE NumShips; - return (GetHeadLink (&GLOBAL (npc_built_ship_q)) != 0); + // XXX: Hack: The assumption here is that we only read the makeup + // of a particular group when initializing an encounter, which + // makes this group 'last encountered'. Also the state of all + // groups is saved here. This may make working with savegames + // harder in the future, as special care will have to be taken + // when loading a game into an encounter. + LastEncGroup = which_group; + if (offset != GROUPS_RANDOM) + PutGroupInfo (GROUPS_RANDOM, GROUP_LIST); + else + FlushGroupInfo (&GH, GROUPS_RANDOM, GROUP_LIST, fp); + ReinitQueue (&GLOBAL (ip_group_q)); + + ReinitQueue (&GLOBAL (npc_built_ship_q)); + // skip RaceType + SeekStateFile (fp, GH.GroupOffset[which_group] + 1, SEEK_SET); + sread_8 (fp, &NumShips); + + while (NumShips--) + { + BYTE RaceType; + HSHIPFRAG hStarShip; + SHIP_FRAGMENT *FragPtr; + + sread_8 (fp, &RaceType); + + hStarShip = CloneShipFragment (RaceType, + &GLOBAL (npc_built_ship_q), 0); + + FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + ReadShipFragment (fp, FragPtr); + UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + } + + CloseStateFile (fp); + return (GetHeadLink (&GLOBAL (npc_built_ship_q)) != 0); + } } DWORD PutGroupInfo (DWORD offset, BYTE which_group) { void *fp; + GROUP_HEADER GH; if (offset != GROUPS_RANDOM && which_group != GROUP_LIST) fp = OpenStateFile (DEFGRPINFO_FILE, "r+b"); else fp = OpenStateFile (RANDGRPINFO_FILE, "r+b"); - if (fp) + if (!fp) + return offset; + + if (offset == GROUPS_ADD_NEW) { - GROUP_HEADER GH; + offset = LengthStateFile (fp); + SeekStateFile (fp, offset, SEEK_SET); + memset (&GH, 0, sizeof (GH)); + GH.star_index = (COUNT)~0; + WriteGroupHeader (fp, &GH); + } - if (offset == GROUPS_ADD_NEW) + if (which_group != GROUP_LIST) + { + SeekStateFile (fp, offset, SEEK_SET); + if (which_group == GROUP_SAVE_IP) { - offset = LengthStateFile (fp); - SeekStateFile (fp, offset, SEEK_SET); - // XXX: All important fields are inited here, and the - // rest are inited below - GH.NumGroups = 0; - GH.star_index = (COUNT)~0; - GH.GroupOffset[0] = 0; - WriteGroupHeader (fp, &GH); + LastEncGroup = 0; + which_group = GROUP_LIST; } - - if (which_group != GROUP_LIST) - { - SeekStateFile (fp, offset, SEEK_SET); - if (which_group == GROUP_SAVE_IP) - { - LastEncGroup = 0; - which_group = GROUP_LIST; - } - } - ReadGroupHeader (fp, &GH); + } + ReadGroupHeader (fp, &GH); #ifdef NEVER - if (GetHeadLink (&GLOBAL (npc_built_ship_q)) - || GH.GroupOffset[0] == 0) + // XXX: this appears to be a remnant of a slightly different group info + // expiration mechanism. Nowadays, the 'defined' groups never expire, + // and the dead 'random' groups stay in the file with NumShips==0 until + // the entire 'random' group header expires. + if (GetHeadLink (&GLOBAL (npc_built_ship_q)) || GH.GroupOffset[0] == 0) #endif /* NEVER */ - { - COUNT month_index, day_index, year_index; + { + COUNT month_index, day_index, year_index; + + /* The groups in this system are good for the next 7 days */ + month_index = 0; + day_index = 7; + year_index = 0; + ValidateEvent (RELATIVE_EVENT, &month_index, &day_index, &year_index); + GH.day_index = (BYTE)day_index; + GH.month_index = (BYTE)month_index; + GH.year_index = year_index; + } + GH.star_index = CurStarDescPtr - star_array; - month_index = 0; - day_index = 7; - year_index = 0; - ValidateEvent (RELATIVE_EVENT, &month_index, &day_index, - &year_index); - GH.day_index = (BYTE)day_index; - GH.month_index = (BYTE)month_index; - GH.year_index = year_index; - } - GH.star_index = CurStarDescPtr - star_array; #ifdef DEBUG_GROUPS - log_add (log_Debug, "PutGroupInfo(%lu): %u out of %u -- %u/%u/%u", - offset, which_group, GH.NumGroups, - GH.month_index, GH.day_index, GH.year_index); + log_add (log_Debug, "PutGroupInfo(%lu): %u out of %u -- %u/%u/%u", + offset, which_group, GH.NumGroups, + GH.month_index, GH.day_index, GH.year_index); #endif /* DEBUG_GROUPS */ - FlushGroupInfo (&GH, offset, which_group, fp); + FlushGroupInfo (&GH, offset, which_group, fp); - CloseStateFile (fp); - } + CloseStateFile (fp); return (offset); } - diff --git a/sc2/src/sc2code/grpinfo.h b/sc2/src/sc2code/grpinfo.h new file mode 100755 index 000000000..ccfeaa161 --- /dev/null +++ b/sc2/src/sc2code/grpinfo.h @@ -0,0 +1,84 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _GRPINFO_H +#define _GRPINFO_H + +#include "port.h" +#include "libs/compiler.h" +#include "displist.h" +#include "libs/gfxlib.h" + // for POINT +#include + +typedef HLINK HIPGROUP; + +typedef struct +{ + // LINK elements; must be first + HIPGROUP pred; + HIPGROUP succ; + + /* unused: COUNT which_side; */ + + UWORD group_counter; + BYTE race_id; + BYTE sys_loc; + BYTE task; // AKA mission + BYTE in_system; + // a simple != 0 flag + // In older savegames this will be >1, because + // CloneShipFragment was used to spawn groups, + // and it set this to crew_level values + + BYTE dest_loc; + BYTE orbit_pos; + /* Also: saved prev dest_loc before intercept call, + * restored to dest_loc on all-clear */ + BYTE group_id; + POINT loc; + + FRAME melee_icon; +} IP_GROUP; + +enum +{ + IN_ORBIT = 0, + EXPLORE, + FLEE, + ON_STATION, + + IGNORE_FLAGSHIP = 1 << 2, + REFORM_GROUP = 1 << 3 +}; +#define MAX_REVOLUTIONS 5 + +#define STATION_RADIUS 1600 +#define ORBIT_RADIUS 2400 + +static inline IP_GROUP * +LockIpGroup (const QUEUE *pq, HIPGROUP h) +{ + assert (GetLinkSize (pq) == sizeof (IP_GROUP)); + return (IP_GROUP *) LockLink (pq, h); +} + +#define UnlockIpGroup(pq, h) UnlockLink (pq, h) +#define FreeIpGroup(pq, h) FreeLink (pq, h) + +extern HIPGROUP BuildGroup (QUEUE *pDstQueue, BYTE race_id); + +#endif /* _GRPINFO_H */ diff --git a/sc2/src/sc2code/hyper.c b/sc2/src/sc2code/hyper.c index 36d5b5b8c..5a2316cfd 100644 --- a/sc2/src/sc2code/hyper.c +++ b/sc2/src/sc2code/hyper.c @@ -172,10 +172,13 @@ check_hyperspace_encounter (void) encounter_flags = 0; percent = EncounterPercent[Type]; - if (encounter_radius != (COUNT)~0) + + if (encounter_radius != INFINITE_RADIUS) + { encounter_radius = (encounter_radius * SPHERE_RADIUS_INCREMENT) >> 1; - else + } + else /* encounter_radius == infinity */ { HENCOUNTER hNextEncounter; diff --git a/sc2/src/sc2code/ipdisp.c b/sc2/src/sc2code/ipdisp.c index 25754324f..a8770102c 100644 --- a/sc2/src/sc2code/ipdisp.c +++ b/sc2/src/sc2code/ipdisp.c @@ -20,6 +20,7 @@ #include "globdata.h" #include "init.h" #include "races.h" +#include "grpinfo.h" #include "encount.h" #include "libs/mathlib.h" @@ -27,32 +28,37 @@ void NotifyOthers (COUNT which_race, BYTE target_loc) { - HSHIPFRAG hStarShip, hNextShip; + HSHIPFRAG hGroup, hNextGroup; - for (hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)); - hStarShip; hStarShip = hNextShip) + for (hGroup = GetHeadLink (&GLOBAL (ip_group_q)); + hGroup; hGroup = hNextGroup) { - SHIP_FRAGMENT *StarShipPtr; + IP_GROUP *GroupPtr; - StarShipPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - hNextShip = _GetSuccLink (StarShipPtr); + GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup); + hNextGroup = _GetSuccLink (GroupPtr); - if (GET_RACE_ID (StarShipPtr) == which_race) + if (GroupPtr->race_id == which_race) { BYTE task; - task = GET_GROUP_MISSION (StarShipPtr) | IGNORE_FLAGSHIP; + task = GroupPtr->task | IGNORE_FLAGSHIP; if (target_loc == 0) { task &= ~IGNORE_FLAGSHIP; - SET_ORBIT_LOC (StarShipPtr, GET_GROUP_DEST (StarShipPtr)); + // XXX: orbit_pos is abused here to store the previous + // group destination, before the intercept task. + // Returned to dest_loc below. + GroupPtr->orbit_pos = GroupPtr->dest_loc; /* task = FLEE | IGNORE_FLAGSHIP; */ } - else if ((target_loc = GET_GROUP_DEST (StarShipPtr)) == 0) + else if ((target_loc = GroupPtr->dest_loc) == 0) { - target_loc = GET_ORBIT_LOC (StarShipPtr); - SET_ORBIT_LOC (StarShipPtr, NORMALIZE_FACING (TFB_Random ())); + // XXX: orbit_pos is abused to store the previous + // group destination, before the intercept task. + target_loc = GroupPtr->orbit_pos; + GroupPtr->orbit_pos = NORMALIZE_FACING (TFB_Random ()); #ifdef OLD target_loc = (BYTE)(( (COUNT)TFB_Random () @@ -61,19 +67,19 @@ NotifyOthers (COUNT which_race, BYTE target_loc) if (!(task & REFORM_GROUP)) { if ((task & ~IGNORE_FLAGSHIP) != EXPLORE) - StarShipPtr->group_counter = 0; + GroupPtr->group_counter = 0; else - StarShipPtr->group_counter = + GroupPtr->group_counter = ((COUNT) TFB_Random () % MAX_REVOLUTIONS) << FACING_SHIFT; } } - SET_GROUP_MISSION (StarShipPtr, task); - SET_GROUP_DEST (StarShipPtr, target_loc); + GroupPtr->task = task; + GroupPtr->dest_loc = target_loc; } - UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + UnlockIpGroup (&GLOBAL (ip_group_q), hGroup); } } @@ -87,7 +93,7 @@ ip_group_preprocess (ELEMENT *ElementPtr) POINT dest_pt; SIZE vdx, vdy; ELEMENT *EPtr; - SHIP_FRAGMENT *StarShipPtr; + IP_GROUP *GroupPtr; EPtr = ElementPtr; EPtr->state_flags &= @@ -95,10 +101,10 @@ ip_group_preprocess (ELEMENT *ElementPtr) ++EPtr->life_span; /* so that it will 'die' * again next time. */ - GetElementStarShip (EPtr, &StarShipPtr); - group_loc = GET_GROUP_LOC (StarShipPtr); + GetElementStarShip (EPtr, &GroupPtr); + group_loc = GroupPtr->sys_loc; /* save old location */ - DisplayArray[EPtr->PrimIndex].Object.Point = StarShipPtr->loc; + DisplayArray[EPtr->PrimIndex].Object.Point = GroupPtr->loc; if (group_loc != 0) radius = MAX_ZOOM_RADIUS; @@ -106,10 +112,10 @@ ip_group_preprocess (ELEMENT *ElementPtr) radius = pSolarSysState->SunDesc[0].radius; dest_pt.x = (SIS_SCREEN_WIDTH >> 1) - + (SIZE)((long)StarShipPtr->loc.x + + (SIZE)((long)GroupPtr->loc.x * (DISPLAY_FACTOR >> 1) / radius); dest_pt.y = (SIS_SCREEN_HEIGHT >> 1) - + (SIZE)((long)StarShipPtr->loc.y + + (SIZE)((long)GroupPtr->loc.y * (DISPLAY_FACTOR >> 1) / radius); EPtr->current.location.x = DISPLAY_TO_WORLD (dest_pt.x) + (COORD)(LOG_SPACE_WIDTH >> 1) @@ -126,18 +132,18 @@ ip_group_preprocess (ELEMENT *ElementPtr) flagship_loc = (BYTE)(pSolarSysState->pBaseDesc->pPrevDesc - pSolarSysState->PlanetDesc + 1); - task = GET_GROUP_MISSION (StarShipPtr); + task = GroupPtr->task; if (pSolarSysState->MenuState.CurState) goto ExitIPProcess; - if ((task & REFORM_GROUP) && --StarShipPtr->group_counter == 0) + if ((task & REFORM_GROUP) && --GroupPtr->group_counter == 0) { task &= ~REFORM_GROUP; - SET_GROUP_MISSION (StarShipPtr, task); + GroupPtr->task = task; if ((task & ~IGNORE_FLAGSHIP) != EXPLORE) - StarShipPtr->group_counter = 0; + GroupPtr->group_counter = 0; else - StarShipPtr->group_counter = ((COUNT)TFB_Random () + GroupPtr->group_counter = ((COUNT)TFB_Random () % MAX_REVOLUTIONS) << FACING_SHIFT; } @@ -157,7 +163,7 @@ ip_group_preprocess (ELEMENT *ElementPtr) } } - target_loc = GET_GROUP_DEST (StarShipPtr); + target_loc = GroupPtr->dest_loc; if (!(task & (IGNORE_FLAGSHIP | REFORM_GROUP))) { if (target_loc == 0 && task != FLEE) @@ -178,20 +184,20 @@ ip_group_preprocess (ELEMENT *ElementPtr) if (group_loc != 0) /* if in planetary views */ { detect_dist *= (MAX_ZOOM_RADIUS / MIN_ZOOM_RADIUS); - if (GET_RACE_ID (StarShipPtr) == URQUAN_PROBE_SHIP) + if (GroupPtr->race_id == URQUAN_PROBE_SHIP) detect_dist <<= 1; } - vdx = GLOBAL (ip_location.x) - StarShipPtr->loc.x; - vdy = GLOBAL (ip_location.y) - StarShipPtr->loc.y; + vdx = GLOBAL (ip_location.x) - GroupPtr->loc.x; + vdy = GLOBAL (ip_location.y) - GroupPtr->loc.y; if ((long)vdx * vdx + (long)vdy * vdy < (long)detect_dist * detect_dist) { EPtr->thrust_wait = 0; ZeroVelocityComponents (&EPtr->velocity); - NotifyOthers (GET_RACE_ID (StarShipPtr), 0); - task = GET_GROUP_MISSION (StarShipPtr); - if ((target_loc = GET_GROUP_DEST (StarShipPtr)) == 0) + NotifyOthers (GroupPtr->race_id, 0); + task = GroupPtr->task; + if ((target_loc = GroupPtr->dest_loc) == 0) target_loc = flagship_loc; } } @@ -203,7 +209,7 @@ ip_group_preprocess (ELEMENT *ElementPtr) if (task <= ON_STATION) #ifdef NEVER if (task <= FLEE || (task == ON_STATION - && GET_GROUP_DEST (StarShipPtr) == 0)) + && GroupPtr->dest_loc == 0)) #endif /* NEVER */ { BOOLEAN Transition; @@ -214,16 +220,15 @@ ip_group_preprocess (ELEMENT *ElementPtr) Transition = FALSE; if (task == FLEE) { - dest_pt.x = StarShipPtr->loc.x << 1; - dest_pt.y = StarShipPtr->loc.y << 1; + dest_pt.x = GroupPtr->loc.x << 1; + dest_pt.y = GroupPtr->loc.y << 1; } - else if (((task != ON_STATION || GET_GROUP_DEST (StarShipPtr) == 0) + else if (((task != ON_STATION || GroupPtr->dest_loc == 0) && group_loc == target_loc) - || (task == ON_STATION - && GET_GROUP_DEST (StarShipPtr) + || (task == ON_STATION && GroupPtr->dest_loc && group_loc == 0)) { - if (GET_GROUP_DEST (StarShipPtr) == 0) + if (GroupPtr->dest_loc == 0) dest_pt = GLOBAL (ip_location); else { @@ -247,37 +252,38 @@ ip_group_preprocess (ELEMENT *ElementPtr) ); } - angle = FACING_TO_ANGLE (GET_ORBIT_LOC (StarShipPtr) + 1); + angle = FACING_TO_ANGLE (GroupPtr->orbit_pos + 1); dest_pt.x = org.x + COSINE (angle, orbit_dist); dest_pt.y = org.y + SINE (angle, orbit_dist); - if (StarShipPtr->loc.x == dest_pt.x - && StarShipPtr->loc.y == dest_pt.y) + if (GroupPtr->loc.x == dest_pt.x + && GroupPtr->loc.y == dest_pt.y) { BYTE next_loc; - SET_ORBIT_LOC (StarShipPtr, - NORMALIZE_FACING (ANGLE_TO_FACING (angle))); + GroupPtr->orbit_pos = NORMALIZE_FACING ( + ANGLE_TO_FACING (angle)); angle += FACING_TO_ANGLE (1); dest_pt.x = org.x + COSINE (angle, orbit_dist); dest_pt.y = org.y + SINE (angle, orbit_dist); EPtr->thrust_wait = (BYTE)~0; - if (StarShipPtr->group_counter) - --StarShipPtr->group_counter; + if (GroupPtr->group_counter) + --GroupPtr->group_counter; else if (task == EXPLORE && (next_loc = (BYTE)(((COUNT)TFB_Random () % pSolarSysState->SunDesc[0].NumPlanets) + 1)) != target_loc) { EPtr->thrust_wait = 0; - SET_GROUP_DEST (StarShipPtr, target_loc = next_loc); + target_loc = next_loc; + GroupPtr->dest_loc = next_loc; } } } } else if (group_loc == 0) { - if (GET_GROUP_DEST (StarShipPtr) == 0) + if (GroupPtr->dest_loc == 0) dest_pt = pSolarSysState->SunDesc[0].location; else XFormIPLoc (&pSolarSysState->PlanetDesc[ @@ -288,12 +294,12 @@ ip_group_preprocess (ELEMENT *ElementPtr) if (task == ON_STATION) target_loc = 0; - dest_pt.x = StarShipPtr->loc.x << 1; - dest_pt.y = StarShipPtr->loc.y << 1; + dest_pt.x = GroupPtr->loc.x << 1; + dest_pt.y = GroupPtr->loc.y << 1; } - delta_x = dest_pt.x - StarShipPtr->loc.x; - delta_y = dest_pt.y - StarShipPtr->loc.y; + delta_x = dest_pt.x - GroupPtr->loc.x; + delta_y = dest_pt.y - GroupPtr->loc.y; angle = ARCTAN (delta_x, delta_y); if (EPtr->thrust_wait && EPtr->thrust_wait != (BYTE)~0) @@ -303,7 +309,7 @@ ip_group_preprocess (ELEMENT *ElementPtr) { SIZE speed; - if (EPtr->thrust_wait && GET_GROUP_DEST (StarShipPtr) != 0) + if (EPtr->thrust_wait && GroupPtr->dest_loc != 0) { #define ORBIT_SPEED 60 speed = ORBIT_SPEED; @@ -317,7 +323,7 @@ ip_group_preprocess (ELEMENT *ElementPtr) RACE_IP_SPEED }; - speed = RaceIPSpeed[GET_RACE_ID (StarShipPtr)]; + speed = RaceIPSpeed[GroupPtr->race_id]; EPtr->thrust_wait = TRACK_WAIT; } @@ -334,13 +340,13 @@ ip_group_preprocess (ELEMENT *ElementPtr) if (task == FLEE) goto CheckGetAway; } - else if (target_loc == GET_GROUP_DEST (StarShipPtr)) + else if (target_loc == GroupPtr->dest_loc) { PartialRevolution: if ((long)((COUNT)(dx * dx) + (COUNT)(dy * dy)) >= (long)delta_x * delta_x + (long)delta_y * delta_y) { - StarShipPtr->loc = dest_pt; + GroupPtr->loc = dest_pt; vdx = vdy = 0; ZeroVelocityComponents (&EPtr->velocity); } @@ -361,8 +367,7 @@ PartialRevolution: } } - if (task == ON_STATION - && GET_GROUP_DEST (StarShipPtr)) + if (task == ON_STATION && GroupPtr->dest_loc) goto PartialRevolution; else if ((long)((COUNT)(dx * dx) + (COUNT)(dy * dy)) >= (long)delta_x * delta_x + (long)delta_y * delta_y) @@ -372,10 +377,10 @@ PartialRevolution: { CheckGetAway: dest_pt.x = (SIS_SCREEN_WIDTH >> 1) - + (SIZE)((long)StarShipPtr->loc.x + + (SIZE)((long)GroupPtr->loc.x * (DISPLAY_FACTOR >> 1) / MAX_ZOOM_RADIUS); dest_pt.y = (SIS_SCREEN_HEIGHT >> 1) - + (SIZE)((long)StarShipPtr->loc.y + + (SIZE)((long)GroupPtr->loc.y * (DISPLAY_FACTOR >> 1) / MAX_ZOOM_RADIUS); if (dest_pt.x < 0 || dest_pt.x >= SIS_SCREEN_WIDTH @@ -396,38 +401,39 @@ CheckGetAway: PLANET_DESC *pCurDesc; pCurDesc = &pSolarSysState->PlanetDesc[group_loc - 1]; - XFormIPLoc (&pCurDesc->image.origin, &StarShipPtr->loc, + XFormIPLoc (&pCurDesc->image.origin, &GroupPtr->loc, FALSE); - SET_GROUP_LOC (StarShipPtr, group_loc = 0); + group_loc = 0; + GroupPtr->sys_loc = 0; } else if (target_loc == 0) { + /* Group completely left the star system */ EPtr->life_span = 0; EPtr->state_flags |= DISAPPEARING | NONSOLID; - StarShipPtr->crew_level = 0; + GroupPtr->in_system = 0; return; } else { - if (target_loc == GET_GROUP_DEST (StarShipPtr)) + if (target_loc == GroupPtr->dest_loc) { - SET_ORBIT_LOC (StarShipPtr, - NORMALIZE_FACING ( - ANGLE_TO_FACING (angle + HALF_CIRCLE) - )); - StarShipPtr->group_counter = + GroupPtr->orbit_pos = NORMALIZE_FACING ( + ANGLE_TO_FACING (angle + HALF_CIRCLE)); + GroupPtr->group_counter = ((COUNT)TFB_Random () % MAX_REVOLUTIONS) << FACING_SHIFT; } - StarShipPtr->loc.x = -(SIZE)((long)COSINE ( + GroupPtr->loc.x = -(SIZE)((long)COSINE ( angle, SIS_SCREEN_WIDTH * 9 / 16 ) * MAX_ZOOM_RADIUS / (DISPLAY_FACTOR >> 1)); - StarShipPtr->loc.y = -(SIZE)((long)SINE ( + GroupPtr->loc.y = -(SIZE)((long)SINE ( angle, SIS_SCREEN_WIDTH * 9 / 16 ) * MAX_ZOOM_RADIUS / (DISPLAY_FACTOR >> 1)); - SET_GROUP_LOC (StarShipPtr, group_loc = target_loc); + group_loc = target_loc; + GroupPtr->sys_loc = target_loc; } } } @@ -449,14 +455,14 @@ CheckGetAway: } } } - StarShipPtr->loc.x += vdx; - StarShipPtr->loc.y += vdy; + GroupPtr->loc.x += vdx; + GroupPtr->loc.y += vdy; dest_pt.x = (SIS_SCREEN_WIDTH >> 1) - + (SIZE)((long)StarShipPtr->loc.x + + (SIZE)((long)GroupPtr->loc.x * (DISPLAY_FACTOR >> 1) / radius); dest_pt.y = (SIS_SCREEN_HEIGHT >> 1) - + (SIZE)((long)StarShipPtr->loc.y + + (SIZE)((long)GroupPtr->loc.y * (DISPLAY_FACTOR >> 1) / radius); ExitIPProcess: @@ -469,7 +475,7 @@ ExitIPProcess: if (group_loc != flagship_loc || ((task & REFORM_GROUP) - && (StarShipPtr->group_counter & 1))) + && (GroupPtr->group_counter & 1))) { SetPrimType (&DisplayArray[EPtr->PrimIndex], NO_PRIM); EPtr->state_flags |= NONSOLID; @@ -508,7 +514,7 @@ static void ip_group_collision (ELEMENT *ElementPtr0, POINT *pPt0, ELEMENT *ElementPtr1, POINT *pPt1) { - SHIP_FRAGMENT *StarShipPtr; + IP_GROUP *GroupPtr; if ((GLOBAL (CurrentActivity) & START_ENCOUNTER) || pSolarSysState->MenuState.CurState @@ -518,7 +524,7 @@ ip_group_collision (ELEMENT *ElementPtr0, POINT *pPt0, return; } - GetElementStarShip (ElementPtr0, &StarShipPtr); + GetElementStarShip (ElementPtr0, &GroupPtr); if (ElementPtr0->state_flags & ElementPtr1->state_flags & BAD_GUY) { if ((ElementPtr0->state_flags & COLLISION) @@ -529,7 +535,7 @@ ip_group_collision (ELEMENT *ElementPtr0, POINT *pPt0, { ElementPtr1->state_flags |= COLLISION; - StarShipPtr->loc = + GroupPtr->loc = DisplayArray[ElementPtr0->PrimIndex].Object.Point; ElementPtr0->next.location = ElementPtr0->current.location; InitIntersectEndPoint (ElementPtr0); @@ -537,19 +543,18 @@ ip_group_collision (ELEMENT *ElementPtr0, POINT *pPt0, } else { - EncounterGroup = GET_GROUP_ID (StarShipPtr); + EncounterGroup = GroupPtr->group_id; - if (GET_RACE_ID (StarShipPtr) == URQUAN_PROBE_SHIP) + if (GroupPtr->race_id == URQUAN_PROBE_SHIP) { - SET_GROUP_MISSION (StarShipPtr, FLEE | IGNORE_FLAGSHIP); - SET_GROUP_DEST (StarShipPtr, 0); + GroupPtr->task = FLEE | IGNORE_FLAGSHIP; + GroupPtr->dest_loc = 0; } else { - SET_GROUP_MISSION (StarShipPtr, - GET_GROUP_MISSION (StarShipPtr) | REFORM_GROUP); - StarShipPtr->group_counter = 100; - NotifyOthers (GET_RACE_ID (StarShipPtr), (BYTE)~0); + GroupPtr->task |= REFORM_GROUP; + GroupPtr->group_counter = 100; + NotifyOthers (GroupPtr->race_id, (BYTE)~0); } if (!(ElementPtr1->state_flags & COLLISION)) /* not processed yet */ @@ -565,7 +570,7 @@ ip_group_collision (ELEMENT *ElementPtr0, POINT *pPt0, } static void -spawn_ip_group (SHIP_FRAGMENT *StarShipPtr) +spawn_ip_group (IP_GROUP *GroupPtr) { HELEMENT hIPSHIPElement; @@ -576,31 +581,33 @@ spawn_ip_group (SHIP_FRAGMENT *StarShipPtr) ELEMENT *IPSHIPElementPtr; LockElement (hIPSHIPElement, &IPSHIPElementPtr); - IPSHIPElementPtr->turn_wait = GET_GROUP_ID (StarShipPtr); + // XXX: turn_wait hack is not actually used anywhere + IPSHIPElementPtr->turn_wait = GroupPtr->group_id; IPSHIPElementPtr->mass_points = 1; IPSHIPElementPtr->hit_points = 1; IPSHIPElementPtr->state_flags = CHANGING | FINITE_LIFE | IGNORE_VELOCITY; - task = GET_GROUP_MISSION (StarShipPtr); + task = GroupPtr->task; if (!(task & IGNORE_FLAGSHIP)) IPSHIPElementPtr->state_flags |= BAD_GUY; else { IPSHIPElementPtr->state_flags |= GOOD_GUY; - if (GET_RACE_ID (StarShipPtr) == YEHAT_SHIP + // XXX: Hack: Yehat revolution start, fleeing groups + if (GroupPtr->race_id == YEHAT_SHIP && GET_GAME_STATE (YEHAT_CIVIL_WAR)) { - SET_GROUP_MISSION (StarShipPtr, FLEE | (task & REFORM_GROUP)); - SET_GROUP_DEST (StarShipPtr, 0); + GroupPtr->task = FLEE | (task & REFORM_GROUP); + GroupPtr->dest_loc = 0; } } SetPrimType (&DisplayArray[IPSHIPElementPtr->PrimIndex], STAMP_PRIM); // XXX: Hack: farray points to FRAME[3] and given FRAME - IPSHIPElementPtr->current.image.farray = &StarShipPtr->melee_icon; + IPSHIPElementPtr->current.image.farray = &GroupPtr->melee_icon; IPSHIPElementPtr->current.image.frame = SetAbsFrameIndex ( - StarShipPtr->melee_icon, 1); + GroupPtr->melee_icon, 1); /* preprocessing has a side effect * we wish to avoid. So death_func * is used instead, but will achieve @@ -614,16 +621,16 @@ spawn_ip_group (SHIP_FRAGMENT *StarShipPtr) SIZE radius; POINT pt; - if (GET_GROUP_LOC (StarShipPtr) != 0) + if (GroupPtr->sys_loc != 0) radius = MAX_ZOOM_RADIUS; else radius = pSolarSysState->SunDesc[0].radius; pt.x = (SIS_SCREEN_WIDTH >> 1) - + (SIZE)((long)StarShipPtr->loc.x + + (SIZE)((long)GroupPtr->loc.x * DISPLAY_FACTOR / radius); pt.y = (SIS_SCREEN_HEIGHT >> 1) - + (SIZE)((long)StarShipPtr->loc.y + + (SIZE)((long)GroupPtr->loc.y * (DISPLAY_FACTOR >> 1) / radius); IPSHIPElementPtr->current.location.x = @@ -636,7 +643,7 @@ spawn_ip_group (SHIP_FRAGMENT *StarShipPtr) - (LOG_SPACE_HEIGHT >> (MAX_REDUCTION + 1)); } - SetElementStarShip (IPSHIPElementPtr, StarShipPtr); + SetElementStarShip (IPSHIPElementPtr, GroupPtr); SetUpElement (IPSHIPElementPtr); IPSHIPElementPtr->IntersectControl.IntersectStamp.frame = @@ -812,7 +819,7 @@ spawn_flag_ship (void) void DoMissions (void) { - HSHIPFRAG hStarShip, hNextShip; + HSHIPFRAG hGroup, hNextGroup; spawn_flag_ship (); @@ -822,18 +829,18 @@ DoMissions (void) EncounterRace = -1; } - for (hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)); - hStarShip; hStarShip = hNextShip) + for (hGroup = GetHeadLink (&GLOBAL (ip_group_q)); + hGroup; hGroup = hNextGroup) { - SHIP_FRAGMENT *StarShipPtr; + IP_GROUP *GroupPtr; - StarShipPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - hNextShip = _GetSuccLink (StarShipPtr); + GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup); + hNextGroup = _GetSuccLink (GroupPtr); - if (StarShipPtr->crew_level) - spawn_ip_group (StarShipPtr); + if (GroupPtr->in_system) + spawn_ip_group (GroupPtr); - UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + UnlockIpGroup (&GLOBAL (ip_group_q), hGroup); } } diff --git a/sc2/src/sc2code/load.c b/sc2/src/sc2code/load.c index 8493bdf12..50a2b8eb6 100644 --- a/sc2/src/sc2code/load.c +++ b/sc2/src/sc2code/load.c @@ -29,6 +29,7 @@ #include "options.h" #include "setup.h" #include "state.h" +#include "grpinfo.h" #include "libs/tasklib.h" #include "libs/log.h" @@ -172,9 +173,9 @@ LoadShipQueue (DECODE_REF fh, QUEUE *pQueue) cread_16 (fh, &FragPtr->which_side); cread_8 (fh, &FragPtr->captains_name_index); cread_8 (fh, NULL); /* padding */ - cread_16 (fh, &FragPtr->ship_flags); - cread_8 (fh, &FragPtr->var1); - cread_8 (fh, &FragPtr->var2); + cread_16 (fh, NULL); /* unused: was ship_flags */ + cread_8 (fh, &FragPtr->race_id); + cread_8 (fh, &FragPtr->index); // XXX: reading crew as BYTE to maintain savegame compatibility cread_8 (fh, &tmpb); FragPtr->crew_level = tmpb; @@ -182,8 +183,8 @@ LoadShipQueue (DECODE_REF fh, QUEUE *pQueue) FragPtr->max_crew = tmpb; cread_8 (fh, &FragPtr->energy_level); cread_8 (fh, &FragPtr->max_energy); - cread_16 (fh, &FragPtr->loc.x); - cread_16 (fh, &FragPtr->loc.y); + cread_16 (fh, NULL); /* unused; was loc.x */ + cread_16 (fh, NULL); /* unused; was loc.y */ UnlockShipFrag (pQueue, hStarShip); } @@ -216,7 +217,7 @@ LoadRaceQueue (DECODE_REF fh, QUEUE *pQueue) FleetPtr->crew_level = tmpb; cread_8 (fh, &tmpb); FleetPtr->max_crew = tmpb; - cread_8 (fh, &FleetPtr->energy_level); + cread_8 (fh, &FleetPtr->growth); cread_8 (fh, &FleetPtr->max_energy); cread_16 (fh, &FleetPtr->loc.x); cread_16 (fh, &FleetPtr->loc.y); @@ -235,6 +236,45 @@ LoadRaceQueue (DECODE_REF fh, QUEUE *pQueue) } } +static void +LoadGroupQueue (DECODE_REF fh, QUEUE *pQueue) +{ + COUNT num_links; + + cread_16 (fh, &num_links); + + while (num_links--) + { + HIPGROUP hGroup; + IP_GROUP *GroupPtr; + BYTE tmpb; + + cread_16 (fh, NULL); /* unused; was race_id */ + + hGroup = BuildGroup (pQueue, 0); + GroupPtr = LockIpGroup (pQueue, hGroup); + + cread_16 (fh, NULL); /* unused; was which_side */ + cread_8 (fh, NULL); /* unused; was captains_name_index */ + cread_8 (fh, NULL); /* padding; for savegame compat */ + cread_16 (fh, &GroupPtr->group_counter); + cread_8 (fh, &GroupPtr->race_id); + cread_8 (fh, &tmpb); /* was var2 */ + GroupPtr->sys_loc = LONIBBLE (tmpb); + GroupPtr->task = HINIBBLE (tmpb); + cread_8 (fh, &GroupPtr->in_system); /* was crew_level */ + cread_8 (fh, NULL); /* unused; was max_crew */ + cread_8 (fh, &tmpb); /* was energy_level */ + GroupPtr->dest_loc = LONIBBLE (tmpb); + GroupPtr->orbit_pos = HINIBBLE (tmpb); + cread_8 (fh, &GroupPtr->group_id); /* was max_energy */ + cread_16 (fh, &GroupPtr->loc.x); + cread_16 (fh, &GroupPtr->loc.y); + + UnlockIpGroup (pQueue, hGroup); + } +} + static void LoadEncounter (ENCOUNTER *EncounterPtr, DECODE_REF fh) { @@ -379,6 +419,7 @@ LoadGameState (GAME_STATE *GSPtr, DECODE_REF fh) DummyLoadQueue (&GSPtr->avail_race_q, fh); DummyLoadQueue (&GSPtr->npc_built_ship_q, fh); + // Not loading ip_group_q, was not there originally DummyLoadQueue (&GSPtr->encounter_q, fh); DummyLoadQueue (&GSPtr->built_ship_q, fh); @@ -514,6 +555,7 @@ LoadGame (COUNT which_game, SUMMARY_DESC *SummPtr) ReinitQueue (&GLOBAL (GameClock.event_q)); ReinitQueue (&GLOBAL (encounter_q)); + ReinitQueue (&GLOBAL (ip_group_q)); ReinitQueue (&GLOBAL (npc_built_ship_q)); ReinitQueue (&GLOBAL (built_ship_q)); @@ -538,11 +580,13 @@ LoadGame (COUNT which_game, SUMMARY_DESC *SummPtr) if (!(NextActivity & START_INTERPLANETARY)) { if (NextActivity & START_ENCOUNTER) - // load npc queue LoadShipQueue (fh, &GLOBAL (npc_built_ship_q)); else if (LOBYTE (NextActivity) == IN_INTERPLANETARY) - // load group queue - LoadShipQueue (fh, &GLOBAL (npc_built_ship_q)); + // XXX: Technically, this queue does not need to be + // saved/loaded at all. IP groups will be reloaded + // from group state files. But the original code did, + // and so will we until we can prove we do not need to. + LoadGroupQueue (fh, &GLOBAL (ip_group_q)); else // XXX: The empty queue read is only needed to maintain // the savegame compatibility diff --git a/sc2/src/sc2code/master.c b/sc2/src/sc2code/master.c index 344565292..95e81a8ec 100644 --- a/sc2/src/sc2code/master.c +++ b/sc2/src/sc2code/master.c @@ -68,6 +68,7 @@ LoadMasterShipList (void (* YieldProcessing)(void)) // Grab a copy of loaded icons, strings and info // XXX: SHIP_INFO implicitly referenced here BuiltPtr->ShipInfo = RDPtr->ship_info; + BuiltPtr->Fleet = RDPtr->fleet; free_ship (RDPtr, FALSE, FALSE); GetStringContents (SetAbsStringTableIndex ( diff --git a/sc2/src/sc2code/master.h b/sc2/src/sc2code/master.h index 4544e1e66..505878abe 100644 --- a/sc2/src/sc2code/master.h +++ b/sc2/src/sc2code/master.h @@ -31,6 +31,9 @@ typedef struct DWORD RaceResIndex; SHIP_INFO ShipInfo; + FLEET_STUFF Fleet; + // FLEET_STUFF is only necessary here because avail_race_q + // is initialized in part from master_q (kinda hacky) } MASTER_SHIP_INFO; extern QUEUE master_q; diff --git a/sc2/src/sc2code/planets/devices.c b/sc2/src/sc2code/planets/devices.c index d741d745b..72169276b 100644 --- a/sc2/src/sc2code/planets/devices.c +++ b/sc2/src/sc2code/planets/devices.c @@ -25,6 +25,7 @@ #include "load.h" #include "setup.h" #include "state.h" +#include "grpinfo.h" #include "sounds.h" #include "util.h" #include "strlib.h" @@ -217,7 +218,8 @@ UseCaster (void) EncounterGroup = 0; PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7); SaveFlagshipState (); @@ -226,20 +228,20 @@ UseCaster (void) { BOOLEAN FoundIlwrath; - HSHIPFRAG hStarShip; + HIPGROUP hGroup; FoundIlwrath = (BOOLEAN)(CurStarDescPtr->Index == ILWRATH_DEFINED); // In the Ilwrath home system? if (!FoundIlwrath && - (hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)))) + (hGroup = GetHeadLink (&GLOBAL (ip_group_q)))) { - // Ilwrath ship is in the system. - SHIP_FRAGMENT *FragPtr; + // Is an Ilwrath ship in the system? + IP_GROUP *GroupPtr; - FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - FoundIlwrath = (GET_RACE_ID (FragPtr) == ILWRATH_SHIP); - UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup); + FoundIlwrath = (GroupPtr->race_id == ILWRATH_SHIP); + UnlockIpGroup (&GLOBAL (ip_group_q), hGroup); } if (FoundIlwrath) @@ -249,7 +251,8 @@ UseCaster (void) EncounterGroup = 0; PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); if (CurStarDescPtr->Index == ILWRATH_DEFINED) { @@ -321,7 +324,8 @@ DeviceFailed (BYTE which_device) GLOBAL (CurrentActivity) |= START_ENCOUNTER; PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); CloneShipFragment (CHMMR_SHIP, &GLOBAL (npc_built_ship_q), 0); @@ -359,12 +363,13 @@ DeviceFailed (BYTE which_device) else { EncounterGroup = 0; - if (GetHeadLink (&GLOBAL (npc_built_ship_q))) + if (GetHeadLink (&GLOBAL (ip_group_q))) { SET_GAME_STATE (SHIP_TO_COMPEL, 1); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); } if (CurStarDescPtr->Index == SAMATRA_DEFINED) diff --git a/sc2/src/sc2code/planets/genchmmr.c b/sc2/src/sc2code/planets/genchmmr.c index a79fd46c5..d58526e1a 100644 --- a/sc2/src/sc2code/planets/genchmmr.c +++ b/sc2/src/sc2code/planets/genchmmr.c @@ -79,7 +79,8 @@ GenerateChmmr (BYTE control) && ActivateStarShip (ILWRATH_SHIP, SPHERE_TRACKING)) { PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); CloneShipFragment (ILWRATH_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); diff --git a/sc2/src/sc2code/planets/gencol.c b/sc2/src/sc2code/planets/gencol.c index b25bfa349..57a47f49e 100644 --- a/sc2/src/sc2code/planets/gencol.c +++ b/sc2/src/sc2code/planets/gencol.c @@ -19,6 +19,7 @@ #include "build.h" #include "globdata.h" #include "state.h" +#include "grpinfo.h" #include "planets/genall.h" @@ -29,7 +30,7 @@ GenerateColony (BYTE control) { case INIT_NPCS: { - HSHIPFRAG hStarShip; + HIPGROUP hGroup; GLOBAL (BattleGroupRef) = GET_GAME_STATE_32 (COLONY_GRPOFFS0); if (GLOBAL (BattleGroupRef) == 0) @@ -44,18 +45,18 @@ GenerateColony (BYTE control) GenerateRandomIP (INIT_NPCS); if (GLOBAL (BattleGroupRef) - && (hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)))) + && (hGroup = GetHeadLink (&GLOBAL (ip_group_q)))) { - SHIP_FRAGMENT *FragPtr; + IP_GROUP *GroupPtr; - FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - SET_GROUP_MISSION (FragPtr, IN_ORBIT); - SET_GROUP_LOC (FragPtr, 0 + 1); /* orbitting colony */ - SET_GROUP_DEST (FragPtr, 0 + 1); /* orbitting colony */ - FragPtr->loc.x = 0; - FragPtr->loc.y = 0; - FragPtr->group_counter = 0; - UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup); + GroupPtr->task = IN_ORBIT; + GroupPtr->sys_loc = 0 + 1; /* orbitting colony */ + GroupPtr->dest_loc = 0 + 1; /* orbitting colony */ + GroupPtr->loc.x = 0; + GroupPtr->loc.y = 0; + GroupPtr->group_counter = 0; + UnlockIpGroup (&GLOBAL (ip_group_q), hGroup); } break; } diff --git a/sc2/src/sc2code/planets/gendru.c b/sc2/src/sc2code/planets/gendru.c index b2bc1f27b..b5dace24f 100644 --- a/sc2/src/sc2code/planets/gendru.c +++ b/sc2/src/sc2code/planets/gendru.c @@ -115,7 +115,8 @@ GenerateDruuge (BYTE control) { NotifyOthers (DRUUGE_SHIP, (BYTE)~0); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); CloneShipFragment (DRUUGE_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); diff --git a/sc2/src/sc2code/planets/genilw.c b/sc2/src/sc2code/planets/genilw.c index 0b2e7bee0..f9ff4b43c 100644 --- a/sc2/src/sc2code/planets/genilw.c +++ b/sc2/src/sc2code/planets/genilw.c @@ -88,7 +88,8 @@ GenerateIlwrath (BYTE control) { NotifyOthers (ILWRATH_SHIP, (BYTE)~0); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); CloneShipFragment (ILWRATH_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); diff --git a/sc2/src/sc2code/planets/genmyc.c b/sc2/src/sc2code/planets/genmyc.c index 35d8d74cb..673206ff6 100644 --- a/sc2/src/sc2code/planets/genmyc.c +++ b/sc2/src/sc2code/planets/genmyc.c @@ -135,7 +135,8 @@ GenerateMycon (BYTE control) { NotifyOthers (MYCON_SHIP, (BYTE)~0); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); if (CurStarDescPtr->Index == MYCON_DEFINED || !GET_GAME_STATE (MYCON_FELL_FOR_AMBUSH)) diff --git a/sc2/src/sc2code/planets/genorz.c b/sc2/src/sc2code/planets/genorz.c index 82e00578e..8e2467b7f 100644 --- a/sc2/src/sc2code/planets/genorz.c +++ b/sc2/src/sc2code/planets/genorz.c @@ -303,7 +303,8 @@ GenerateOrz (BYTE control) { NotifyOthers (ORZ_SHIP, (BYTE)~0); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); if (CurStarDescPtr->Index == ORZ_DEFINED) { diff --git a/sc2/src/sc2code/planets/genpet.c b/sc2/src/sc2code/planets/genpet.c index 0b8587bb8..c5e8110e0 100644 --- a/sc2/src/sc2code/planets/genpet.c +++ b/sc2/src/sc2code/planets/genpet.c @@ -171,7 +171,8 @@ GenerateTalkingPet (BYTE control) { NotifyOthers (UMGAH_SHIP, (BYTE)~0); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); if (ActivateStarShip (UMGAH_SHIP, SPHERE_TRACKING)) { diff --git a/sc2/src/sc2code/planets/genpku.c b/sc2/src/sc2code/planets/genpku.c index dad4c792a..01838470e 100644 --- a/sc2/src/sc2code/planets/genpku.c +++ b/sc2/src/sc2code/planets/genpku.c @@ -107,7 +107,8 @@ GeneratePkunk (BYTE control) { NotifyOthers (PKUNK_SHIP, (BYTE)~0); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); CloneShipFragment (PKUNK_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); diff --git a/sc2/src/sc2code/planets/gensam.c b/sc2/src/sc2code/planets/gensam.c index ac666ca68..5b68e1b37 100644 --- a/sc2/src/sc2code/planets/gensam.c +++ b/sc2/src/sc2code/planets/gensam.c @@ -22,6 +22,7 @@ #include "resinst.h" #include "races.h" #include "state.h" +#include "grpinfo.h" #include "planets/genall.h" #include "libs/mathlib.h" @@ -32,7 +33,7 @@ BuildUrquanGuard (void) BYTE ship1, ship2; BYTE b0, b1; POINT org; - HSHIPFRAG hStarShip, hNextShip; + HIPGROUP hGroup, hNextGroup; GLOBAL (BattleGroupRef) = GET_GAME_STATE_32 (SAMATRA_GRPOFFS0); @@ -41,6 +42,8 @@ BuildUrquanGuard (void) else ship1 = BLACK_URQUAN_SHIP, ship2 = URQUAN_SHIP; + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); + for (b0 = 0; b0 < MAX_SHIPS_PER_SIDE; ++b0) CloneShipFragment (ship1, &GLOBAL (npc_built_ship_q), 0); @@ -65,53 +68,48 @@ BuildUrquanGuard (void) GetGroupInfo (GLOBAL (BattleGroupRef), GROUP_INIT_IP); - XFormIPLoc ( - &pSolarSysState->PlanetDesc[4].image.origin, - &org, - FALSE - ); - hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)); + XFormIPLoc (&pSolarSysState->PlanetDesc[4].image.origin, + &org, FALSE); + hGroup = GetHeadLink (&GLOBAL (ip_group_q)); for (b0 = 0, b1 = 0; b0 < NUM_URQUAN_GUARDS0; ++b0, b1 += FULL_CIRCLE / (NUM_URQUAN_GUARDS0 + NUM_URQUAN_GUARDS1)) { - SHIP_FRAGMENT *FragPtr; + IP_GROUP *GroupPtr; if (b1 % (FULL_CIRCLE / NUM_URQUAN_GUARDS1) == 0) b1 += FULL_CIRCLE / (NUM_URQUAN_GUARDS0 + NUM_URQUAN_GUARDS1); - FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - hNextShip = _GetSuccLink (FragPtr); - SET_GROUP_MISSION (FragPtr, ON_STATION | IGNORE_FLAGSHIP); - SET_GROUP_LOC (FragPtr, 0); - SET_GROUP_DEST (FragPtr, 4 + 1); - SET_ORBIT_LOC (FragPtr, - NORMALIZE_FACING (ANGLE_TO_FACING (b1))); - FragPtr->group_counter = 0; - FragPtr->loc.x = org.x + COSINE (b1, STATION_RADIUS); - FragPtr->loc.y = org.y + SINE (b1, STATION_RADIUS); - UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - hStarShip = hNextShip; + GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup); + hNextGroup = _GetSuccLink (GroupPtr); + GroupPtr->task = ON_STATION | IGNORE_FLAGSHIP; + GroupPtr->sys_loc = 0; + GroupPtr->dest_loc = 4 + 1; + GroupPtr->orbit_pos = NORMALIZE_FACING (ANGLE_TO_FACING (b1)); + GroupPtr->group_counter = 0; + GroupPtr->loc.x = org.x + COSINE (b1, STATION_RADIUS); + GroupPtr->loc.y = org.y + SINE (b1, STATION_RADIUS); + UnlockIpGroup (&GLOBAL (ip_group_q), hGroup); + hGroup = hNextGroup; } for (b0 = 0, b1 = 0; b0 < NUM_URQUAN_GUARDS1; ++b0, b1 += FULL_CIRCLE / NUM_URQUAN_GUARDS1) { - SHIP_FRAGMENT *FragPtr; + IP_GROUP *GroupPtr; - FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - hNextShip = _GetSuccLink (FragPtr); - SET_GROUP_MISSION (FragPtr, ON_STATION | IGNORE_FLAGSHIP); - SET_GROUP_LOC (FragPtr, 0); - SET_GROUP_DEST (FragPtr, 4 + 1); - SET_ORBIT_LOC (FragPtr, - NORMALIZE_FACING (ANGLE_TO_FACING (b1))); - FragPtr->group_counter = 0; - FragPtr->loc.x = org.x + COSINE (b1, STATION_RADIUS); - FragPtr->loc.y = org.y + SINE (b1, STATION_RADIUS); - UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - hStarShip = hNextShip; + GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup); + hNextGroup = _GetSuccLink (GroupPtr); + GroupPtr->task = ON_STATION | IGNORE_FLAGSHIP; + GroupPtr->sys_loc = 0; + GroupPtr->dest_loc = 4 + 1; + GroupPtr->orbit_pos = NORMALIZE_FACING (ANGLE_TO_FACING (b1)); + GroupPtr->group_counter = 0; + GroupPtr->loc.x = org.x + COSINE (b1, STATION_RADIUS); + GroupPtr->loc.y = org.y + SINE (b1, STATION_RADIUS); + UnlockIpGroup (&GLOBAL (ip_group_q), hGroup); + hGroup = hNextGroup; } } @@ -134,36 +132,32 @@ GenerateSamatra (BYTE control) EncounterRace = -1; // Do not want guards to chase the player { BOOLEAN GuardEngaged; - HSHIPFRAG hStarShip, hNextShip; + HIPGROUP hGroup, hNextGroup; GuardEngaged = FALSE; - for (hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)); - hStarShip; hStarShip = hNextShip) + for (hGroup = GetHeadLink (&GLOBAL (ip_group_q)); + hGroup; hGroup = hNextGroup) { - BYTE task; - SHIP_FRAGMENT *FragPtr; + IP_GROUP *GroupPtr; - FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), - hStarShip); - hNextShip = _GetSuccLink (FragPtr); + GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup); + hNextGroup = _GetSuccLink (GroupPtr); - task = GET_GROUP_MISSION (FragPtr); if (GET_GAME_STATE (URQUAN_MESSED_UP)) { - SET_GROUP_MISSION (FragPtr, - FLEE | IGNORE_FLAGSHIP | (task & REFORM_GROUP)); - SET_GROUP_DEST (FragPtr, 0); + GroupPtr->task &= REFORM_GROUP; + GroupPtr->task |= FLEE | IGNORE_FLAGSHIP; + GroupPtr->dest_loc = 0; } - else if (task & REFORM_GROUP) + else if (GroupPtr->task & REFORM_GROUP) { - task &= ~REFORM_GROUP; - FragPtr->group_counter = 0; - SET_GROUP_MISSION (FragPtr, task); + GroupPtr->task &= ~REFORM_GROUP; + GroupPtr->group_counter = 0; GuardEngaged = TRUE; } - UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + UnlockIpGroup (&GLOBAL (ip_group_q), hGroup); } if (GuardEngaged) @@ -173,22 +167,13 @@ GenerateSamatra (BYTE control) XFormIPLoc ( &pSolarSysState->PlanetDesc[4].image.origin, - &org, - FALSE - ); - angle = ARCTAN ( - GLOBAL (ip_location.x) - org.x, - GLOBAL (ip_location.y) - org.y - ); - GLOBAL (ip_location.x) = org.x - + COSINE (angle, 3000); - GLOBAL (ip_location.y) = org.y - + SINE (angle, 3000); - XFormIPLoc ( - &GLOBAL (ip_location), - &GLOBAL (ShipStamp.origin), - TRUE - ); + &org, FALSE); + angle = ARCTAN (GLOBAL (ip_location.x) - org.x, + GLOBAL (ip_location.y) - org.y); + GLOBAL (ip_location.x) = org.x + COSINE (angle, 3000); + GLOBAL (ip_location.y) = org.y + SINE (angle, 3000); + XFormIPLoc (&GLOBAL (ip_location), + &GLOBAL (ShipStamp.origin), TRUE); } } break; @@ -220,7 +205,8 @@ GenerateSamatra (BYTE control) && pSolarSysState->pOrbitalDesc == &pSolarSysState->MoonDesc[0]) { PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); if (!GET_GAME_STATE (URQUAN_MESSED_UP)) CloneShipFragment (!GET_GAME_STATE (KOHR_AH_FRENZY) ? diff --git a/sc2/src/sc2code/planets/genshof.c b/sc2/src/sc2code/planets/genshof.c index 538761177..209ca3142 100644 --- a/sc2/src/sc2code/planets/genshof.c +++ b/sc2/src/sc2code/planets/genshof.c @@ -19,29 +19,28 @@ #include "build.h" #include "globdata.h" #include "state.h" +#include "grpinfo.h" #include "planets/genall.h" static void check_old_shofixti (void) { - HSHIPFRAG hStarShip; + HIPGROUP hGroup; if (GLOBAL (BattleGroupRef) - && (hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q))) + && (hGroup = GetHeadLink (&GLOBAL (ip_group_q))) && GET_GAME_STATE (SHOFIXTI_RECRUITED)) { - BYTE task; - SHIP_FRAGMENT *FragPtr; + IP_GROUP *GroupPtr; - FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - task = GET_GROUP_MISSION (FragPtr); + GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup); - SET_GROUP_MISSION (FragPtr, - FLEE | IGNORE_FLAGSHIP | (task & REFORM_GROUP)); - SET_GROUP_DEST (FragPtr, 0); + GroupPtr->task &= REFORM_GROUP; + GroupPtr->task |= FLEE | IGNORE_FLAGSHIP; + GroupPtr->dest_loc = 0; - UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + UnlockIpGroup (&GLOBAL (ip_group_q), hGroup); } } @@ -91,7 +90,7 @@ GenerateShofixti (BYTE control) case UNINIT_NPCS: if (GLOBAL (BattleGroupRef) && !GET_GAME_STATE (SHOFIXTI_RECRUITED) - && GetHeadLink (&GLOBAL (npc_built_ship_q)) == 0) + && GetHeadLink (&GLOBAL (ip_group_q)) == 0) { if (!GET_GAME_STATE (SHOFIXTI_KIA)) { diff --git a/sc2/src/sc2code/planets/gensol.c b/sc2/src/sc2code/planets/gensol.c index 9bb94221b..1b636088c 100644 --- a/sc2/src/sc2code/planets/gensol.c +++ b/sc2/src/sc2code/planets/gensol.c @@ -25,6 +25,7 @@ #include "races.h" #include "resinst.h" #include "state.h" +#include "grpinfo.h" #include "encount.h" #include "planets/genall.h" #include "libs/mathlib.h" @@ -33,22 +34,22 @@ static int init_probe (void) { - HSHIPFRAG hStarShip; + HIPGROUP hGroup; if (!GET_GAME_STATE (PROBE_MESSAGE_DELIVERED) && GetGroupInfo (GLOBAL (BattleGroupRef), GROUP_INIT_IP) - && (hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)))) + && (hGroup = GetHeadLink (&GLOBAL (ip_group_q)))) { - SHIP_FRAGMENT *FragPtr; + IP_GROUP *GroupPtr; - FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - SET_GROUP_MISSION (FragPtr, IN_ORBIT); - SET_GROUP_LOC (FragPtr, 2 + 1); /* orbitting earth */ - SET_GROUP_DEST (FragPtr, 2 + 1); /* orbitting earth */ - FragPtr->loc.x = 0; - FragPtr->loc.y = 0; - FragPtr->group_counter = 0; - UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup); + GroupPtr->task = IN_ORBIT; + GroupPtr->sys_loc = 2 + 1; /* orbitting earth */ + GroupPtr->dest_loc = 2 + 1; /* orbitting earth */ + GroupPtr->loc.x = 0; + GroupPtr->loc.y = 0; + GroupPtr->group_counter = 0; + UnlockIpGroup (&GLOBAL (ip_group_q), hGroup); return 1; } @@ -154,7 +155,8 @@ generate_orbital (void) && pSolarSysState->pOrbitalDesc == &pSolarSysState->MoonDesc[0]) { PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); EncounterGroup = 0; GLOBAL (CurrentActivity) |= START_ENCOUNTER; @@ -427,7 +429,8 @@ GenerateSOL (BYTE control) else { GLOBAL (BattleGroupRef) = 0; - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); } break; case GENERATE_ENERGY: diff --git a/sc2/src/sc2code/planets/genspa.c b/sc2/src/sc2code/planets/genspa.c index 7bd58a046..c6386a855 100644 --- a/sc2/src/sc2code/planets/genspa.c +++ b/sc2/src/sc2code/planets/genspa.c @@ -160,7 +160,8 @@ GenerateSpathi (BYTE control) { NotifyOthers (SPATHI_SHIP, (BYTE)~0); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); CloneShipFragment (SPATHI_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); diff --git a/sc2/src/sc2code/planets/gensup.c b/sc2/src/sc2code/planets/gensup.c index 420b73877..f4e4cacee 100644 --- a/sc2/src/sc2code/planets/gensup.c +++ b/sc2/src/sc2code/planets/gensup.c @@ -105,7 +105,8 @@ GenerateSupox (BYTE control) { NotifyOthers (SUPOX_SHIP, (BYTE)~0); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); CloneShipFragment (SUPOX_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); diff --git a/sc2/src/sc2code/planets/genthrad.c b/sc2/src/sc2code/planets/genthrad.c index b911c8b49..7eb2dc11a 100644 --- a/sc2/src/sc2code/planets/genthrad.c +++ b/sc2/src/sc2code/planets/genthrad.c @@ -146,7 +146,8 @@ GenerateThradd (BYTE control) { NotifyOthers (THRADDASH_SHIP, (BYTE)~0); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); CloneShipFragment (THRADDASH_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); diff --git a/sc2/src/sc2code/planets/genutw.c b/sc2/src/sc2code/planets/genutw.c index c59217f38..65f0cba5a 100644 --- a/sc2/src/sc2code/planets/genutw.c +++ b/sc2/src/sc2code/planets/genutw.c @@ -34,7 +34,10 @@ GenerateUtwig (BYTE control) case INIT_NPCS: if (CurStarDescPtr->Index == BOMB_DEFINED && !GET_GAME_STATE (UTWIG_BOMB)) - ReinitQueue (&GLOBAL (npc_built_ship_q)); + { + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); + } else GenerateRandomIP (INIT_NPCS); break; @@ -147,7 +150,8 @@ GenerateUtwig (BYTE control) { NotifyOthers (UTWIG_SHIP, (BYTE)~0); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); CloneShipFragment (UTWIG_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); @@ -180,7 +184,8 @@ GenerateUtwig (BYTE control) COUNT i; PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); for (i = 0; i < 5; ++i) CloneShipFragment (DRUUGE_SHIP, diff --git a/sc2/src/sc2code/planets/genvux.c b/sc2/src/sc2code/planets/genvux.c index 64fd723f0..24945ca4b 100644 --- a/sc2/src/sc2code/planets/genvux.c +++ b/sc2/src/sc2code/planets/genvux.c @@ -160,7 +160,8 @@ GenerateVUX (BYTE control) { NotifyOthers (VUX_SHIP, (BYTE)~0); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); CloneShipFragment (VUX_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); diff --git a/sc2/src/sc2code/planets/genyeh.c b/sc2/src/sc2code/planets/genyeh.c index d423036ad..b02ce8e3a 100644 --- a/sc2/src/sc2code/planets/genyeh.c +++ b/sc2/src/sc2code/planets/genyeh.c @@ -89,7 +89,8 @@ GenerateYehat (BYTE control) { NotifyOthers (YEHAT_SHIP, (BYTE)~0); PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); CloneShipFragment (YEHAT_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); diff --git a/sc2/src/sc2code/planets/genzoq.c b/sc2/src/sc2code/planets/genzoq.c index 7cc42ac27..937b668a2 100644 --- a/sc2/src/sc2code/planets/genzoq.c +++ b/sc2/src/sc2code/planets/genzoq.c @@ -22,6 +22,7 @@ #include "nameref.h" #include "resinst.h" #include "state.h" +#include "grpinfo.h" #include "planets/genall.h" #include "libs/mathlib.h" @@ -29,25 +30,22 @@ static void check_scout (void) { - HSHIPFRAG hStarShip; + HIPGROUP hGroup; if (GLOBAL (BattleGroupRef) - && (hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q)))) + && (hGroup = GetHeadLink (&GLOBAL (ip_group_q)))) { - BYTE task; - SHIP_FRAGMENT *FragPtr; + IP_GROUP *GroupPtr; - FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); - task = GET_GROUP_MISSION (FragPtr); + GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup); - if (task & REFORM_GROUP) + if (GroupPtr->task & REFORM_GROUP) { - SET_GROUP_MISSION (FragPtr, - FLEE | IGNORE_FLAGSHIP | REFORM_GROUP); - SET_GROUP_DEST (FragPtr, 0); + GroupPtr->task = FLEE | IGNORE_FLAGSHIP | REFORM_GROUP; + GroupPtr->dest_loc = 0; } - UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); + UnlockIpGroup (&GLOBAL (ip_group_q), hGroup); } } @@ -154,7 +152,8 @@ GenerateZoqFotPik (BYTE control) if (ActivateStarShip (ZOQFOTPIK_SHIP, SPHERE_TRACKING)) { PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); if (GET_GAME_STATE (ZOQFOT_DISTRESS)) { diff --git a/sc2/src/sc2code/planets/roster.c b/sc2/src/sc2code/planets/roster.c index e37986df6..96ecc7f41 100644 --- a/sc2/src/sc2code/planets/roster.c +++ b/sc2/src/sc2code/planets/roster.c @@ -107,7 +107,7 @@ DeltaSupportCrew (SIZE crew_delta) StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), (HSHIPFRAG)pMenuState->CurFrame); hTemplate = GetStarShipFromIndex (&GLOBAL (avail_race_q), - GET_RACE_ID (StarShipPtr)); + StarShipPtr->race_id); TemplatePtr = LockFleetInfo (&GLOBAL (avail_race_q), hTemplate); StarShipPtr->crew_level += crew_delta; diff --git a/sc2/src/sc2code/planets/scan.c b/sc2/src/sc2code/planets/scan.c index e7832a386..8d69ab51a 100644 --- a/sc2/src/sc2code/planets/scan.c +++ b/sc2/src/sc2code/planets/scan.c @@ -773,7 +773,8 @@ PickPlanetSide (MENU_STATE *pMS) EncounterGroup = 0; PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); - ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); + assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); hStarShip = CloneShipFragment (SPATHI_SHIP, &GLOBAL (npc_built_ship_q), 1); diff --git a/sc2/src/sc2code/planets/solarsys.c b/sc2/src/sc2code/planets/solarsys.c index 7562ced90..8e3b6db89 100644 --- a/sc2/src/sc2code/planets/solarsys.c +++ b/sc2/src/sc2code/planets/solarsys.c @@ -1460,6 +1460,7 @@ InitSolarSys (void) EncounterRace = -1; EncounterGroup = 0; GLOBAL (BattleGroupRef) = 0; + ReinitQueue (&GLOBAL (ip_group_q)); ReinitQueue (&GLOBAL (npc_built_ship_q)); (*pSolarSysState->GenFunc) (INIT_NPCS); } @@ -1590,6 +1591,7 @@ GenerateRandomIP (BYTE control) case UNINIT_NPCS: PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); ReinitQueue (&GLOBAL (npc_built_ship_q)); + ReinitQueue (&GLOBAL (ip_group_q)); break; case GENERATE_MINERAL: GenerateMineralDeposits (&pSolarSysState->SysInfo, diff --git a/sc2/src/sc2code/races.h b/sc2/src/sc2code/races.h index 76b55b83c..d1ff2d2ad 100644 --- a/sc2/src/sc2code/races.h +++ b/sc2/src/sc2code/races.h @@ -111,69 +111,28 @@ typedef struct BYTE ship_mass; } CHARACTERISTIC_STUFF; -// XXX: This struct is also used to store group info -// Groups should get an own struct typedef struct { UWORD ship_flags; - /* Also: group_counter */ - BYTE var1; - /* Also: ship_cost, race_id */ - BYTE var2; - /* Also: group loc and mission, ship's queue index, - * escort window number in built_ship_q, - * fleet strength in loaded ship descriptors */ + BYTE ship_cost; + COUNT crew_level; - /* For ships in npc_built_ship_q, the value INFINITE_FLEET for - * crew_level indicates an infinite number of ships. */ COUNT max_crew; BYTE energy_level; - /* Also: group destination and orbit loc, */ BYTE max_energy; - /* Also: group_id */ - POINT loc; STRING race_strings; FRAME icons; FRAME melee_icon; -#define INFINITE_FLEET ((COUNT) ~0) } SHIP_INFO; -// XXX: TODO: remove these -#define ship_cost var1 -#define group_counter ship_flags - -enum +typedef struct { - IN_ORBIT = 0, - EXPLORE, - FLEE, - ON_STATION, + COUNT strength; + POINT known_loc; - IGNORE_FLAGSHIP = 1 << 2, - REFORM_GROUP = 1 << 3 -}; -#define MAX_REVOLUTIONS 5 - -#define GET_RACE_ID(s) ((s)->var1) -#define SET_RACE_ID(s,v) ((s)->var1 = (v)) -#define GET_GROUP_LOC(s) LONIBBLE ((s)->var2) -#define SET_GROUP_LOC(s,v) ((s)->var2 = \ - MAKE_BYTE ((v), HINIBBLE ((s)->var2))) -#define GET_GROUP_MISSION(s) HINIBBLE ((s)->var2) -#define SET_GROUP_MISSION(s,v) ((s)->var2 = \ - MAKE_BYTE (LONIBBLE ((s)->var2), (v))) -#define GET_GROUP_DEST(s) LONIBBLE ((s)->energy_level) -#define SET_GROUP_DEST(s,v) ((s)->energy_level = \ - MAKE_BYTE ((v), HINIBBLE ((s)->energy_level))) -#define GET_ORBIT_LOC(s) HINIBBLE ((s)->energy_level) -#define SET_ORBIT_LOC(s,v) ((s)->energy_level = \ - MAKE_BYTE (LONIBBLE ((s)->energy_level), (v))) -#define GET_GROUP_ID(s) ((s)->max_energy) -#define SET_GROUP_ID(s,v) ((s)->max_energy = (v)) - -#define STATION_RADIUS 1600 -#define ORBIT_RADIUS 2400 +#define INFINITE_RADIUS ((COUNT) ~0) +} FLEET_STUFF; typedef struct { @@ -196,6 +155,7 @@ typedef void (UNINIT_FUNC) (RACE_DESC *pRaceDesc); struct race_desc { SHIP_INFO ship_info _ALIGNED_ANY; + FLEET_STUFF fleet _ALIGNED_ANY; CHARACTERISTIC_STUFF characteristics _ALIGNED_ANY; DATA_STUFF ship_data _ALIGNED_ANY; INTEL_STUFF cyborg_control _ALIGNED_ANY; @@ -282,38 +242,23 @@ typedef struct COUNT which_side; BYTE captains_name_index; -#if 0 - // XXX: new fields to replace var1 and var2 - // var1: BYTE race_id; - BYTE ship_cost; - // var2: datatypes? - BYTE fleet_strength; BYTE index; -#endif - - UWORD ship_flags; - /* Also: group_counter */ - BYTE var1; - /* Also: ship_cost, race_id */ - BYTE var2; - /* Also: group loc and mission, ship's queue index, - * escort window number in built_ship_q, - * fleet strength in loaded ship descriptors */ COUNT crew_level; /* For ships in npc_built_ship_q, the value INFINITE_FLEET for * crew_level indicates an infinite number of ships. */ COUNT max_crew; + BYTE energy_level; - /* Also: group destination and orbit loc, */ BYTE max_energy; - /* Also: group_id */ - POINT loc; + // XXX: energy_level and max_energy are unused. We save and load + // them, but otherwise nothing needs them atm. STRING race_strings; FRAME icons; - FRAME melee_icon; + FRAME melee_icon; /* Only used by Shipyard */ +#define INFINITE_FLEET ((COUNT) ~0) } SHIP_FRAGMENT; static inline SHIP_FRAGMENT * @@ -337,16 +282,14 @@ typedef struct DWORD RaceResIndex; - UWORD ship_flags; - BYTE days_left; - /* Days left before the fleet reachers 'dest_loc'. */ + UWORD ship_flags; /* 0, GOOD_GUY, or BAD_GUY */ + BYTE days_left; /* Days left before the fleet reachers 'dest_loc'. */ BYTE growth_fract; COUNT crew_level; COUNT max_crew; - BYTE energy_level; + BYTE growth; BYTE max_energy; - POINT loc; - /* Location of the fleet (center) */ + POINT loc; /* Location of the fleet (center) */ STRING race_strings; /* Race specific strings, see doc/devel/racestrings. */ diff --git a/sc2/src/sc2code/save.c b/sc2/src/sc2code/save.c index dfd0269f0..53b78d8ea 100644 --- a/sc2/src/sc2code/save.c +++ b/sc2/src/sc2code/save.c @@ -32,6 +32,7 @@ #include "shipcont.h" #include "setup.h" #include "state.h" +#include "grpinfo.h" #include "util.h" #include "libs/inplib.h" #include "libs/log.h" @@ -138,7 +139,7 @@ SaveShipQueue (DECODE_REF fh, QUEUE *pQueue) FragPtr = LockShipFrag (pQueue, hStarShip); hNextShip = _GetSuccLink (FragPtr); - Index = GET_RACE_ID (FragPtr); + Index = FragPtr->race_id; // Write the number identifying this ship type. // See races.h; look for the enum containing NUM_AVAILABLE_RACES. cwrite_16 (fh, Index); @@ -147,16 +148,16 @@ SaveShipQueue (DECODE_REF fh, QUEUE *pQueue) cwrite_16 (fh, FragPtr->which_side); cwrite_8 (fh, FragPtr->captains_name_index); cwrite_8 (fh, 0); /* padding */ - cwrite_16 (fh, FragPtr->ship_flags); - cwrite_8 (fh, FragPtr->var1); - cwrite_8 (fh, FragPtr->var2); + cwrite_16 (fh, 0); /* unused: was ship_flags */ + cwrite_8 (fh, FragPtr->race_id); + cwrite_8 (fh, FragPtr->index); // XXX: writing crew as BYTE to maintain savegame compatibility cwrite_8 (fh, FragPtr->crew_level); cwrite_8 (fh, FragPtr->max_crew); cwrite_8 (fh, FragPtr->energy_level); cwrite_8 (fh, FragPtr->max_energy); - cwrite_16 (fh, FragPtr->loc.x); - cwrite_16 (fh, FragPtr->loc.y); + cwrite_16 (fh, 0); /* unused; was loc.x */ + cwrite_16 (fh, 0); /* unused; was loc.y */ UnlockShipFrag (pQueue, hStarShip); hStarShip = hNextShip; @@ -193,7 +194,7 @@ SaveRaceQueue (DECODE_REF fh, QUEUE *pQueue) cwrite_8 (fh, FleetPtr->growth_fract); cwrite_8 (fh, FleetPtr->crew_level); cwrite_8 (fh, FleetPtr->max_crew); - cwrite_8 (fh, FleetPtr->energy_level); + cwrite_8 (fh, FleetPtr->growth); cwrite_8 (fh, FleetPtr->max_energy); cwrite_16 (fh, FleetPtr->loc.x); cwrite_16 (fh, FleetPtr->loc.y); @@ -213,6 +214,44 @@ SaveRaceQueue (DECODE_REF fh, QUEUE *pQueue) } } +static void +SaveGroupQueue (DECODE_REF fh, QUEUE *pQueue) +{ + HIPGROUP hGroup, hNextGroup; + + // Write the number of entries in the queue. + cwrite_16 (fh, CountLinks (pQueue)); + + for (hGroup = GetHeadLink (pQueue); hGroup; hGroup = hNextGroup) + { + IP_GROUP *GroupPtr; + + GroupPtr = LockIpGroup (pQueue, hGroup); + hNextGroup = _GetSuccLink (GroupPtr); + + cwrite_16 (fh, GroupPtr->race_id); /* unused; for old versions */ + + cwrite_16 (fh, 0); /* unused; was which_side */ + cwrite_8 (fh, 0); /* unused; was captains_name_index */ + cwrite_8 (fh, 0); /* padding; for savegame compat */ + cwrite_16 (fh, GroupPtr->group_counter); + cwrite_8 (fh, GroupPtr->race_id); + assert (GroupPtr->sys_loc < 0x10 && GroupPtr->task < 0x10); + cwrite_8 (fh, MAKE_BYTE (GroupPtr->sys_loc, GroupPtr->task)); + /* was var2 */ + cwrite_8 (fh, GroupPtr->in_system); /* was crew_level */ + cwrite_8 (fh, 0); /* unused; was max_crew */ + assert (GroupPtr->dest_loc < 0x10 && GroupPtr->orbit_pos < 0x10); + cwrite_8 (fh, MAKE_BYTE (GroupPtr->dest_loc, GroupPtr->orbit_pos)); + /* was energy_level */ + cwrite_8 (fh, GroupPtr->group_id); /* was max_energy */ + cwrite_16 (fh, GroupPtr->loc.x); + cwrite_16 (fh, GroupPtr->loc.y); + + UnlockIpGroup (pQueue, hGroup); + } +} + static void SaveEncounter (const ENCOUNTER *EncounterPtr, DECODE_REF fh) { @@ -345,6 +384,7 @@ SaveGameState (const GAME_STATE *GSPtr, DECODE_REF fh) DummySaveQueue (&GSPtr->avail_race_q, fh); DummySaveQueue (&GSPtr->npc_built_ship_q, fh); + // Not saving ip_group_q, was not there originally DummySaveQueue (&GSPtr->encounter_q, fh); DummySaveQueue (&GSPtr->built_ship_q, fh); @@ -451,7 +491,7 @@ PrepareSummary (SUMMARY_DESC *SummPtr) StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); hNextShip = _GetSuccLink (StarShipPtr); - SummPtr->ShipList[SummPtr->NumShips] = GET_RACE_ID (StarShipPtr); + SummPtr->ShipList[SummPtr->NumShips] = StarShipPtr->race_id; UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); } } @@ -645,11 +685,14 @@ RetrySave: if (!(GLOBAL (CurrentActivity) & START_INTERPLANETARY)) { if (GLOBAL (CurrentActivity) & START_ENCOUNTER) - // save npc queue SaveShipQueue (fh, &GLOBAL (npc_built_ship_q)); else if (LOBYTE (GLOBAL (CurrentActivity)) == IN_INTERPLANETARY) - // save group queue - SaveShipQueue (fh, &GLOBAL (npc_built_ship_q)); + // XXX: Technically, this queue does not need to be + // saved/loaded at all. IP groups will be reloaded + // from group state files. But the original code did, + // and so will we until we can prove we do not need to. + SaveGroupQueue (fh, &GLOBAL (ip_group_q)); + //SaveEmptyQueue (fh); else // XXX: empty queue write-out is only needed to maintain // the savegame compatibility diff --git a/sc2/src/sc2code/ships/androsyn/androsyn.c b/sc2/src/sc2code/ships/androsyn/androsyn.c index 93758baa8..b42ad8390 100644 --- a/sc2/src/sc2code/ships/androsyn/androsyn.c +++ b/sc2/src/sc2code/ships/androsyn/androsyn.c @@ -39,19 +39,22 @@ static RACE_DESC androsynth_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | SEEKING_WEAPON, 15, /* Super Melee cost */ - ~0, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - MAX_X_UNIVERSE >> 1, MAX_Y_UNIVERSE >> 1, - }, (STRING)ANDROSYNTH_RACE_STRINGS, (FRAME)ANDROSYNTH_ICON_MASK_PMAP_ANIM, (FRAME)ANDROSYNTH_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + INFINITE_RADIUS, /* Initial sphere of influence radius */ + // XXX: Why infinite radius? Bug? + { /* Known location (center of SoI) */ + MAX_X_UNIVERSE >> 1, MAX_Y_UNIVERSE >> 1, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/arilou/arilou.c b/sc2/src/sc2code/ships/arilou/arilou.c index 26e8ff4b8..8564d20f6 100644 --- a/sc2/src/sc2code/ships/arilou/arilou.c +++ b/sc2/src/sc2code/ships/arilou/arilou.c @@ -41,19 +41,21 @@ static RACE_DESC arilou_desc = { - { + { /* SHIP_INFO */ /* FIRES_FORE | */ IMMEDIATE_WEAPON, 16, /* Super Melee cost */ - 250 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 438, 6372, - }, (STRING)ARILOU_RACE_STRINGS, (FRAME)ARILOU_ICON_MASK_PMAP_ANIM, (FRAME)ARILOU_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 250 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 438, 6372, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/blackurq/blackurq.c b/sc2/src/sc2code/ships/blackurq/blackurq.c index da55903ea..836acdddf 100644 --- a/sc2/src/sc2code/ships/blackurq/blackurq.c +++ b/sc2/src/sc2code/ships/blackurq/blackurq.c @@ -43,19 +43,21 @@ static RACE_DESC black_urquan_desc = { - { + { /* SHIP_INFO */ FIRES_FORE, 30, /* Super Melee cost */ - 2666 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 6000, 6250, - }, (STRING)KOHR_AH_RACE_STRINGS, (FRAME)KOHR_AH_ICON_MASK_PMAP_ANIM, (FRAME)KOHR_AH_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 2666 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 6000, 6250, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/chenjesu/chenjesu.c b/sc2/src/sc2code/ships/chenjesu/chenjesu.c index bc20657cd..f5607b6a5 100644 --- a/sc2/src/sc2code/ships/chenjesu/chenjesu.c +++ b/sc2/src/sc2code/ships/chenjesu/chenjesu.c @@ -46,19 +46,21 @@ static RACE_DESC chenjesu_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | SEEKING_SPECIAL | SEEKING_WEAPON, 28, /* Super Melee cost */ - 0 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 0, 0, - }, (STRING)CHENJESU_RACE_STRINGS, (FRAME)CHENJESU_ICON_MASK_PMAP_ANIM, (FRAME)CHENJESU_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 0, /* Initial sphere of influence radius */ + { /* Known location (center of SoI) */ + 0, 0, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/chmmr/chmmr.c b/sc2/src/sc2code/ships/chmmr/chmmr.c index 85090b306..1e743784a 100644 --- a/sc2/src/sc2code/ships/chmmr/chmmr.c +++ b/sc2/src/sc2code/ships/chmmr/chmmr.c @@ -43,19 +43,21 @@ static RACE_DESC chmmr_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | IMMEDIATE_WEAPON | SEEKING_SPECIAL | POINT_DEFENSE, 30, /* Super Melee cost */ - 0, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 0, 0, - }, (STRING)CHMMR_RACE_STRINGS, (FRAME)CHMMR_ICON_MASK_PMAP_ANIM, (FRAME)CHMMR_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 0, /* Initial sphere of influence radius */ + { /* Known location (center of SoI) */ + 0, 0, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/druuge/druuge.c b/sc2/src/sc2code/ships/druuge/druuge.c index 34051b045..57b30898c 100644 --- a/sc2/src/sc2code/ships/druuge/druuge.c +++ b/sc2/src/sc2code/ships/druuge/druuge.c @@ -39,19 +39,21 @@ static RACE_DESC druuge_desc = { - { + { /* SHIP_INFO */ FIRES_FORE, 17, /* Super Melee cost */ - 1400 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 9500, 2792, - }, (STRING)DRUUGE_RACE_STRINGS, (FRAME)DRUUGE_ICON_MASK_PMAP_ANIM, (FRAME)DRUUGE_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 1400 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 9500, 2792, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/human/human.c b/sc2/src/sc2code/ships/human/human.c index e07cae6fe..43a1e5a38 100644 --- a/sc2/src/sc2code/ships/human/human.c +++ b/sc2/src/sc2code/ships/human/human.c @@ -43,19 +43,21 @@ static RACE_DESC human_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | SEEKING_WEAPON | POINT_DEFENSE, 11, /* Super Melee cost */ - 0 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 1752, 1450, - }, (STRING)HUMAN_RACE_STRINGS, (FRAME)HUMAN_ICON_MASK_PMAP_ANIM, (FRAME)HUMAN_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 0, /* Initial sphere of influence radius */ + { /* Known location (center of SoI) */ + 1752, 1450, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/ilwrath/ilwrath.c b/sc2/src/sc2code/ships/ilwrath/ilwrath.c index 781ca153d..ac3b2d3f4 100644 --- a/sc2/src/sc2code/ships/ilwrath/ilwrath.c +++ b/sc2/src/sc2code/ships/ilwrath/ilwrath.c @@ -41,19 +41,21 @@ static RACE_DESC ilwrath_desc = { - { + { /* SHIP_INFO */ FIRES_FORE, 10, /* Super Melee cost */ - 1410 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 48, 1700, - }, (STRING)ILWRATH_RACE_STRINGS, (FRAME)ILWRATH_ICON_MASK_PMAP_ANIM, (FRAME)ILWRATH_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 1410 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 48, 1700, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/lastbat/lastbat.c b/sc2/src/sc2code/ships/lastbat/lastbat.c index b2ba1706a..d842de691 100644 --- a/sc2/src/sc2code/ships/lastbat/lastbat.c +++ b/sc2/src/sc2code/ships/lastbat/lastbat.c @@ -46,19 +46,21 @@ static RACE_DESC samatra_desc = { - { + { /* SHIP_INFO */ /* FIRES_FORE | */ IMMEDIATE_WEAPON | CREW_IMMUNE, 16, /* Super Melee cost */ - 0, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 0, 0, - }, (STRING)0, (FRAME)0, (FRAME)0, }, + { /* FLEET_STUFF */ + 0, /* Initial sphere of influence radius */ + { /* Known location (center of SoI) */ + 0, 0, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/melnorme/melnorme.c b/sc2/src/sc2code/ships/melnorme/melnorme.c index 61f3539d3..4b85979d3 100644 --- a/sc2/src/sc2code/ships/melnorme/melnorme.c +++ b/sc2/src/sc2code/ships/melnorme/melnorme.c @@ -42,19 +42,21 @@ static RACE_DESC melnorme_desc = { - { + { /* SHIP_INFO */ FIRES_FORE, 18, /* Super Melee cost */ - ~0, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - MAX_X_UNIVERSE >> 1, MAX_Y_UNIVERSE >> 1, - }, (STRING)MELNORME_RACE_STRINGS, (FRAME)MELNORME_ICON_MASK_PMAP_ANIM, (FRAME)MELNORME_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + INFINITE_RADIUS, /* Initial sphere of influence radius */ + { /* Known location (center of SoI) */ + MAX_X_UNIVERSE >> 1, MAX_Y_UNIVERSE >> 1, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/mmrnmhrm/mmrnmhrm.c b/sc2/src/sc2code/ships/mmrnmhrm/mmrnmhrm.c index c0284f479..b516922e3 100644 --- a/sc2/src/sc2code/ships/mmrnmhrm/mmrnmhrm.c +++ b/sc2/src/sc2code/ships/mmrnmhrm/mmrnmhrm.c @@ -54,19 +54,21 @@ static CHARACTERISTIC_STUFF otherwing_desc[NUM_SIDES]; static RACE_DESC mmrnmhrm_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | IMMEDIATE_WEAPON, 19, /* Super Melee cost */ - 0 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 0, 0, - }, (STRING)MMRNMHRM_RACE_STRINGS, (FRAME)MMRNMHRM_ICON_MASK_PMAP_ANIM, (FRAME)MMRNMHRM_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 0, /* Initial sphere of influence radius */ + { /* Known location (center of SoI) */ + 0, 0, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/mycon/mycon.c b/sc2/src/sc2code/ships/mycon/mycon.c index 39712d179..0f353f774 100644 --- a/sc2/src/sc2code/ships/mycon/mycon.c +++ b/sc2/src/sc2code/ships/mycon/mycon.c @@ -42,19 +42,21 @@ static RACE_DESC mycon_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | SEEKING_WEAPON, 21, /* Super Melee cost */ - 1070 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 6392, 2200, - }, (STRING)MYCON_RACE_STRINGS, (FRAME)MYCON_ICON_MASK_PMAP_ANIM, (FRAME)MYCON_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 1070 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 6392, 2200, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/orz/orz.c b/sc2/src/sc2code/ships/orz/orz.c index 33858e915..2447dda1a 100644 --- a/sc2/src/sc2code/ships/orz/orz.c +++ b/sc2/src/sc2code/ships/orz/orz.c @@ -44,19 +44,21 @@ static RACE_DESC orz_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | SEEKING_SPECIAL, 23, /* Super Melee cost */ - 333 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 3608, 2637, - }, (STRING)ORZ_RACE_STRINGS, (FRAME)ORZ_ICON_MASK_PMAP_ANIM, (FRAME)ORZ_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 333 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 3608, 2637, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/pkunk/pkunk.c b/sc2/src/sc2code/ships/pkunk/pkunk.c index 5e1ac8a92..9268baab8 100644 --- a/sc2/src/sc2code/ships/pkunk/pkunk.c +++ b/sc2/src/sc2code/ships/pkunk/pkunk.c @@ -42,19 +42,21 @@ static RACE_DESC pkunk_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | FIRES_LEFT | FIRES_RIGHT, 20, /* Super Melee cost */ - 666 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 502, 401, - }, (STRING)PKUNK_RACE_STRINGS, (FRAME)PKUNK_ICON_MASK_PMAP_ANIM, (FRAME)PKUNK_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 666 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 502, 401, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/probe/probe.c b/sc2/src/sc2code/ships/probe/probe.c index f8d62278e..3638505cb 100644 --- a/sc2/src/sc2code/ships/probe/probe.c +++ b/sc2/src/sc2code/ships/probe/probe.c @@ -36,19 +36,21 @@ static RACE_DESC probe_desc = { - { + { /* SHIP_INFO */ 0, 0, /* Super Melee cost */ - 0, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 0, 0, - }, 0, 0, (FRAME)PROBE_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 0, /* Initial sphere of influence radius */ + { /* Known location (center of SoI) */ + 0, 0, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/shofixti/shofixti.c b/sc2/src/sc2code/ships/shofixti/shofixti.c index 4f7b406d0..3c7de31fa 100644 --- a/sc2/src/sc2code/ships/shofixti/shofixti.c +++ b/sc2/src/sc2code/ships/shofixti/shofixti.c @@ -42,19 +42,21 @@ static RACE_DESC shofixti_desc = { - { + { /* SHIP_INFO */ FIRES_FORE, 5, /* Super Melee cost */ - 0 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 0, 0, - }, (STRING)SHOFIXTI_RACE_STRINGS, (FRAME)SHOFIXTI_ICON_MASK_PMAP_ANIM, (FRAME)SHOFIXTI_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 0, /* Initial sphere of influence radius */ + { /* Known location (center of SoI) */ + 0, 0, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/sis_ship/sis_ship.c b/sc2/src/sc2code/ships/sis_ship/sis_ship.c index 068487032..886906c54 100644 --- a/sc2/src/sc2code/ships/sis_ship/sis_ship.c +++ b/sc2/src/sc2code/ships/sis_ship/sis_ship.c @@ -48,19 +48,21 @@ static RACE_DESC sis_desc = { - { + { /* SHIP_INFO */ 0, 16, /* Super Melee cost */ - 0 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 0, 0, - }, 0, (FRAME)SIS_ICON_MASK_PMAP_ANIM, 0, }, + { /* FLEET_STUFF */ + 0, /* Initial sphere of influence radius */ + { /* Known location (center of SoI) */ + 0, 0, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/slylandr/slylandr.c b/sc2/src/sc2code/ships/slylandr/slylandr.c index 2c71a8d32..510bfd380 100644 --- a/sc2/src/sc2code/ships/slylandr/slylandr.c +++ b/sc2/src/sc2code/ships/slylandr/slylandr.c @@ -41,19 +41,21 @@ static RACE_DESC slylandro_desc = { - { + { /* SHIP_INFO */ SEEKING_WEAPON | CREW_IMMUNE, 17, /* Super Melee cost */ - ~0, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 333, 9812, - }, (STRING)SLYLANDRO_RACE_STRINGS, (FRAME)SLYLANDRO_ICON_MASK_PMAP_ANIM, (FRAME)SLYLANDRO_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + INFINITE_RADIUS, /* Initial sphere of influence radius */ + { /* Known location (center of SoI) */ + 333, 9812, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/spathi/spathi.c b/sc2/src/sc2code/ships/spathi/spathi.c index bb4a0aaad..2c3a6ac40 100644 --- a/sc2/src/sc2code/ships/spathi/spathi.c +++ b/sc2/src/sc2code/ships/spathi/spathi.c @@ -39,19 +39,21 @@ static RACE_DESC spathi_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | FIRES_AFT | SEEKING_SPECIAL | DONT_CHASE, 18, /* Super Melee cost */ - 1000 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 2549, 3600, - }, (STRING)SPATHI_RACE_STRINGS, (FRAME)SPATHI_ICON_MASK_PMAP_ANIM, (FRAME)SPATHI_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 1000 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 2549, 3600, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/supox/supox.c b/sc2/src/sc2code/ships/supox/supox.c index 87ae839fe..d149161f9 100644 --- a/sc2/src/sc2code/ships/supox/supox.c +++ b/sc2/src/sc2code/ships/supox/supox.c @@ -41,19 +41,21 @@ static RACE_DESC supox_desc = { - { + { /* SHIP_INFO */ FIRES_FORE, 16, /* Super Melee cost */ - 333 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 7468, 9246, - }, (STRING)SUPOX_RACE_STRINGS, (FRAME)SUPOX_ICON_MASK_PMAP_ANIM, (FRAME)SUPOX_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 333 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 7468, 9246, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/syreen/syreen.c b/sc2/src/sc2code/ships/syreen/syreen.c index 2618a6366..50c3027c8 100644 --- a/sc2/src/sc2code/ships/syreen/syreen.c +++ b/sc2/src/sc2code/ships/syreen/syreen.c @@ -42,19 +42,21 @@ static RACE_DESC syreen_desc = { - { + { /* SHIP_INFO */ FIRES_FORE, 13, /* Super Melee cost */ - 0 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, SYREEN_MAX_CREW_SIZE, MAX_ENERGY, MAX_ENERGY, - { - 0, 0, - }, (STRING)SYREEN_RACE_STRINGS, (FRAME)SYREEN_ICON_MASK_PMAP_ANIM, (FRAME)SYREEN_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 0, /* Initial sphere of influence radius */ + { /* Known location (center of SoI) */ + 0, 0, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/thradd/thradd.c b/sc2/src/sc2code/ships/thradd/thradd.c index 3c1355e3f..7793d9f13 100644 --- a/sc2/src/sc2code/ships/thradd/thradd.c +++ b/sc2/src/sc2code/ships/thradd/thradd.c @@ -42,19 +42,21 @@ static RACE_DESC thraddash_desc = { - { + { /* SHIP_INFO */ FIRES_FORE, 10, /* Super Melee cost */ - 833 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 2535, 8358, - }, (STRING)THRADDASH_RACE_STRINGS, (FRAME)THRADDASH_ICON_MASK_PMAP_ANIM, (FRAME)THRADDASH_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 833 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 2535, 8358, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/umgah/umgah.c b/sc2/src/sc2code/ships/umgah/umgah.c index 80c89a98e..7237a78db 100644 --- a/sc2/src/sc2code/ships/umgah/umgah.c +++ b/sc2/src/sc2code/ships/umgah/umgah.c @@ -41,19 +41,21 @@ static FRAME LastShipFrame[2]; static RACE_DESC umgah_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | IMMEDIATE_WEAPON, 7, /* Super Melee cost */ - 833 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 1798, 6000, - }, (STRING)UMGAH_RACE_STRINGS, (FRAME)UMGAH_ICON_MASK_PMAP_ANIM, (FRAME)UMGAH_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 833 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 1798, 6000, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/urquan/urquan.c b/sc2/src/sc2code/ships/urquan/urquan.c index ad8cedc09..b01a12cbf 100644 --- a/sc2/src/sc2code/ships/urquan/urquan.c +++ b/sc2/src/sc2code/ships/urquan/urquan.c @@ -43,19 +43,21 @@ static RACE_DESC urquan_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | SEEKING_SPECIAL, 30, /* Super Melee cost */ - 2666 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 5750, 6000, - }, (STRING)URQUAN_RACE_STRINGS, (FRAME)URQUAN_ICON_MASK_PMAP_ANIM, (FRAME)URQUAN_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 2666 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 5750, 6000, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/utwig/utwig.c b/sc2/src/sc2code/ships/utwig/utwig.c index 2fd918cd0..43deeb9cd 100644 --- a/sc2/src/sc2code/ships/utwig/utwig.c +++ b/sc2/src/sc2code/ships/utwig/utwig.c @@ -43,19 +43,21 @@ static RACE_DESC utwig_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | POINT_DEFENSE | SHIELD_DEFENSE, 22, /* Super Melee cost */ - 666 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY >> 1, MAX_ENERGY, - { - 8534, 8797, - }, (STRING)UTWIG_RACE_STRINGS, (FRAME)UTWIG_ICON_MASK_PMAP_ANIM, (FRAME)UTWIG_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 666 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 8534, 8797, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/vux/vux.c b/sc2/src/sc2code/ships/vux/vux.c index 51679542b..b4c592e32 100644 --- a/sc2/src/sc2code/ships/vux/vux.c +++ b/sc2/src/sc2code/ships/vux/vux.c @@ -44,19 +44,21 @@ static RACE_DESC vux_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | SEEKING_SPECIAL | IMMEDIATE_WEAPON, 12, /* Super Melee cost */ - 900 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 4412, 1558, - }, (STRING)VUX_RACE_STRINGS, (FRAME)VUX_ICON_MASK_PMAP_ANIM, (FRAME)VUX_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 900 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 4412, 1558, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/yehat/yehat.c b/sc2/src/sc2code/ships/yehat/yehat.c index d2e165d03..e103bdfe1 100644 --- a/sc2/src/sc2code/ships/yehat/yehat.c +++ b/sc2/src/sc2code/ships/yehat/yehat.c @@ -41,19 +41,21 @@ static RACE_DESC yehat_desc = { - { + { /* SHIP_INFO */ FIRES_FORE | SHIELD_DEFENSE, 23, /* Super Melee cost */ - 750 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 4970, 40, - }, (STRING)YEHAT_RACE_STRINGS, (FRAME)YEHAT_ICON_MASK_PMAP_ANIM, (FRAME)YEHAT_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 750 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 4970, 40, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/ships/zoqfot/zoqfot.c b/sc2/src/sc2code/ships/zoqfot/zoqfot.c index f55c30374..d02f90db7 100644 --- a/sc2/src/sc2code/ships/zoqfot/zoqfot.c +++ b/sc2/src/sc2code/ships/zoqfot/zoqfot.c @@ -42,19 +42,21 @@ static RACE_DESC zoqfotpik_desc = { - { + { /* SHIP_INFO */ FIRES_FORE, 6, /* Super Melee cost */ - 320 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */ MAX_CREW, MAX_CREW, MAX_ENERGY, MAX_ENERGY, - { - 3761, 5333, - }, (STRING)ZOQFOTPIK_RACE_STRINGS, (FRAME)ZOQFOTPIK_ICON_MASK_PMAP_ANIM, (FRAME)ZOQFOTPIK_MICON_MASK_PMAP_ANIM, }, + { /* FLEET_STUFF */ + 320 / SPHERE_RADIUS_INCREMENT * 2, /* Initial SoI radius */ + { /* Known location (center of SoI) */ + 3761, 5333, + }, + }, { MAX_THRUST, THRUST_INCREMENT, diff --git a/sc2/src/sc2code/shipyard.c b/sc2/src/sc2code/shipyard.c index 15f48c117..f7bc2edcf 100644 --- a/sc2/src/sc2code/shipyard.c +++ b/sc2/src/sc2code/shipyard.c @@ -275,7 +275,7 @@ ShowShipCrew (SHIP_FRAGMENT *StarShipPtr, RECT *pRect) FLEET_INFO *TemplatePtr; hTemplate = GetStarShipFromIndex (&GLOBAL (avail_race_q), - GET_RACE_ID (StarShipPtr)); + StarShipPtr->race_id); TemplatePtr = LockFleetInfo (&GLOBAL (avail_race_q), hTemplate); if (StarShipPtr->crew_level >= TemplatePtr->crew_level) sprintf (buf, "%u", StarShipPtr->crew_level); @@ -363,7 +363,7 @@ ShowCombatShip (COUNT which_window, SHIP_FRAGMENT *YankedStarShipPtr) while (hStarShip) { StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); - if (StarShipPtr->var2 > which_window) + if (StarShipPtr->index > which_window) { UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); break; @@ -377,7 +377,7 @@ ShowCombatShip (COUNT which_window, SHIP_FRAGMENT *YankedStarShipPtr) hStarShip = hTailShip; StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); - StarShipPtr->var2 = which_window; + StarShipPtr->index = which_window; UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); } @@ -401,7 +401,7 @@ ShowCombatShip (COUNT which_window, SHIP_FRAGMENT *YankedStarShipPtr) pship_win_info->ship_s.origin.y = (SHIP_WIN_WIDTH >> 1); pship_win_info->ship_s.frame = StarShipPtr->melee_icon; - which_window = GET_GROUP_LOC (StarShipPtr); + which_window = StarShipPtr->index; pship_win_info->finished_s.x = hangar_x_coords[ which_window % HANGAR_SHIPS_ROW]; pship_win_info->finished_s.y = HANGAR_Y + (HANGAR_DY * @@ -643,7 +643,7 @@ DoModifyShips (MENU_STATE *pMS) { StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip); - if (StarShipPtr->var2 == pMS->CurState) + if (StarShipPtr->index == pMS->CurState) { UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); break; @@ -688,9 +688,8 @@ DoModifyShips (MENU_STATE *pMS) { /* Get fleet info from selected escort */ SHIP_FRAGMENT *FragPtr = LockShipFrag ( &GLOBAL (built_ship_q), hStarShip); - BYTE Index = GET_RACE_ID (FragPtr); hSpinShip = GetStarShipFromIndex ( - &GLOBAL (avail_race_q), Index); + &GLOBAL (avail_race_q), FragPtr->race_id); UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip); } @@ -923,7 +922,7 @@ DoModifyShips (MENU_STATE *pMS) hTemplate = GetStarShipFromIndex ( &GLOBAL (avail_race_q), - GET_RACE_ID (StarShipPtr)); + StarShipPtr->race_id); TemplatePtr = LockFleetInfo ( &GLOBAL (avail_race_q), hTemplate); if (GLOBAL_SIS (ResUnits) >= @@ -937,7 +936,7 @@ DoModifyShips (MENU_STATE *pMS) DeltaSISGauges (0, 0, -GLOBAL (CrewCost)); else DeltaSISGauges (0, 0, -(COUNT)ShipCost[ - GET_RACE_ID (StarShipPtr) ]); + StarShipPtr->race_id]); ++StarShipPtr->crew_level; crew_delta = 1; ShowShipCrew (StarShipPtr, &pMS->flash_rect0); @@ -995,7 +994,7 @@ DoModifyShips (MENU_STATE *pMS) CREW_EXPENSE_THRESHOLD ? 2 : 0)); else DeltaSISGauges (0, 0, (COUNT)ShipCost[ - GET_RACE_ID (StarShipPtr)]); + StarShipPtr->race_id]); crew_delta = -1; --StarShipPtr->crew_level; } diff --git a/sc2/src/sc2code/sis.h b/sc2/src/sc2code/sis.h index 614ccd01b..1400ce855 100644 --- a/sc2/src/sc2code/sis.h +++ b/sc2/src/sc2code/sis.h @@ -109,8 +109,10 @@ enum #define FUEL_RESERVE FUEL_VOLUME_PER_ROW #define MAX_COMBAT_SHIPS 12 -// XXX: Only half of this number if actually used -#define MAX_BATTLE_GROUPS 64 +#define MAX_BATTLE_GROUPS 32 + +// XXX: Needed to maintain savegame compatibility +#define NUM_SAVED_BATTLE_GROUPS 64 #define IP_SHIP_THRUST_INCREMENT 8 #define IP_SHIP_TURN_WAIT 17 diff --git a/sc2/src/sc2code/starbase.c b/sc2/src/sc2code/starbase.c index 95d76e59e..a279448b9 100644 --- a/sc2/src/sc2code/starbase.c +++ b/sc2/src/sc2code/starbase.c @@ -481,12 +481,14 @@ VisitStarBase (void) || (GLOBAL (CurrentActivity) & CHECK_ABORT)) goto ExitStarBase; + /* Create an Ilwrath ship responding to the Ur-Quan + * probe's broadcast */ hStarShip = CloneShipFragment (ILWRATH_SHIP, &GLOBAL (npc_built_ship_q), 7); FragPtr = LockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); /* Hack (sort of): Suppress the tally and salvage info * after the battle */ - SET_RACE_ID (FragPtr, (BYTE)~0); + FragPtr->race_id = (BYTE)~0; UnlockShipFrag (&GLOBAL (npc_built_ship_q), hStarShip); InitCommunication (ILWRATH_CONVERSATION); diff --git a/sc2/src/sc2code/uqmdebug.c b/sc2/src/sc2code/uqmdebug.c index fed1da3eb..fa7d1dedc 100644 --- a/sc2/src/sc2code/uqmdebug.c +++ b/sc2/src/sc2code/uqmdebug.c @@ -406,7 +406,7 @@ showSpheres (void) FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hStarShip); hNextShip = _GetSuccLink (FleetPtr); - if ((FleetPtr->actual_strength != (COUNT) ~0) && + if ((FleetPtr->actual_strength != INFINITE_RADIUS) && (FleetPtr->known_strength != FleetPtr->actual_strength)) { FleetPtr->known_strength = FleetPtr->actual_strength;