From eff368f0993b90cfa11e1c77f7dfda924b21ecee Mon Sep 17 00:00:00 2001 From: Flugente Date: Sat, 13 Jun 2015 17:26:16 +0000 Subject: [PATCH] - New Quest: if Kingpin is unaware Maria escaped with the player's help, he enlists the player to kill the DaSilvas - Moved civ factions for mod compatibility (UC) Does not break savegame compatibility. Requires GameDir >= r2252. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7889 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- GameVersion.cpp | 18 ++-- Laptop/email.h | 16 +++ Laptop/history.cpp | 28 +++--- Strategic/Game Event Hook.cpp | 44 ++++++++- Strategic/Game Event Hook.h | 4 + Strategic/Game Events.cpp | 4 + Strategic/LuaInitNPCs.cpp | 172 +++++++++++++++++++++++++++++---- Strategic/LuaInitNPCs.h | 1 + Strategic/Quests.cpp | 11 +++ Strategic/Quests.h | 16 ++- Tactical/Civ Quotes.cpp | 80 ++++++++------- Tactical/Overhead Types.h | 6 +- Tactical/Overhead.cpp | 50 +++++++++- Tactical/Overhead.h | 3 + Tactical/Soldier Create.cpp | 157 +++++++++++++++++------------- Tactical/Soldier Create.h | 7 ++ Tactical/Soldier Init List.cpp | 9 ++ Tactical/Soldier Init List.h | 3 + 18 files changed, 467 insertions(+), 162 deletions(-) diff --git a/GameVersion.cpp b/GameVersion.cpp index 06ab52ba..97087067 100644 --- a/GameVersion.cpp +++ b/GameVersion.cpp @@ -15,9 +15,9 @@ #ifdef JA2EDITOR #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.7887 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.7889 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.7887 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.7889 (Development Build)" }; #endif // ------------------------------ @@ -27,11 +27,11 @@ //DEBUG BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.7887 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.7889 (Development Build)" }; #elif defined (JA113DEMO) - CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.7887 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.7889 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Debug: v1.13.7887 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: v1.13.7889 (Development Build)" }; #endif #elif defined CRIPPLED_VERSION @@ -46,16 +46,16 @@ //RELEASE BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.7887 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.7889 (Development Build)" }; #elif defined (JA113DEMO) - CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.7887 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.7889 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Release v1.13.7887 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release v1.13.7889 (Development Build)" }; #endif #endif -CHAR8 czVersionNumber[16] = { "Build 15.06.04" }; //YY.MM.DD +CHAR8 czVersionNumber[16] = { "Build 15.06.13" }; //YY.MM.DD CHAR16 zTrackingNumber[16] = { L"Z" }; // SAVE_GAME_VERSION is defined in header, change it there diff --git a/Laptop/email.h b/Laptop/email.h index 03f79c1b..0d33e3e7 100644 --- a/Laptop/email.h +++ b/Laptop/email.h @@ -366,6 +366,21 @@ #define PMC_INTRO (JOHN_KULBA_MISSED_FLIGHT_3 + JOHN_KULBA_MISSED_FLIGHT_3_LENGTH) #define PMC_INTRO_LENGTH 3 + #define KINGPIN_BOUNTY_INITIAL (PMC_INTRO + PMC_INTRO_LENGTH) + #define KINGPIN_BOUNTY_INITIAL_LENGTH 6 + + #define KINGPIN_BOUNTY_KINGPIN_REWARD (KINGPIN_BOUNTY_INITIAL + KINGPIN_BOUNTY_INITIAL_LENGTH) + #define KINGPIN_BOUNTY_KINGPIN_REWARD_LENGTH 4 + + #define KINGPIN_BOUNTY_ANGEL_THANKS (KINGPIN_BOUNTY_KINGPIN_REWARD + KINGPIN_BOUNTY_KINGPIN_REWARD_LENGTH) + #define KINGPIN_BOUNTY_ANGEL_THANKS_LENGTH 4 + + #define KINGPIN_BOUNTY_BH_GOTTARGET (KINGPIN_BOUNTY_ANGEL_THANKS + KINGPIN_BOUNTY_ANGEL_THANKS_LENGTH) + #define KINGPIN_BOUNTY_BH_GOTTARGET_LENGTH 4 + + #define KINGPIN_BOUNTY_TARGET_GOTAWAY (KINGPIN_BOUNTY_BH_GOTTARGET + KINGPIN_BOUNTY_BH_GOTTARGET_LENGTH) + #define KINGPIN_BOUNTY_TARGET_GOTAWAY_LENGTH 4 + #endif // WANNE: New 1.13 MERC merc mail text for level up that Speck sends @@ -511,6 +526,7 @@ enum { MAIL_MIGUEL, #endif PMC, + ANGEL_DASILVA, }; // the length of the subject in char diff --git a/Laptop/history.cpp b/Laptop/history.cpp index 03d421e6..d47031b4 100644 --- a/Laptop/history.cpp +++ b/Laptop/history.cpp @@ -656,9 +656,9 @@ UINT32 ProcessAndEnterAHistoryRecord( UINT8 ubCode, UINT32 uiDate, UINT8 ubSecon pHistory = pHistory->Next; pHistory->Next = NULL; pHistory->ubCode = ubCode; - pHistory->ubSecondCode = ubSecondCode; + pHistory->ubSecondCode = ubSecondCode; pHistory->uiDate = uiDate; - pHistory->uiIdNumber = uiId; + pHistory->uiIdNumber = uiId; pHistory->sSectorX = sSectorX; pHistory->sSectorY = sSectorY; pHistory->bSectorZ = bSectorZ; @@ -673,10 +673,10 @@ UINT32 ProcessAndEnterAHistoryRecord( UINT8 ubCode, UINT32 uiDate, UINT8 ubSecon // setup info passed pHistory->Next = NULL; pHistory->ubCode = ubCode; - pHistory->ubSecondCode = ubSecondCode; + pHistory->ubSecondCode = ubSecondCode; pHistory->uiDate = uiDate; - pHistory->uiIdNumber = uiId; - pHistoryListHead = pHistory; + pHistory->uiIdNumber = uiId; + pHistoryListHead = pHistory; pHistory->sSectorX = sSectorX; pHistory->sSectorY = sSectorY; pHistory->bSectorZ = bSectorZ; @@ -900,7 +900,7 @@ void DrawHistoryRecordsText( void ) // loop through record list - for(iCounter; iCounter ubColor == 0 ) { @@ -910,6 +910,7 @@ void DrawHistoryRecordsText( void ) { SetFontForeground(FONT_RED); } + // get and write the date swprintf(sString, L"%d", ( pCurHistory->uiDate / ( 24 * 60 ) ) ); FindFontCenterCoordinates(RECORD_DATE_X + 5, 0, RECORD_DATE_WIDTH,0, sString, HISTORY_TEXT_FONT,&usX, &usY); @@ -920,14 +921,13 @@ void DrawHistoryRecordsText( void ) ProcessHistoryTransactionString(sString, pCurHistory); // mprintf(RECORD_DATE_X + RECORD_DATE_WIDTH + 25, RECORD_Y + ( iCounter * ( BOX_HEIGHT ) ) + 3, pHistoryStrings[pCurHistory->ubCode] ); mprintf(RECORD_DATE_X + RECORD_LOCATION_WIDTH +RECORD_DATE_WIDTH + 15, RECORD_Y + ( iCounter * ( BOX_HEIGHT ) ) + 3, sString ); - - + // no location if( ( pCurHistory->sSectorX == -1 )||( pCurHistory->sSectorY == -1 ) ) { FindFontCenterCoordinates( RECORD_DATE_X + RECORD_DATE_WIDTH, 0,RECORD_LOCATION_WIDTH + 10, 0, pHistoryLocations[0] ,HISTORY_TEXT_FONT, &sX, &sY ); - mprintf(sX, RECORD_Y + ( iCounter * ( BOX_HEIGHT ) ) + 3, pHistoryLocations[0] ); - } + mprintf(sX, RECORD_Y + ( iCounter * ( BOX_HEIGHT ) ) + 3, pHistoryLocations[0] ); + } else { GetSectorIDString( pCurHistory->sSectorX, pCurHistory->sSectorY, pCurHistory->bSectorZ, sString, TRUE ); @@ -947,17 +947,14 @@ void DrawHistoryRecordsText( void ) // last page, no Historys left, return if( ! pCurHistory ) { - // restore shadow - SetFontShadow(DEFAULT_SHADOW); + SetFontShadow(DEFAULT_SHADOW); return; } - } // restore shadow SetFontShadow(DEFAULT_SHADOW); - return; } @@ -1269,6 +1266,9 @@ void ProcessHistoryTransactionString(STR16 pString, HistoryUnitPtr pHistory) //swprintf( pString, pHistoryStrings[ pHistory->ubCode ], pHistory->ubSecondCode ); swprintf( pString, HistoryName[ pHistory->ubCode ].sHistory, pHistory->ubSecondCode ); break; + default: + swprintf( pString, L"missing text, kinda" ); + break; } } diff --git a/Strategic/Game Event Hook.cpp b/Strategic/Game Event Hook.cpp index 78677f56..1e0ffc38 100644 --- a/Strategic/Game Event Hook.cpp +++ b/Strategic/Game Event Hook.cpp @@ -46,6 +46,7 @@ #include "PostalService.h" #include "MilitiaSquads.h" #include "PMC.h" // added by Flugente + #include "finances.h" // added by Flugente #endif #include "connect.h" @@ -524,12 +525,53 @@ BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent ) case EVENT_PMC_REINFORCEMENT_ARRIVAL: HandlePMCArrival( (UINT8)pEvent->uiParam ); break; + + case EVENT_KINGPIN_BOUNTY_INITIAL: + if ( gMercProfiles[KINGPIN].bMercStatus != MERC_IS_DEAD && !CheckFact( FACT_KINGPIN_DEAD, NO_PROFILE ) && !CheckFact( FACT_KINGPIN_IS_ENEMY, NO_PROFILE ) ) + { + AddEmail( KINGPIN_BOUNTY_INITIAL, KINGPIN_BOUNTY_INITIAL_LENGTH, KING_PIN, GetWorldTotalMin( ), -1, -1, TYPE_EMAIL_EMAIL_EDT ); + } + break; + + case EVENT_KINGPIN_BOUNTY_END_KILLEDTHEM: + if ( gMercProfiles[KINGPIN].bMercStatus != MERC_IS_DEAD && !CheckFact( FACT_KINGPIN_DEAD, NO_PROFILE ) && !CheckFact( FACT_KINGPIN_IS_ENEMY, NO_PROFILE ) ) + { + AddEmail( KINGPIN_BOUNTY_KINGPIN_REWARD, KINGPIN_BOUNTY_KINGPIN_REWARD_LENGTH, KING_PIN, GetWorldTotalMin( ), -1, -1, TYPE_EMAIL_EMAIL_EDT ); + + // also authorise payment from kingpin to the player + AddTransactionToPlayersBook( ANONYMOUS_DEPOSIT, 0, GetWorldTotalMin( ), 10000 ); + } + + // in any case, this quest is now over + EndQuest( QUEST_KINGPIN_ANGEL_MARIA, gWorldSectorX, gWorldSectorY ); + + break; + + case EVENT_KINGPIN_BOUNTY_END_TIME_PASSED: + + // if we eliminated all bounty hunters and Angel & Maria are still alive, they send us an email + if ( gMercProfiles[MARIA].bMercStatus != MERC_IS_DEAD && gMercProfiles[ANGEL].bMercStatus != MERC_IS_DEAD + && CheckFact( FACT_BOUNTYHUNTER_KILLED_1, NO_PROFILE ) && CheckFact( FACT_BOUNTYHUNTER_KILLED_2, NO_PROFILE ) ) + { + AddEmail( KINGPIN_BOUNTY_ANGEL_THANKS, KINGPIN_BOUNTY_ANGEL_THANKS_LENGTH, ANGEL_DASILVA, GetWorldTotalMin( ), -1, -1, TYPE_EMAIL_EMAIL_EDT ); + + AddEmail( KINGPIN_BOUNTY_TARGET_GOTAWAY, KINGPIN_BOUNTY_TARGET_GOTAWAY_LENGTH, KING_PIN, GetWorldTotalMin( ), -1, -1, TYPE_EMAIL_EMAIL_EDT ); + } + // we can assume that the bounty hunters for to them first - Kingpin sends an email and states that someone else finished the job + else if ( gMercProfiles[KINGPIN].bMercStatus != MERC_IS_DEAD && !CheckFact( FACT_KINGPIN_DEAD, NO_PROFILE ) && !CheckFact( FACT_KINGPIN_IS_ENEMY, NO_PROFILE ) ) + { + AddEmail( KINGPIN_BOUNTY_BH_GOTTARGET, KINGPIN_BOUNTY_BH_GOTTARGET_LENGTH, KING_PIN, GetWorldTotalMin( ), -1, -1, TYPE_EMAIL_EMAIL_EDT ); + } + + // in any case, this quest is now over + EndQuest( QUEST_KINGPIN_ANGEL_MARIA, gWorldSectorX, gWorldSectorY ); + + break; } gfPreventDeletionOfAnyEvent = fOrigPreventFlag; return TRUE; } - #ifdef CRIPPLED_VERSION void CrippledVersionEndGameCheck() { diff --git a/Strategic/Game Event Hook.h b/Strategic/Game Event Hook.h index 6f098fe0..9ef0317f 100644 --- a/Strategic/Game Event Hook.h +++ b/Strategic/Game Event Hook.h @@ -116,6 +116,10 @@ enum EVENT_PMC_EMAIL, // Flugente: pmc will send us an introduction email EVENT_PMC_REINFORCEMENT_ARRIVAL, // Flugente: pmc hired militia arrives + EVENT_KINGPIN_BOUNTY_INITIAL, // Flugente: a new quest by Kingpin: kill the DaSilvas while fighting off the competition + EVENT_KINGPIN_BOUNTY_END_KILLEDTHEM, + EVENT_KINGPIN_BOUNTY_END_TIME_PASSED, + NUMBER_OF_EVENT_TYPES_PLUS_ONE, NUMBER_OF_EVENT_TYPES = NUMBER_OF_EVENT_TYPES_PLUS_ONE - 1 }; diff --git a/Strategic/Game Events.cpp b/Strategic/Game Events.cpp index e4eac830..2340310a 100644 --- a/Strategic/Game Events.cpp +++ b/Strategic/Game Events.cpp @@ -110,7 +110,11 @@ CHAR16 gEventName[NUMBER_OF_EVENT_TYPES_PLUS_ONE][40]={ L"HelicopterHoverForAMinute", L"HelicopterRefuelForAMinute", L"MilitiaMovementOrder", + L"PMCEmail", L"PMCReinforcementArrival", + L"KingpinBounty1", + L"KingpinBounty2", + L"KingpinBounty3", }; #endif diff --git a/Strategic/LuaInitNPCs.cpp b/Strategic/LuaInitNPCs.cpp index d39e3f7b..cce82ac5 100644 --- a/Strategic/LuaInitNPCs.cpp +++ b/Strategic/LuaInitNPCs.cpp @@ -735,6 +735,9 @@ static int l_GetTimeQuestWasStarted (lua_State *L); static int l_RepairmanIsFixingItemsButNoneAreDoneYet(lua_State *L); static int l_SECTOR(lua_State *L); +static int l_SECTORX( lua_State *L ); +static int l_SECTORY( lua_State *L ); + static int l_SectorInfoBloodCats(lua_State *L); static int l_SpokenToHeadMiner(lua_State *L); @@ -841,6 +844,11 @@ static int l_ResetBoxers( lua_State *L ); static int l_AddVolunteers( lua_State *L ); +static int l_CreateArmedCivilain( lua_State *L ); + +static int l_GetFact( lua_State *L ); +static int l_SetFact( lua_State *L ); + using namespace std; UINT16 idProfil; @@ -1477,6 +1485,9 @@ void IniFunction(lua_State *L, BOOLEAN bQuests ) lua_register(L, "RepairmanIsFixingItemsButNoneAreDoneYet", l_RepairmanIsFixingItemsButNoneAreDoneYet); lua_register(L, "SECTOR", l_SECTOR); + lua_register(L, "SECTORX", l_SECTORX ); + lua_register(L, "SECTORY", l_SECTORY ); + lua_register(L, "GetSectorInfoBloodCats", l_SectorInfoBloodCats); lua_register(L, "SpokenToHeadMiner", l_SpokenToHeadMiner); @@ -1690,6 +1701,11 @@ void IniFunction(lua_State *L, BOOLEAN bQuests ) lua_register(L,"EnvEndRainStorm", l_EnvEndRainStorm); lua_register( L, "AddVolunteers", l_AddVolunteers ); + + lua_register(L, "CreateArmedCivilain", l_CreateArmedCivilain ); + + lua_register(L, "GetFact", l_GetFact ); + lua_register(L, "SetFact", l_SetFact ); } #ifdef NEWMUSIC BOOLEAN LetLuaMusicControl(UINT8 Init) @@ -2578,6 +2594,7 @@ BOOLEAN LuaHandleQuestCodeOnSector( INT16 sSectorX, INT16 sSectorY, INT8 bSector lua_register(_LS.L(), "CheckForMissingHospitalSupplies", l_CheckForMissingHospitalSupplies); lua_register(_LS.L(), "CheckForKingpinsMoneyMissing", l_FunctionCheckForKingpinsMoneyMissing); lua_register(_LS.L(), "SetProfileStrategicInsertionData", l_ProfilesStrategicInsertionData ); + lua_register(_LS.L(), "CreateArmedCivilain", l_CreateArmedCivilain ); IniFunction( _LS.L(), TRUE ); IniGlobalGameSetting( _LS.L() ); @@ -2628,6 +2645,26 @@ void LuaRecruitRPCAdditionalHandling( UINT8 usProfile ) LuaFunction( _LS.L, "RecruitRPCAdditionalHandling" ).Param( usProfile ).Call( 1 ); } +void LuaHandleSectorTacticalEntry( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ) +{ + const char* filename = "scripts\\strategicmap.lua"; + + LuaScopeState _LS( true ); + + lua_register( _LS.L( ), "CheckFact", l_CheckFact ); + lua_register( _LS.L( ), "SECTORX", l_SECTORX ); + lua_register( _LS.L( ), "SECTORY", l_SECTORY ); + lua_register( _LS.L( ), "SECTOR", l_SECTOR ); + lua_register( _LS.L( ), "GetFact", l_GetFact ); + lua_register( _LS.L( ), "SetFact", l_SetFact ); + 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 ); +} + BOOLEAN LetLuaGameInit(UINT8 Init) { const char* filename = "scripts\\GameInit.lua"; @@ -2729,6 +2766,7 @@ BOOLEAN LuaInternalQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY, BOOLEAN LuaScopeState _LS(true); + lua_register( _LS.L( ), "CreateArmedCivilain", l_CreateArmedCivilain ); IniFunction( _LS.L(), FALSE ); IniGlobalGameSetting( _LS.L() ); @@ -4416,42 +4454,68 @@ UINT8 TANKS_ILOSC = 0; static int l_SECTOR(lua_State *L) { -UINT8 n = lua_gettop(L); -int i; -UINT16 x,y; -UINT8 val; + UINT8 val = 0; - for (i= 1; i<=n; i++ ) + if ( lua_gettop( L ) ) { - if (i == 1 ) x = lua_tointeger(L,i); - if (i == 2 ) y = lua_tointeger(L,i); + UINT16 x = lua_tointeger( L, 1 ); + UINT16 y = lua_tointeger( L, 2 ); + + val = SECTOR( x, y ); } - - val = SECTOR( x, y ); - + lua_pushinteger(L, val); -return 1; + return 1; +} + +static int l_SECTORX( lua_State *L ) +{ + UINT8 val = 0; + + if ( lua_gettop( L ) ) + { + UINT8 sector = lua_tointeger( L, 1 ); + + val = SECTORX( sector ); + } + + lua_pushinteger( L, val ); + + return 1; +} + +static int l_SECTORY( lua_State *L ) +{ + UINT8 val = 0; + + if ( lua_gettop( L ) ) + { + UINT8 sector = lua_tointeger( L, 1 ); + + val = SECTORY( sector ); + } + + lua_pushinteger( L, val ); + + return 1; } static int l_CALCULATE_STRATEGIC_INDEX(lua_State *L) { -UINT8 n = lua_gettop(L); -int i; -UINT16 x,y; -UINT8 val; + UINT8 val = 0; - for (i= 1; i<=n; i++ ) + if ( lua_gettop( L ) ) { - if (i == 1 ) x = lua_tointeger(L,i); - if (i == 2 ) y = lua_tointeger(L,i); + UINT16 x = lua_tointeger( L, 1 ); + UINT16 y = lua_tointeger( L, 2 ); + + val = CALCULATE_STRATEGIC_INDEX( x, y ); } - - val = CALCULATE_STRATEGIC_INDEX( x, y ); lua_pushinteger(L, val); -return 1; + return 1; } static int l_SectorInfoBloodCats(lua_State *L) @@ -12964,3 +13028,69 @@ static int l_AddVolunteers( lua_State *L ) return 0; } +static int l_CreateArmedCivilain( lua_State *L ) +{ + if ( lua_gettop( L ) ) + { + UINT8 usCivilianGroup = lua_tointeger( L, 1 ); + UINT8 usSoldierClass = lua_tointeger( L, 2 ); + INT32 sGridNo = lua_tointeger( L, 3 ); + BOOLEAN fHostile = lua_tointeger( L, 4 ); + + SOLDIERTYPE* pSoldier = TacticalCreateArmedCivilian( usSoldierClass ); + + if ( pSoldier ) + { + if ( sGridNo != NOWHERE ) + { + pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO; + pSoldier->sInsertionGridNo = sGridNo; + } + + AddSoldierToSector( pSoldier->ubID ); + + // So we can see them! + AllTeamsLookForAll( NO_INTERRUPTS ); + + // set correct civ group + if ( usCivilianGroup ) + { + pSoldier->ubCivilianGroup = usCivilianGroup; + + if ( fHostile ) + gTacticalStatus.fCivGroupHostile[pSoldier->ubCivilianGroup] = CIV_GROUP_WILL_BECOME_HOSTILE; + } + } + } + + return 0; +} + +static int l_GetFact( lua_State *L ) +{ + UINT8 val = 0; + + if ( lua_gettop( L ) ) + { + UINT16 fact = lua_tointeger( L, 1 ); + + val = GetFact( fact ); + } + + lua_pushinteger( L, val ); + + return 1; +} + +static int l_SetFact( lua_State *L ) +{ + if ( lua_gettop( L ) ) + { + UINT16 fact = lua_tointeger( L, 1 ); + UINT8 val = lua_tointeger( L, 2 ); + + SetFact( fact, val ); + } + + return 0; +} diff --git a/Strategic/LuaInitNPCs.h b/Strategic/LuaInitNPCs.h index efbb0a20..b8461c0b 100644 --- a/Strategic/LuaInitNPCs.h +++ b/Strategic/LuaInitNPCs.h @@ -61,6 +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 ); extern BOOLEAN LuaHandleDelayedItemsArrival( UINT32 uiReason, UINT8 Init); extern BOOLEAN LetLuaHandleNPCSystemEvent( UINT32 uiEvent, UINT8 Init); diff --git a/Strategic/Quests.cpp b/Strategic/Quests.cpp index c609b2e8..6afa3e7c 100644 --- a/Strategic/Quests.cpp +++ b/Strategic/Quests.cpp @@ -1366,6 +1366,17 @@ BOOLEAN CheckFact( UINT16 usFact, UINT8 ubProfileID ) return( gubFact[usFact] ); } +void SetFact( UINT16 usFact, UINT8 aVal ) +{ + if ( usFact < NUM_FACTS ) + gubFact[usFact] = aVal; +} + +UINT8 GetFact( UINT16 usFact ) +{ + return gubFact[usFact]; +} + void StartQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY ) { InternalStartQuest( ubQuest, sSectorX, sSectorY, TRUE ); diff --git a/Strategic/Quests.h b/Strategic/Quests.h index 006d334b..b7ed442f 100644 --- a/Strategic/Quests.h +++ b/Strategic/Quests.h @@ -78,6 +78,8 @@ enum Quests QUEST_23 = 23, QUEST_24 = 24, QUEST_KILL_DEIDRANNA = 25, + + QUEST_KINGPIN_ANGEL_MARIA, // Flugente: new quest: if the palyer rescued Maria without implicating himself, Kingpin hires bounty hunters to kill them #endif } ; /* @@ -559,6 +561,11 @@ enum Facts FACT_DISEASE_WHODATA_SUBSCRIBED, // if we are currently subscripted, we will pay x$ per day FACT_DISEASE_WHODATA_ACCESS, // do we currently have access to the data + // Flugente: Kingpin bounty hunter quest + FACT_BOUNTYHUNTER_SECTOR_1, + FACT_BOUNTYHUNTER_SECTOR_2, + FACT_BOUNTYHUNTER_KILLED_1, + FACT_BOUNTYHUNTER_KILLED_2, #ifdef JA2UB //Ja25 UB @@ -617,9 +624,12 @@ enum Facts extern UINT8 gubQuest[MAX_QUESTS]; extern UINT8 gubFact[NUM_FACTS]; -extern void SetFactTrue( UINT16 usFact ); -extern void SetFactFalse( UINT16 usFact ); -extern BOOLEAN CheckFact( UINT16 usFact, UINT8 ubProfileID ); +void SetFactTrue( UINT16 usFact ); +void SetFactFalse( UINT16 usFact ); +BOOLEAN CheckFact( UINT16 usFact, UINT8 ubProfileID ); + +void SetFact( UINT16 usFact, UINT8 aVal ); +UINT8 GetFact( UINT16 usFact ); extern void StartQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY ); extern void EndQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY ); diff --git a/Tactical/Civ Quotes.cpp b/Tactical/Civ Quotes.cpp index f5b241c7..7d65184e 100644 --- a/Tactical/Civ Quotes.cpp +++ b/Tactical/Civ Quotes.cpp @@ -494,7 +494,7 @@ UINT16 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT16 *pubCivHintToUse, BOOLE #else INT8 bTownId; - INT8 bCivHint; + INT8 bCivHint; INT8 bMineId; #endif @@ -508,26 +508,25 @@ UINT16 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT16 *pubCivHintToUse, BOOLE (*pubCivHintToUse) = 0; ubCivType = GetCivType( pCiv ); - - - for( iCounter2 = NON_CIV_GROUP; iCounter2 < NUM_CIV_GROUPS; iCounter2++ ) - { + + if ( pCiv->ubCivilianGroup < NUM_CIV_GROUPS ) + { #ifdef JA2UB - if (pCiv->ubCivilianGroup > UNNAMED_CIV_GROUP_19 && pCiv->ubCivilianGroup == iCounter2) + if ( pCiv->ubCivilianGroup > UNNAMED_CIV_GROUP_19 ) #else - if (pCiv->ubCivilianGroup > QUEENS_CIV_GROUP && pCiv->ubCivilianGroup == iCounter2) + if ( pCiv->ubCivilianGroup > QUEENS_CIV_GROUP ) #endif + { + if ( pCiv->aiData.bNeutral ) { - if ( pCiv->aiData.bNeutral ) - { - return( FileEDTQUoteID = iCounter2*2 +10); - } - else - { - return( FileEDTQUoteID = iCounter2*2 + 11); - } - } + return(FileEDTQUoteID = pCiv->ubCivilianGroup * 2 + 10); + } + else + { + return(FileEDTQUoteID = pCiv->ubCivilianGroup * 2 + 11); + } } + } #ifdef JA2UB if( ubCivType != CIV_TYPE_ENEMY ) @@ -747,7 +746,7 @@ UINT16 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT16 *pubCivHintToUse, BOOLE // If we are in medunna, and queen is dead, use these... if ( bTownId == MEDUNA && CheckFact( FACT_QUEEN_DEAD, 0 ) ) { - return( CIV_QUOTE_DEIDRANNA_DEAD ); + return( CIV_QUOTE_DEIDRANNA_DEAD ); } // if in a town @@ -767,44 +766,42 @@ UINT16 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT16 *pubCivHintToUse, BOOLE } } - // ATE: OK, check if we should look for a civ hint.... if ( fCanUseHints ) { - bCivHint = ConsiderCivilianQuotes( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, FALSE ); + bCivHint = ConsiderCivilianQuotes( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, FALSE ); } else { - bCivHint = -1; + bCivHint = -1; } // ATE: check miners...... if ( pCiv->ubSoldierClass == SOLDIER_CLASS_MINER ) { - bMiners = TRUE; + bMiners = TRUE; - // If not a civ hint available... - if ( bCivHint == -1 ) - { - // Check if they are under our control... - - // Should I go talk to miner? - // Not done yet. - - // Are they working for us? - bMineId = GetIdOfMineForSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); - - if ( PlayerControlsMine( bMineId ) ) + // If not a civ hint available... + if ( bCivHint == -1 ) { - return( CIV_QUOTE_MINERS_FOR_PLAYER ); - } - else - { - return( CIV_QUOTE_MINERS_NOT_FOR_PLAYER ); + // Check if they are under our control... + + // Should I go talk to miner? + // Not done yet. + + // Are they working for us? + bMineId = GetIdOfMineForSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + + if ( PlayerControlsMine( bMineId ) ) + { + return( CIV_QUOTE_MINERS_FOR_PLAYER ); + } + else + { + return( CIV_QUOTE_MINERS_NOT_FOR_PLAYER ); + } } } - } - // Is one availible? // If we are to say low loyalty, do chance @@ -855,8 +852,7 @@ UINT16 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT16 *pubCivHintToUse, BOOLE return( CIV_QUOTE_KIDS_HIGH_LOYALTY ); } } - - + // All purpose quote here.... if ( ubCivType == CIV_TYPE_ADULT ) { diff --git a/Tactical/Overhead Types.h b/Tactical/Overhead Types.h index 8cd5e2d8..91ff7142 100644 --- a/Tactical/Overhead Types.h +++ b/Tactical/Overhead Types.h @@ -361,10 +361,10 @@ enum UNNAMED_CIV_GROUP_19, ASSASSIN_CIV_GROUP, // Flugente: enemy assassins belong to this group POW_PRISON_CIV_GROUP, // Flugente: prisoners of war the player caught are in this group - VOLUNTEER_CIV_GROUP, // Flugente: civilians that the player recruited + UNNAMED_CIV_GROUP_22, UNNAMED_CIV_GROUP_23, - UNNAMED_CIV_GROUP_24, - UNNAMED_CIV_GROUP_25, + VOLUNTEER_CIV_GROUP, // Flugente: civilians that the player recruited + BOUNTYHUNTER_CIV_GROUP, // Flugente: hostile bounty hunters UNNAMED_CIV_GROUP_26, UNNAMED_CIV_GROUP_27, UNNAMED_CIV_GROUP_28, diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index 57e87c38..e5111850 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -3843,6 +3843,33 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld ) // If this was a volunteer, then we definetly reduce our volunteer pool if ( pSoldierOld->bTeam == CIV_TEAM && pSoldierOld->ubCivilianGroup == VOLUNTEER_CIV_GROUP ) AddVolunteers( -1 ); + + // if this was a bounty hunter, and no other bounty hunters exist in this sector, we must have wiped out a bounty hunter group + if ( pSoldierOld->bTeam == CIV_TEAM && pSoldierOld->ubCivilianGroup == BOUNTYHUNTER_CIV_GROUP ) + { + if ( !IsCivFactionMemberAliveInSector( BOUNTYHUNTER_CIV_GROUP ) ) + { + if ( SECTOR( pSoldierOld->sSectorX, pSoldierOld->sSectorY ) == GetFact( FACT_BOUNTYHUNTER_SECTOR_1 ) ) + SetFactTrue( FACT_BOUNTYHUNTER_KILLED_1 ); + + if ( SECTOR( pSoldierOld->sSectorX, pSoldierOld->sSectorY ) == GetFact( FACT_BOUNTYHUNTER_SECTOR_2 ) ) + SetFactTrue( FACT_BOUNTYHUNTER_KILLED_2 ); + } + } + + // if Angel an Maria are dead and the bounty hunter quest is still ongoing, then finish it + if ( gubQuest[QUEST_KINGPIN_ANGEL_MARIA] == QUESTINPROGRESS ) + { + if ( pSoldierOld->ubProfile == ANGEL && gMercProfiles[MARIA].bMercStatus == MERC_IS_DEAD || + pSoldierOld->ubProfile == MARIA && gMercProfiles[ANGEL].bMercStatus == MERC_IS_DEAD ) + { + // send Email from kingpin with a delay + AddStrategicEvent( EVENT_KINGPIN_BOUNTY_END_KILLEDTHEM, GetWorldTotalMin( ) + 60 * (1 + Random( 6 )), 0 ); + + // remove 'other + DeleteStrategicEvent( EVENT_KINGPIN_BOUNTY_END_TIME_PASSED, 0 ); + } + } } else if ( pSoldierOld->bTeam == MILITIA_TEAM ) { @@ -11179,4 +11206,25 @@ BOOLEAN CoweringShockLevel( SOLDIERTYPE * pSoldier ) } return FALSE; -} \ No newline at end of file +} + +// Flugente: is any member of a specific civilian faction still alive in the current sector? +BOOLEAN IsCivFactionMemberAliveInSector( UINT8 usCivilianGroup ) +{ + SOLDIERTYPE *pSoldier = NULL; + + // IF IT'S THE SELECTED GUY, MAKE ANOTHER SELECTED! + UINT16 cnt = gTacticalStatus.Team[CIV_TEAM].bFirstID; + + // look for all mercs on the same team, + for ( pSoldier = MercPtrs[cnt]; cnt <= gTacticalStatus.Team[CIV_TEAM].bLastID; ++cnt, ++pSoldier ) + { + if ( pSoldier->bActive && (pSoldier->sSectorX == gWorldSectorX) && (pSoldier->sSectorY == gWorldSectorY) && (pSoldier->bSectorZ == gbWorldSectorZ) ) + { + if ( pSoldier->ubCivilianGroup == usCivilianGroup && pSoldier->stats.bLife > 0 ) + return TRUE; + } + } + + return FALSE; +} diff --git a/Tactical/Overhead.h b/Tactical/Overhead.h index d429f0e8..d7fda351 100644 --- a/Tactical/Overhead.h +++ b/Tactical/Overhead.h @@ -424,5 +424,8 @@ BOOLEAN GetRandomUnknownVIPSector( UINT16& aSector ); void DeleteVIP( INT16 sMapX, INT16 sMapY ); void VIPFleesToMeduna(); +// Flugente: is any member of a specific civilian faction still alive in the current sector? +BOOLEAN IsCivFactionMemberAliveInSector( UINT8 usCivilianGroup ); + #endif diff --git a/Tactical/Soldier Create.cpp b/Tactical/Soldier Create.cpp index 3031eab7..1697794e 100644 --- a/Tactical/Soldier Create.cpp +++ b/Tactical/Soldier Create.cpp @@ -1339,70 +1339,7 @@ BOOLEAN TacticalCopySoldierFromProfile( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STR { pSoldier->usSoldierFlagMask |= (SOLDIER_COVERT_SOLDIER|SOLDIER_COVERT_NPC_SPECIAL|SOLDIER_NEW_VEST|SOLDIER_NEW_PANTS); - UINT8 rnd = Random(11); - - // Vest - switch ( rnd ) - { - 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; - } - - rnd = Random(6); - - // Pants - switch ( rnd ) - { - 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; - } + SetClothes( pSoldier, Random( 11 ), Random( 6 ) ); } return( TRUE ); @@ -1503,6 +1440,46 @@ INT32 ChooseHairColor( UINT8 usBodyType, INT32 skin ) return hair; } +// Flugente: set palettes for vest/shirt +void SetClothes( SOLDIERTYPE* pSoldier, INT8 aVest, INT8 aPants ) +{ + if ( !pSoldier ) + return; + + // Vest + if ( aVest >= 0 && aVest < 11 ) + { + 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; + } + } + + // Pants + if ( aPants >= 0 && aPants < 6 ) + { + 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; + } + } +} + void GeneratePaletteForSoldier( SOLDIERTYPE *pSoldier, UINT8 ubSoldierClass, UINT8 ubTeam ) { INT32 skin, hair; @@ -3336,7 +3313,50 @@ SOLDIERTYPE* TacticalCreateCreature( INT8 bCreatureBodyType ) return TacticalCreateSoldier( &pp, &ubID ); } -// Flugente: assassins are elite soldiers of the civ team that go hostile on a certain event, otherwsie they just blend in +// Flugente: create an armed civilian +SOLDIERTYPE* TacticalCreateArmedCivilian( UINT8 usSoldierClass ) +{ + BASIC_SOLDIERCREATE_STRUCT bp; + SOLDIERCREATE_STRUCT pp; + UINT8 ubID; + SOLDIERTYPE * pSoldier = NULL; + + // this needs the covert ops trait, and thus the new trait system + if ( !gGameOptions.fNewTraitSystem ) + return NULL; + + // not in autoresolve! + if ( guiCurrentScreen == AUTORESOLVE_SCREEN ) + return NULL; + + memset( &bp, 0, sizeof(BASIC_SOLDIERCREATE_STRUCT) ); + RandomizeRelativeLevel( &(bp.bRelativeAttributeLevel), usSoldierClass ); + RandomizeRelativeLevel( &(bp.bRelativeEquipmentLevel), usSoldierClass ); + bp.bTeam = CIV_TEAM; + bp.bOrders = FARPATROL; + bp.bAttitude = (INT8)Random( MAXATTITUDES ); + bp.bBodyType = Random( 4 ); + bp.ubSoldierClass = usSoldierClass; + CreateDetailedPlacementGivenBasicPlacementInfo( &pp, &bp ); + + pSoldier = TacticalCreateSoldier( &pp, &ubID ); + + if ( pSoldier ) + { + // send soldier to centre of map, roughly + pSoldier->aiData.sNoiseGridno = (CENTRAL_GRIDNO + (Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS) + (Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS) * WORLD_COLS); + pSoldier->aiData.ubNoiseVolume = MAX_MISC_NOISE_DURATION; + + // random clothes + SetClothes( pSoldier, Random( 11 ), Random( 6 ) ); + + pSoldier->CreateSoldierPalettes( ); + } + + 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) { BASIC_SOLDIERCREATE_STRUCT bp; @@ -3978,10 +3998,11 @@ UINT8 GetLocationModifier( UINT8 ubSoldierClass ) #endif BOOLEAN fSuccess; - + // Flugente: why do we always crash the game if something does not work? // where is all this taking place? - fSuccess = GetCurrentBattleSectorXYZ( &sSectorX, &sSectorY, &sSectorZ ); - Assert( fSuccess ); + if ( !GetCurrentBattleSectorXYZ( &sSectorX, &sSectorY, &sSectorZ ) ) + return 0; + #ifdef JA2UB //Ja25 UB //switch on the sector, to determine modifer diff --git a/Tactical/Soldier Create.h b/Tactical/Soldier Create.h index 7172cb22..6a48ebb2 100644 --- a/Tactical/Soldier Create.h +++ b/Tactical/Soldier Create.h @@ -447,10 +447,14 @@ SOLDIERTYPE* TacticalCreateCreature( INT8 bCreatureBodyType ); SOLDIERTYPE* TacticalCreateEnemyTank(); SOLDIERTYPE* TacticalCreateJeep(); +// Flugente: create an armed civilian +SOLDIERTYPE* TacticalCreateArmedCivilian( UINT8 usSoldierClass = SOLDIER_CLASS_ARMY ); + // 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); +// create a prisoner (in a prison cell) in the current sector void CreatePrisonerOfWar(); // randomly generates a relative level rating (attributes or equipment) @@ -557,4 +561,7 @@ 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); + #endif \ No newline at end of file diff --git a/Tactical/Soldier Init List.cpp b/Tactical/Soldier Init List.cpp index 8c819a3c..9d194846 100644 --- a/Tactical/Soldier Init List.cpp +++ b/Tactical/Soldier Init List.cpp @@ -57,6 +57,7 @@ #include "CampaignStats.h" // added by Flugente #include "Town Militia.h" // added by Flugente #include "PreBattle Interface.h" // added by Flugente +#include "LuaInitNPCs.h" // added by Flugente BOOLEAN gfOriginalList = TRUE; @@ -951,8 +952,12 @@ UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum ) // Flugente: spawn prisoners of war in prison sectors if ( bTeam == CIV_TEAM ) + { SectorAddPrisonersofWar(gWorldSectorX, gWorldSectorY, gbWorldSectorZ); + LuaHandleSectorTacticalEntry( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + } + //There aren't any basic placements of desired team, so exit. return ubNumAdded; } @@ -1002,8 +1007,12 @@ UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum ) // Flugente: spawn prisoners of war in prison sectors if ( bTeam == CIV_TEAM ) + { SectorAddPrisonersofWar(gWorldSectorX, gWorldSectorY, gbWorldSectorZ); + LuaHandleSectorTacticalEntry( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + } + return ubNumAdded; } diff --git a/Tactical/Soldier Init List.h b/Tactical/Soldier Init List.h index 17a3abbe..85051259 100644 --- a/Tactical/Soldier Init List.h +++ b/Tactical/Soldier Init List.h @@ -65,4 +65,7 @@ void SectorAddAssassins( INT16 sMapX, INT16 sMapY, INT16 sMapZ ); // Flugente: decide wether to create prisoners of war in a sector. Not to be confused with player POWs void SectorAddPrisonersofWar( INT16 sMapX, INT16 sMapY, INT16 sMapZ ); +// Flugente: add script-defined civilians if Lua functions say so +void SectorAddLuaCivilians( INT16 sMapX, INT16 sMapY, INT16 sMapZ ); + #endif \ No newline at end of file