diff --git a/GameSettings.cpp b/GameSettings.cpp index 3df94a18..8f08d9fe 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1458,6 +1458,9 @@ void LoadGameExternalOptions() // Neutral civilians can detect and avoid player's mines gGameExternalOptions.bNeutralCiviliansAvoidPlayerMines = iniReader.ReadBoolean("Tactical Interface Settings","CIVILIANS_AVOID_PLAYER_MINES",FALSE); + // can extra civilians be created via LUA? + gGameExternalOptions.bExtraCivilians = iniReader.ReadBoolean( "Tactical Interface Settings", "ALLOW_EXTRA_CIVILIANS", FALSE ); + // Add smoke after regular explosions gGameExternalOptions.bAddSmokeAfterExplosion = iniReader.ReadBoolean("Tactical Interface Settings","ADD_SMOKE_AFTER_EXPLOSION",FALSE); diff --git a/GameSettings.h b/GameSettings.h index 15c20337..1257d239 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -798,6 +798,7 @@ typedef struct BOOLEAN bAllowWearSuppressor; BOOLEAN bLazyCivilians; BOOLEAN bNeutralCiviliansAvoidPlayerMines; //sevenfm: Neutral civilians can detect mines with MAPELEMENT_PLAYER_MINE_PRESENT flag set + BOOLEAN bExtraCivilians; // Flugente: add civilians via LUA BOOLEAN bAddSmokeAfterExplosion; BOOLEAN bAllowExplosiveAttachments; BOOLEAN bAllowSpecialExplosiveAttachments; diff --git a/Laptop/IMP Color Choosing.cpp b/Laptop/IMP Color Choosing.cpp index 6534047e..1dd6cafa 100644 --- a/Laptop/IMP Color Choosing.cpp +++ b/Laptop/IMP Color Choosing.cpp @@ -21,55 +21,11 @@ #include "WCheck.h" #include "Animation Data.h" #include "GameSettings.h" + #include "Soldier Create.h" // added by Flugente for enums #endif #include "IMP Confirm.h" -enum -{ - PINKSKIN, - TANSKIN, - DARKSKIN, - BLACKSKIN, - NUMSKINS -}; -enum -{ - BROWNHEAD, - BLACKHEAD, - WHITEHEAD, - BLONDHEAD, - REDHEAD, - NUMHEADS -}; - -enum -{ - WHITEVEST, - GYELLOWSHIRT, - YELLOWVEST, - GREYVEST, - BROWNVEST, - PURPLESHIRT, - BLUEVEST, - JEANVEST, - GREENVEST, - REDVEST, - BLACKSHIRT, - NUMSHIRTS -}; - -enum -{ - BLUEPANTS, - BLACKPANTS, - JEANPANTS, - TANPANTS, - BEIGEPANTS, - GREENPANTS, - NUMPANTS -}; - // Skin colors /*STR16 sSkinTexts[]={ L"Pink Skin", diff --git a/Strategic/LuaInitNPCs.cpp b/Strategic/LuaInitNPCs.cpp index 9e824e2f..d7896eff 100644 --- a/Strategic/LuaInitNPCs.cpp +++ b/Strategic/LuaInitNPCs.cpp @@ -845,6 +845,7 @@ static int l_ResetBoxers( lua_State *L ); static int l_AddVolunteers( lua_State *L ); static int l_CreateArmedCivilain( lua_State *L ); +static int l_CreateCivilian( lua_State *L ); static int l_BuildFortification( lua_State *L ); static int l_RemoveFortification( lua_State *L ); @@ -1706,6 +1707,7 @@ void IniFunction(lua_State *L, BOOLEAN bQuests ) lua_register( L, "AddVolunteers", l_AddVolunteers ); lua_register(L, "CreateArmedCivilain", l_CreateArmedCivilain ); + lua_register( L, "CreateCivilian", l_CreateCivilian ); lua_register( L, "BuildFortification", l_BuildFortification ); lua_register( L, "RemoveFortification", l_RemoveFortification ); @@ -2653,7 +2655,7 @@ void LuaRecruitRPCAdditionalHandling( UINT8 usProfile ) LuaFunction( _LS.L, "RecruitRPCAdditionalHandling" ).Param( usProfile ).Call( 1 ); } -void LuaHandleSectorTacticalEntry( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ) +void LuaHandleSectorTacticalEntry( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, BOOLEAN fHasEverBeenPlayerControlled ) { const char* filename = "scripts\\strategicmap.lua"; @@ -2665,12 +2667,13 @@ void LuaHandleSectorTacticalEntry( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ lua_register( _LS.L( ), "SECTOR", l_SECTOR ); lua_register( _LS.L( ), "GetFact", l_GetFact ); lua_register( _LS.L( ), "SetFact", l_SetFact ); + lua_register( _LS.L( ), "CreateCivilian", l_CreateCivilian ); IniFunction( _LS.L( ), TRUE ); IniGlobalGameSetting( _LS.L( ) ); SGP_THROW_IFFALSE( _LS.L.EvalFile( filename ), _BS( "Cannot open file: " ) << filename << _BS::cget ); - LuaFunction( _LS.L, "HandleSectorTacticalEntry" ).Param( sSectorX ).Param( sSectorY ).Param( bSectorZ ).Call( 3 ); + LuaFunction( _LS.L, "HandleSectorTacticalEntry" ).Param( sSectorX ).Param( sSectorY ).Param( bSectorZ ).Param( fHasEverBeenPlayerControlled ).Call( 4 ); } BOOLEAN LetLuaGameInit(UINT8 Init) @@ -13038,7 +13041,7 @@ static int l_AddVolunteers( lua_State *L ) static int l_CreateArmedCivilain( lua_State *L ) { - if ( lua_gettop( L ) ) + if ( lua_gettop( L ) >= 4 ) { UINT8 usCivilianGroup = lua_tointeger( L, 1 ); UINT8 usSoldierClass = lua_tointeger( L, 2 ); @@ -13074,6 +13077,37 @@ static int l_CreateArmedCivilain( lua_State *L ) return 0; } +static int l_CreateCivilian( lua_State *L ) +{ + if ( lua_gettop( L ) >= 11 ) + { + INT32 sGridNo = lua_tointeger( L, 1 ); + UINT8 usCivilianGroup = lua_tointeger( L, 2 ); + INT8 sBodyType = lua_tointeger( L, 3 ); + INT8 aVest = lua_tointeger( L, 4 ); + INT8 aPants = lua_tointeger( L, 5 ); + INT8 aHair = lua_tointeger( L, 6 ); + INT8 aSkin = lua_tointeger( L, 7 ); + INT16 item1 = lua_tointeger( L, 8 ); + INT16 item2 = lua_tointeger( L, 9 ); + INT16 item3 = lua_tointeger( L, 10 ); + INT16 item4 = lua_tointeger( L, 11 ); + + if ( gGameExternalOptions.bExtraCivilians ) + { + SOLDIERTYPE* pSoldier = TacticalCreateCivilian( sGridNo, usCivilianGroup, sBodyType, aVest, aPants, aHair, aSkin, item1, item2, item3, item4 ); + + if ( pSoldier ) + { + // So we can see them! + AllTeamsLookForAll( NO_INTERRUPTS ); + } + } + } + + return 0; +} + static int l_BuildFortification( lua_State *L ) { if ( lua_gettop( L ) ) diff --git a/Strategic/LuaInitNPCs.h b/Strategic/LuaInitNPCs.h index b8461c0b..ff55b786 100644 --- a/Strategic/LuaInitNPCs.h +++ b/Strategic/LuaInitNPCs.h @@ -61,7 +61,7 @@ extern BOOLEAN LuaHandleQuestCodeOnSector( INT16 sSectorX, INT16 sSectorY, INT8 void LuaHandleSectorLiberation( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, BOOLEAN fFirstTime ); void LuaRecruitRPCAdditionalHandling( UINT8 usProfile ); -void LuaHandleSectorTacticalEntry( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ); +void LuaHandleSectorTacticalEntry( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, BOOLEAN fHasEverBeenPlayerControlled ); extern BOOLEAN LuaHandleDelayedItemsArrival( UINT32 uiReason, UINT8 Init); extern BOOLEAN LetLuaHandleNPCSystemEvent( UINT32 uiEvent, UINT8 Init); diff --git a/Tactical/Overhead Types.h b/Tactical/Overhead Types.h index bf13269e..d90a947c 100644 --- a/Tactical/Overhead Types.h +++ b/Tactical/Overhead Types.h @@ -366,13 +366,13 @@ enum VOLUNTEER_CIV_GROUP, // Flugente: civilians that the player recruited BOUNTYHUNTER_CIV_GROUP, // Flugente: hostile bounty hunters DOWNEDPILOT_CIV_GROUP, // Flugente: downed pilots - UNNAMED_CIV_GROUP_27, - UNNAMED_CIV_GROUP_28, - UNNAMED_CIV_GROUP_29, - UNNAMED_CIV_GROUP_30, - UNNAMED_CIV_GROUP_31, - UNNAMED_CIV_GROUP_32, - UNNAMED_CIV_GROUP_33, + SCIENTIST_GROUP, // Flugente: enemy civilian personnel + RADAR_TECHNICIAN_GROUP, + AIRPORT_STAFF_GROUP, + BARRACK_STAFF_GROUP, + FACTORY_GROUP, + ADMINISTRATIVE_STAFF_GROUP, + LOYAL_CIV_GROUP, // civil population deeply loyal to the queen UNNAMED_CIV_GROUP_34, UNNAMED_CIV_GROUP_35, UNNAMED_CIV_GROUP_36, diff --git a/Tactical/Soldier Create.cpp b/Tactical/Soldier Create.cpp index 52cd05ee..f9e810b3 100644 --- a/Tactical/Soldier Create.cpp +++ b/Tactical/Soldier Create.cpp @@ -1343,7 +1343,7 @@ BOOLEAN TacticalCopySoldierFromProfile( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STR { pSoldier->usSoldierFlagMask |= (SOLDIER_COVERT_SOLDIER|SOLDIER_COVERT_NPC_SPECIAL|SOLDIER_NEW_VEST|SOLDIER_NEW_PANTS); - SetClothes( pSoldier, Random( 11 ), Random( 6 ) ); + SetClothes( pSoldier, Random( NUMSHIRTS ), Random( NUMPANTS ) ); } return( TRUE ); @@ -1445,41 +1445,67 @@ INT32 ChooseHairColor( UINT8 usBodyType, INT32 skin ) } // Flugente: set palettes for vest/shirt -void SetClothes( SOLDIERTYPE* pSoldier, INT8 aVest, INT8 aPants ) +void SetClothes( SOLDIERTYPE* pSoldier, INT8 aVest, INT8 aPants, INT8 aHair, INT8 aSkin ) { if ( !pSoldier ) return; - + // Vest - if ( aVest >= 0 && aVest < 11 ) + if ( aVest >= 0 && aVest < NUMSHIRTS ) { switch ( aVest ) { - case 0: SET_PALETTEREP_ID( pSoldier->VestPal, "BROWNVEST" ); break; - case 1: SET_PALETTEREP_ID( pSoldier->VestPal, "greyVEST" ); break; - case 2: SET_PALETTEREP_ID( pSoldier->VestPal, "GREENVEST" ); break; - case 3: SET_PALETTEREP_ID( pSoldier->VestPal, "JEANVEST" ); break; - case 4: SET_PALETTEREP_ID( pSoldier->VestPal, "REDVEST" ); break; - case 5: SET_PALETTEREP_ID( pSoldier->VestPal, "BLUEVEST" ); break; - case 6: SET_PALETTEREP_ID( pSoldier->VestPal, "YELLOWVEST" ); break; - case 7: SET_PALETTEREP_ID( pSoldier->VestPal, "WHITEVEST" ); break; - case 8: SET_PALETTEREP_ID( pSoldier->VestPal, "BLACKSHIRT" ); break; - case 9: SET_PALETTEREP_ID( pSoldier->VestPal, "GYELLOWSHIRT" ); break; - default: SET_PALETTEREP_ID( pSoldier->VestPal, "PURPLESHIRT" ); break; + case WHITEVEST: SET_PALETTEREP_ID( pSoldier->VestPal, "WHITEVEST" ); break; + case GYELLOWSHIRT: SET_PALETTEREP_ID( pSoldier->VestPal, "GYELLOWSHIRT" ); break; + case YELLOWVEST: SET_PALETTEREP_ID( pSoldier->VestPal, "YELLOWVEST" ); break; + case GREYVEST: SET_PALETTEREP_ID( pSoldier->VestPal, "greyVEST" ); break; + case BROWNVEST: SET_PALETTEREP_ID( pSoldier->VestPal, "BROWNVEST" ); break; + case PURPLESHIRT: SET_PALETTEREP_ID( pSoldier->VestPal, "PURPLESHIRT" ); break; + case BLUEVEST: SET_PALETTEREP_ID( pSoldier->VestPal, "BLUEVEST" ); break; + case JEANVEST: SET_PALETTEREP_ID( pSoldier->VestPal, "JEANVEST" ); break; + case GREENVEST: SET_PALETTEREP_ID( pSoldier->VestPal, "GREENVEST" ); break; + case REDVEST: SET_PALETTEREP_ID( pSoldier->VestPal, "REDVEST" ); break; + case BLACKSHIRT: SET_PALETTEREP_ID( pSoldier->VestPal, "BLACKSHIRT" ); break; + } } // Pants - if ( aPants >= 0 && aPants < 6 ) + if ( aPants >= 0 && aPants < NUMPANTS ) { switch ( aPants ) { - case 0: SET_PALETTEREP_ID( pSoldier->PantsPal, "GREENPANTS" ); break; - case 1: SET_PALETTEREP_ID( pSoldier->PantsPal, "JEANPANTS" ); break; - case 2: SET_PALETTEREP_ID( pSoldier->PantsPal, "TANPANTS" ); break; - case 3: SET_PALETTEREP_ID( pSoldier->PantsPal, "BLACKPANTS" ); break; - case 4: SET_PALETTEREP_ID( pSoldier->PantsPal, "BLUEPANTS" ); break; - default: SET_PALETTEREP_ID( pSoldier->PantsPal, "BEIGEPANTS" ); break; + case BLUEPANTS: SET_PALETTEREP_ID( pSoldier->PantsPal, "BLUEPANTS" ); break; + case BLACKPANTS: SET_PALETTEREP_ID( pSoldier->PantsPal, "BLACKPANTS" ); break; + case JEANPANTS: SET_PALETTEREP_ID( pSoldier->PantsPal, "JEANPANTS" ); break; + case TANPANTS: SET_PALETTEREP_ID( pSoldier->PantsPal, "TANPANTS" ); break; + case BEIGEPANTS: SET_PALETTEREP_ID( pSoldier->PantsPal, "BEIGEPANTS" ); break; + case GREENPANTS: SET_PALETTEREP_ID( pSoldier->PantsPal, "GREENPANTS" ); break; + } + } + + // Hair + if ( aHair >= 0 && aHair < NUMHEADS ) + { + switch ( aHair ) + { + case BROWNHEAD: SET_PALETTEREP_ID( pSoldier->HeadPal, "BROWNHEAD" ); break; + case BLACKHEAD: SET_PALETTEREP_ID( pSoldier->HeadPal, "BLACKHEAD" ); break; + case WHITEHEAD: SET_PALETTEREP_ID( pSoldier->HeadPal, "WHITEHEAD" ); break; + case BLONDEHEAD:SET_PALETTEREP_ID( pSoldier->HeadPal, "BLONDHEAD" ); break; + case REDHEAD: SET_PALETTEREP_ID( pSoldier->HeadPal, "REDHEAD" ); break; + } + } + + // Skin + if ( aSkin >= 0 && aSkin < NUMSKINS ) + { + switch ( aSkin ) + { + case PINKSKIN: SET_PALETTEREP_ID( pSoldier->SkinPal, "PINKSKIN" ); break; + case TANSKIN: SET_PALETTEREP_ID( pSoldier->SkinPal, "TANSKIN" ); break; + case DARKSKIN: SET_PALETTEREP_ID( pSoldier->SkinPal, "DARKSKIN" ); break; + case BLACKSKIN: SET_PALETTEREP_ID( pSoldier->SkinPal, "BLACKSKIN" ); break; } } } @@ -3335,7 +3361,7 @@ SOLDIERTYPE* TacticalCreateArmedCivilian( UINT8 usSoldierClass ) pSoldier->aiData.ubNoiseVolume = MAX_MISC_NOISE_DURATION; // random clothes - SetClothes( pSoldier, Random( 11 ), Random( 6 ) ); + SetClothes( pSoldier, Random( NUMSHIRTS ), Random( NUMPANTS ) ); pSoldier->CreateSoldierPalettes( ); } @@ -3343,6 +3369,92 @@ SOLDIERTYPE* TacticalCreateArmedCivilian( UINT8 usSoldierClass ) return(pSoldier); } +SOLDIERTYPE* TacticalCreateCivilian( INT32 sGridNo, UINT8 usCivilianGroup, INT8 sBodyType, INT8 aVest, INT8 aPants, INT8 aHair, INT8 aSkin, INT16 sItem1, INT16 sItem2, INT16 sItem3, INT16 sItem4 ) +{ + // not in autoresolve! + if ( guiCurrentScreen == AUTORESOLVE_SCREEN ) + return NULL; + + UINT8 ubID = NOBODY; + SOLDIERTYPE* pSoldier = NULL; + SOLDIERCREATE_STRUCT MercCreateStruct; + + MercCreateStruct.initialize( ); + MercCreateStruct.bTeam = CIV_TEAM; + MercCreateStruct.ubProfile = NO_PROFILE; + MercCreateStruct.sSectorX = gWorldSectorX; + MercCreateStruct.sSectorY = gWorldSectorY; + MercCreateStruct.bSectorZ = gbWorldSectorZ; + MercCreateStruct.sInsertionGridNo = sGridNo; + MercCreateStruct.ubDirection = Random( NUM_WORLD_DIRECTIONS ); + + while ( sBodyType < 0 || sBodyType >= CRIPPLECIV || (sBodyType >= ADULTFEMALEMONSTER && sBodyType <= QUEENMONSTER) ) + { + sBodyType = Random( CRIPPLECIV + 1 ); + } + + MercCreateStruct.ubBodyType = sBodyType; + + RandomizeNewSoldierStats( &MercCreateStruct ); + + if ( sItem1 >= NOTHING ) + { + CreateItems( (UINT16)(sItem1), (INT8)(80 + Random( 21 )), 1, &gTempObject ); + PlaceObjectInSoldierCreateStruct( &MercCreateStruct, &gTempObject ); + } + + if ( sItem2 >= NOTHING ) + { + CreateItems( (UINT16)(sItem2), (INT8)(80 + Random( 21 )), 1, &gTempObject ); + PlaceObjectInSoldierCreateStruct( &MercCreateStruct, &gTempObject ); + } + + if ( sItem3 >= NOTHING ) + { + CreateItems( (UINT16)(sItem3), (INT8)(80 + Random( 21 )), 1, &gTempObject ); + PlaceObjectInSoldierCreateStruct( &MercCreateStruct, &gTempObject ); + } + + if ( sItem4 >= NOTHING ) + { + CreateItems( (UINT16)(sItem4), (INT8)(80 + Random( 21 )), 1, &gTempObject ); + PlaceObjectInSoldierCreateStruct( &MercCreateStruct, &gTempObject ); + } + + pSoldier = TacticalCreateSoldier( &MercCreateStruct, &ubID ); + + if ( pSoldier ) + { + AddSoldierToSector( pSoldier->ubID ); + + // set correct civ group + pSoldier->ubCivilianGroup = usCivilianGroup; + + // make him wear administrator uniform + UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( pSoldier, pSoldier->usAnimState ); + + if ( usPaletteAnimSurface != INVALID_ANIMATION_SURFACE ) + { + SetClothes( pSoldier, aVest, aPants, aHair, aSkin ); + + // Use palette from HVOBJECT, then use substitution for pants, etc + memcpy( pSoldier->p8BPPPalette, gAnimSurfaceDatabase[usPaletteAnimSurface].hVideoObject->pPaletteEntry, sizeof(pSoldier->p8BPPPalette) * 256 ); + + SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->HeadPal ); + SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->VestPal ); + SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->PantsPal ); + SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->SkinPal ); + + pSoldier->CreateSoldierPalettes( ); + + // Dirty + fInterfacePanelDirty = DIRTYLEVEL2; + } + } + + return(pSoldier); +} + // Flugente: assassins are elite soldiers of the civ team that go hostile on a certain event, otherwise they just blend in SOLDIERTYPE* TacticalCreateEnemyAssassin(UINT8 disguisetype) { diff --git a/Tactical/Soldier Create.h b/Tactical/Soldier Create.h index 0d6522f4..c3a90eb0 100644 --- a/Tactical/Soldier Create.h +++ b/Tactical/Soldier Create.h @@ -49,6 +49,33 @@ enum NUMHEADS }; +enum +{ + WHITEVEST, + GYELLOWSHIRT, + YELLOWVEST, + GREYVEST, + BROWNVEST, + PURPLESHIRT, + BLUEVEST, + JEANVEST, + GREENVEST, + REDVEST, + BLACKSHIRT, + NUMSHIRTS +}; + +enum +{ + BLUEPANTS, + BLACKPANTS, + JEANPANTS, + TANPANTS, + BEIGEPANTS, + GREENPANTS, + NUMPANTS +}; + //Kris: SERIALIZING INFORMATION //All maps must have: // -MAPCREATE_STRUCT @@ -448,6 +475,8 @@ SOLDIERTYPE* TacticalCreateEnemyJeep( ); // Flugente: create an armed civilian SOLDIERTYPE* TacticalCreateArmedCivilian( UINT8 usSoldierClass = SOLDIER_CLASS_ARMY ); +SOLDIERTYPE* TacticalCreateCivilian( INT32 sGridNo, UINT8 usCivilianGroup, INT8 sBodyType, INT8 aVest, INT8 aPants, INT8 aHair, INT8 aSkin, INT16 sItem1, INT16 sItem2, INT16 sItem3, INT16 sItem4 ); + // Flugente: assassins are elite soldiers of the civ team that go hostile on a certain event, otherwise they just blend in SOLDIERTYPE* TacticalCreateEnemyAssassin(UINT8 disguisetype); void CreateAssassin(UINT8 disguisetype); @@ -563,6 +592,6 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre INT32 ChooseHairColor( UINT8 usBodyType, INT32 skin ); // Flugente: set palettes for vest/shirt -void SetClothes(SOLDIERTYPE* pSoldier, INT8 aVest, INT8 aPants); +void SetClothes( SOLDIERTYPE* pSoldier, INT8 aVest, INT8 aPants, INT8 aHair = -1, INT8 aSkin = -1 ); #endif \ No newline at end of file diff --git a/Tactical/Soldier Init List.cpp b/Tactical/Soldier Init List.cpp index 15d7d859..014e6168 100644 --- a/Tactical/Soldier Init List.cpp +++ b/Tactical/Soldier Init List.cpp @@ -956,7 +956,20 @@ UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum ) SectorAddDownedPilot( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); - LuaHandleSectorTacticalEntry( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + BOOLEAN sectorhaseverbeenplayercontrolled = FALSE; + if ( gbWorldSectorZ ) + { + UNDERGROUND_SECTORINFO *pSector = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + + if ( pSector && pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins > 0 ) + { + sectorhaseverbeenplayercontrolled = TRUE; + } + } + else + sectorhaseverbeenplayercontrolled = SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].fSurfaceWasEverPlayerControlled; + + LuaHandleSectorTacticalEntry( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, sectorhaseverbeenplayercontrolled ); } //There aren't any basic placements of desired team, so exit. @@ -1013,7 +1026,20 @@ UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum ) SectorAddDownedPilot( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); - LuaHandleSectorTacticalEntry( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + BOOLEAN sectorhaseverbeenplayercontrolled = FALSE; + if ( gbWorldSectorZ ) + { + UNDERGROUND_SECTORINFO *pSector = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + + if ( pSector && pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins > 0 ) + { + sectorhaseverbeenplayercontrolled = TRUE; + } + } + else + sectorhaseverbeenplayercontrolled = SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].fSurfaceWasEverPlayerControlled; + + LuaHandleSectorTacticalEntry( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, sectorhaseverbeenplayercontrolled ); } return ubNumAdded;