MERGED source code from development trunk revision 4545 up to latest current revision 4882

Development Trunk: https://ja2svn.dyndns.org/source/ja2/branches/Wanne/JA2%201.13%20MP
A detailed list of all the features (changes) is visible in the history log of the development trunk:

INFO: The source code for the official 2011 release (4870) has been branched here:
https://ja2svn.dyndns.org/source/ja2/branches/JA2_rev.4870_2011

This commit contains the following features:

*** Externalized Vehicles ***
o Now with this feature we can add/remove vehicles
o New XML File: TableData\Vehicles.xml
o Added a new function parameter to lua file Scripts\Overhead lua to set up the helicopter in method: SetUpHelicopterForPlayer()
o Added example mini (Docs\Externalized Vehicles Example.zip) mod which adds 2 additional vehicles (hummer and ice-cream truck to sector A9)

*** Up to 255 save slots ***
- There is a "Next" and "Prev" button where you can scroll through the save slots
- It is now possible to load the automatic save (SAVE_EVERY_N_HOURS) from the load screen. This is the first slot after the quickload slot
- Added the 2 alternate players end turn saves (which can be enabled/disabled in option screen) to the save/load game form

*** New Feature: Externalized emails from Emails.edt to XML***
o This feature can be enabled/disabled in the Source:
--> See email.cpp: If "ReadXMLEmail" == FALSE, then normal way (read from Email.edt) otherwise read from XML files
o 2 new XML files: TableData\Email\EmailMercAvailable.xml and EmailMercLevelUp.xml
o Renamed SenderNamesList.xml to EmailSenderNamesList.xml and moved from TableData folder to TableData\Email folder
o Names for mercenaries are get from the file MercProfiles.xml and different names get from the file EmailSenderNamesList.xml

*** Externalized Hidden Towns (Tixa, Orta) ***
o Now it is possible to add new hidden towns (locations)
o See file: TableData/Map/Cities.xml
o New variable in TableData/Map/Cities.xml
- hiddenTown:   0 = show on strategy map, 1 = Hide on strategy map
- townIcon:     1 = on, 0 = off (This is the icon you see on the strategy map)
- szIconFile:   The path to the sti icon file (eg: interface\prison.sti, interface\my_icon.sti)
- iconPosition: The x,y position of the icon on the strategy map

*** Encyclopedia and Briefing Room, reachable from the laptop ***
o 2 new ja2_options.ini properties: BRIEFING_ROOM, ENCYCLOPEDIA
o demonstration video: http://www.youtube.com/watch?v=7CIXdXWLrAo
o Added Example usage of the Briefing Room
- Extract it in your JA2 1.13 folder and use the latest development executable
- The briefing room can be reached from the laptop. Enter SN5631 for the code and then click the "Exit" button
- See "Info_BriefingRoom.txt" and "BriefingRoom_Mission1.png"

*** Improved interrupt system (IIS) ***
o This system changes the way interrupts work. See: http://www.ja-galaxy-forum.com/board/ubbthreads.php?ubb=showflat&Number=290787#Post290787
o Option system (see ja2_options.ini: IMPROVED_INTERRUPT_SYSTEM)
o A few more settings for the interrupt system in ja2_options.ini
o INFO: Multiplayer games always use the "old" interrupt system, not matter what the user selects in the ja2_options.ini

*** Walking and sidestepping with weapon raised ***
o Enable/disable the walking/sidestepping with raised weapon in ja2_options.ini: ALLOW_WALKING_WITH_WEAPON_RAISED
o You can set an AP/BP modifier when walking/sidestepping with weapon raised in APBPConstants.ini: AP_MODIFIER_WEAPON_READY
o The following feature apply when you walk/sidestep with weapon raised:
-> limited angle of view, but you can see more farther when the weapon has a scope
-> better change for interrupts if you see an enemy
-> less APs and BPs when shooting, because the weapon is already raised
-> It should cost more APs when walking. Maybe you can export the additional AP and BP modifier to the APBPConstants.ini

*** Increase squad size to 8 (800x600) and 8 and 10 (1024x768) ***
o Squad sizes (dependend on the screen resolution) can be selected in the start new game screen
o In a multiplayer game, the squad size will always be 6, because it does not work with more soldiers/squad

*** Added UB-1.13 source code ***
o Merged the UB-1.13 source code (Revision: 4721) from svn: http://subversion.assembla.com/svn/ub-source113
o If you want to build UB-EXE or UB-MapEditor, just enable the 2 defines (JA2UB and JA2UBMAPS) in "builddefines.h"
o The UB-Verion reads from "ja2_UB.ini" instead of "ja2.ini"
o There are 2 new XML files
- Layout\LayoutMainMenu.xml
- MapAction\ActionItems.xml
o There are 2 new LUA-Script files
- Scripts\ExplosionControl.lua
- Scripts\InterfaceDialogue.lua

*** Hide enemy health text / enemy hit count ***
o ja2_options.ini: HIDE_ENEMY_HEALTH_TEXT, HIDE_ENEMY_HIT_COUNT
o both new settings only have effect in a singleplayer game
o see: http://www.ja-galaxy-forum.com/board/ubbthreads.php?ubb=showflat&Number=128840&page=1


git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4885 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2012-01-18 11:19:01 +00:00
parent c42d68ff0f
commit e64d5a2fa6
264 changed files with 40710 additions and 2771 deletions
+11 -1
View File
@@ -27,7 +27,17 @@ typedef enum
ACTION_ITEM_UNTRAP_DOOR,
ACTION_ITEM_TOGGLE_PRESSURE_ITEMS,
ACTION_ITEM_MUSEUM_ALARM,
ACTION_ITEM_BLOODCAT_ALARM
ACTION_ITEM_BLOODCAT_ALARM,
#ifdef JA2UB
ACTION_ITEM_BIGGENS_BOMBS,
ACTION_ITEM_BIGGENS_WARNING,
ACTION_ITEM_SEE_FORTIFIED_DOOR,
ACTION_ITEM_OPEN_FORTIFED_DOOR,
ACTION_ITEM_SEE_POWER_GEN_FAN,
ACTION_ITEM_NEW = ACTION_ITEM_SEE_POWER_GEN_FAN + 215
#else
ACTION_ITEM_NEW = ACTION_ITEM_BLOODCAT_ALARM + 220
#endif
} ItemActionType;
#endif
+71 -3
View File
@@ -997,6 +997,16 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] =
//RUN (with pistol)
{"RUN WITH PISTOL" , 0, 0, (FLOAT)2.6, ANIM_MOVING | ANIM_TURNING | ANIM_NORESTART | ANIM_RAISE_WEAPON | ANIM_MODERATE_EFFORT, ANIM_STAND, ANIM_STAND, -1},
//SIDE STEPPING WITH READIED WEAPON
"SIDE STEPPING WITH PISTOL RDY" , 0, 50, (FLOAT)0.4, ANIM_MOVING | ANIM_NORESTART | ANIM_FIREREADY | ANIM_RAISE_WEAPON | ANIM_VARIABLE_EFFORT, ANIM_STAND, ANIM_STAND, -1,
"SIDE STEPPING WITH RIFLE RDY" , 0, 50, (FLOAT)0.4, ANIM_MOVING | ANIM_NORESTART | ANIM_FIREREADY | ANIM_RAISE_WEAPON | ANIM_VARIABLE_EFFORT, ANIM_STAND, ANIM_STAND, -1,
"SIDE STEPPING WITH DUAL RDY" , 0, 50, (FLOAT)0.4, ANIM_MOVING | ANIM_NORESTART | ANIM_FIREREADY | ANIM_RAISE_WEAPON | ANIM_VARIABLE_EFFORT, ANIM_STAND, ANIM_STAND, -1,
//WALKING WITH READIED WEAPON
{"WALKING WITH PISTOL RDY" , 20, 0, (FLOAT)1.6, ANIM_MOVING | ANIM_TURNING | ANIM_NORESTART | ANIM_FIREREADY | ANIM_RAISE_WEAPON | ANIM_VARIABLE_EFFORT, ANIM_STAND, ANIM_STAND, -1},
{"WALKING WITH RIFLE RDY" , 20, 0, (FLOAT)1.6, ANIM_MOVING | ANIM_TURNING | ANIM_NORESTART | ANIM_FIREREADY | ANIM_RAISE_WEAPON | ANIM_VARIABLE_EFFORT, ANIM_STAND, ANIM_STAND, -1},
{"WALKING WITH DUAL RDY" , 20, 0, (FLOAT)1.6, ANIM_MOVING | ANIM_TURNING | ANIM_NORESTART | ANIM_FIREREADY | ANIM_RAISE_WEAPON | ANIM_VARIABLE_EFFORT, ANIM_STAND, ANIM_STAND, -1},
};
ANI_SPEED_DEF gubAnimWalkSpeeds[ TOTALBODYTYPES ] =
@@ -1397,6 +1407,14 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ REGMALE ][ JUMPDOWNWALL ] = RGMWALLJUMP;
gubAnimSurfaceIndex[ REGMALE ][ JUMPWINDOWS ] = RGMJUMPWINDOWS;
gubAnimSurfaceIndex[ REGMALE ][ SIDE_STEP_PISTOL_RDY ] = RGMSIDESTEP_P_RDY;
gubAnimSurfaceIndex[ REGMALE ][ SIDE_STEP_RIFLE_RDY ] = RGMSIDESTEP_R_RDY;
gubAnimSurfaceIndex[ REGMALE ][ SIDE_STEP_DUAL_RDY ] = RGMSIDESTEP_D_RDY;
gubAnimSurfaceIndex[ REGMALE ][ WALKING_PISTOL_RDY ] = RGMWALK_P_RDY;
gubAnimSurfaceIndex[ REGMALE ][ WALKING_RIFLE_RDY ] = RGMWALK_R_RDY;
gubAnimSurfaceIndex[ REGMALE ][ WALKING_DUAL_RDY ] = RGMWALK_D_RDY;
gubAnimSurfaceMidWaterSubIndex[ REGMALE ][ STANDING][0] = RGMWATER_R_STD;
gubAnimSurfaceMidWaterSubIndex[ REGMALE ][ WALKING ][0] = RGMWATER_R_WALK;
@@ -1775,6 +1793,13 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ BIGMALE ][ JUMPWINDOWS ] = BGMJUMPWINDOWS;
gubAnimSurfaceIndex[ BIGMALE ][ SIDE_STEP_PISTOL_RDY ] = BGMSIDESTEP_P_RDY;
gubAnimSurfaceIndex[ BIGMALE ][ SIDE_STEP_RIFLE_RDY ] = BGMSIDESTEP_R_RDY;
gubAnimSurfaceIndex[ BIGMALE ][ SIDE_STEP_DUAL_RDY ] = BGMSIDESTEP_D_RDY;
gubAnimSurfaceIndex[ BIGMALE ][ WALKING_PISTOL_RDY ] = BGMWALK_P_RDY;
gubAnimSurfaceIndex[ BIGMALE ][ WALKING_RIFLE_RDY ] = BGMWALK_R_RDY;
gubAnimSurfaceIndex[ BIGMALE ][ WALKING_DUAL_RDY ] = BGMWALK_D_RDY;
gubAnimSurfaceItemSubIndex[ BIGMALE ][ STANDING ] = BGMPISTOLBREATH;
gubAnimSurfaceItemSubIndex[ BIGMALE ][ WALKING ] = BGMNOTHING_WALK;
@@ -2169,6 +2194,14 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ STOCKYMALE ][ JUMPWINDOWS ] = RGMJUMPWINDOWS;
gubAnimSurfaceIndex[ STOCKYMALE ][ SIDE_STEP_PISTOL_RDY ] = RGMSIDESTEP_P_RDY;
gubAnimSurfaceIndex[ STOCKYMALE ][ SIDE_STEP_RIFLE_RDY ] = RGMSIDESTEP_R_RDY;
gubAnimSurfaceIndex[ STOCKYMALE ][ SIDE_STEP_DUAL_RDY ] = RGMSIDESTEP_D_RDY;
gubAnimSurfaceIndex[ STOCKYMALE ][ WALKING_PISTOL_RDY ] = RGMWALK_P_RDY;
gubAnimSurfaceIndex[ STOCKYMALE ][ WALKING_RIFLE_RDY ] = RGMWALK_R_RDY;
gubAnimSurfaceIndex[ STOCKYMALE ][ WALKING_DUAL_RDY ] = RGMWALK_D_RDY;
gubAnimSurfaceItemSubIndex[ STOCKYMALE ][ STANDING ] = RGMPISTOLBREATH;
gubAnimSurfaceItemSubIndex[ STOCKYMALE ][ WALKING ] = RGMNOTHING_WALK;
gubAnimSurfaceItemSubIndex[ STOCKYMALE ][ RUNNING] = RGMNOTHING_RUN;
@@ -2541,6 +2574,15 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceIndex[ REGFEMALE ][ JUMPWINDOWS ] = RGFJUMPWINDOWS;
gubAnimSurfaceIndex[ REGFEMALE ][ SIDE_STEP_PISTOL_RDY ] = RGFSIDESTEP_P_RDY;
gubAnimSurfaceIndex[ REGFEMALE ][ SIDE_STEP_RIFLE_RDY ] = RGFSIDESTEP_R_RDY;
gubAnimSurfaceIndex[ REGFEMALE ][ SIDE_STEP_DUAL_RDY ] = RGFSIDESTEP_D_RDY;
gubAnimSurfaceIndex[ REGFEMALE ][ WALKING_PISTOL_RDY ] = RGFWALK_P_RDY;
gubAnimSurfaceIndex[ REGFEMALE ][ WALKING_RIFLE_RDY ] = RGFWALK_R_RDY;
gubAnimSurfaceIndex[ REGFEMALE ][ WALKING_DUAL_RDY ] = RGFWALK_D_RDY;
gubAnimSurfaceItemSubIndex[ REGFEMALE ][ STANDING ] = RGFPISTOLBREATH;
gubAnimSurfaceItemSubIndex[ REGFEMALE ][ WALKING ] = RGFNOTHING_WALK;
gubAnimSurfaceItemSubIndex[ REGFEMALE ][ RUNNING ] = RGFNOTHING_RUN;
@@ -3275,6 +3317,14 @@ BOOLEAN LoadAnimationStateInstructions( )
memcpy(gusAnimInst[RUNNING_W_PISTOL],fuckTheBoundz[RUNNING],sizeof(fuckTheBoundz[RUNNING]));
memcpy(gusAnimInst[SIDE_STEP_PISTOL_RDY],fuckTheBoundz[SIDE_STEP],sizeof(fuckTheBoundz[SIDE_STEP]));
memcpy(gusAnimInst[SIDE_STEP_RIFLE_RDY],fuckTheBoundz[SIDE_STEP],sizeof(fuckTheBoundz[SIDE_STEP]));
memcpy(gusAnimInst[SIDE_STEP_DUAL_RDY],fuckTheBoundz[SIDE_STEP],sizeof(fuckTheBoundz[SIDE_STEP]));
memcpy(gusAnimInst[WALKING_PISTOL_RDY],fuckTheBoundz[WALKING],sizeof(fuckTheBoundz[WALKING]));
memcpy(gusAnimInst[WALKING_RIFLE_RDY],fuckTheBoundz[WALKING],sizeof(fuckTheBoundz[WALKING]));
memcpy(gusAnimInst[WALKING_DUAL_RDY],fuckTheBoundz[WALKING],sizeof(fuckTheBoundz[WALKING]));
return( TRUE );
}
@@ -3665,6 +3715,20 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta
// else usAnimSurface = BGMSTANDAIM2;
}
}
if ( usAnimSurface == BGMSIDESTEP_R_RDY )
{
if ( pSoldier->uiAnimSubFlags & SUB_ANIM_BIGGUYSHOOT2 )
{
usAnimSurface = BGMSIDESTEP_R_RDY2;
}
}
if ( usAnimSurface == BGMWALK_R_RDY )
{
if ( pSoldier->uiAnimSubFlags & SUB_ANIM_BIGGUYSHOOT2 )
{
usAnimSurface = BGMWALK_R_RDY2;
}
}
// SWITCH TO DIFFERENT STAND ANIMATION FOR BIG GUY!
if ( usAnimSurface == BGMSTANDING )
@@ -3788,13 +3852,17 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta
// Look for good two pistols sub anim.....
if ( gDoubleHandledSub.usAnimState == usAnimState )
{
{
// Do we carry two pistols...
//if ( Item[ pSoldier->inv[ SECONDHANDPOS ].usItem ].usItemClass == IC_GUN )
if ( pSoldier->IsValidSecondHandShot() )
{
usAnimSurface = gDoubleHandledSub.usAnimationSurfaces[ pSoldier->ubBodyType ];
fAdjustedForItem = TRUE;
usAltAnimSurface = gDoubleHandledSub.usAnimationSurfaces[ pSoldier->ubBodyType ];
if ( usAltAnimSurface != INVALID_ANIMATION )
{
usAnimSurface = usAltAnimSurface;
fAdjustedForItem = TRUE;
}
}
}
+8
View File
@@ -563,6 +563,14 @@ enum AnimationStates
THROW_KNIFE_SP_BM,
RUNNING_W_PISTOL,
SIDE_STEP_PISTOL_RDY,
SIDE_STEP_RIFLE_RDY,
SIDE_STEP_DUAL_RDY,
WALKING_PISTOL_RDY,
WALKING_RIFLE_RDY,
WALKING_DUAL_RDY,
NUMANIMATIONSTATES
};
+26
View File
@@ -522,6 +522,32 @@ AnimationSurfaceType gAnimSurfaceDatabase[ NUMANIMATIONSURFACETYPES ] =
BGMPISTOL_RUN, "ANIMS\\M_MERC\\M_P_RUN.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGFPISTOL_RUN, "ANIMS\\F_MERC\\F_P_RUN.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGMSIDESTEP_P_RDY, "ANIMS\\S_MERC\\S_P_RDY_SDSP.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGMSIDESTEP_R_RDY, "ANIMS\\S_MERC\\S_R_RDY_SDSP.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGMSIDESTEP_D_RDY, "ANIMS\\S_MERC\\S_DBL_RDY_SDSP.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
BGMSIDESTEP_P_RDY, "ANIMS\\M_MERC\\M_N2_SDSP_RDY.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
BGMSIDESTEP_R_RDY, "ANIMS\\M_MERC\\M_R_SDSP_RDY.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
BGMSIDESTEP_R_RDY2, "ANIMS\\M_MERC\\M_R_BDSS_SDSP_RDY.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
BGMSIDESTEP_D_RDY, "ANIMS\\M_MERC\\M_DBL_SDSP_RDY.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGFSIDESTEP_P_RDY, "ANIMS\\F_MERC\\F_P_RDY_SDSP.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGFSIDESTEP_R_RDY, "ANIMS\\F_MERC\\F_R_RDY_SDSP.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGFSIDESTEP_D_RDY, "ANIMS\\F_MERC\\F_DBL_RDY_SDSP.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGMWALK_P_RDY, "ANIMS\\S_MERC\\S_P_RDY_WALK.sti", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGMWALK_R_RDY, "ANIMS\\S_MERC\\S_R_RDY_WALK.sti", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGMWALK_D_RDY, "ANIMS\\S_MERC\\S_DBL_RDY_WALK.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
BGMWALK_P_RDY, "ANIMS\\M_MERC\\M_N2_RDY_WALK.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
BGMWALK_R_RDY, "ANIMS\\M_MERC\\M_R_RDY_WALK.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
BGMWALK_R_RDY2, "ANIMS\\M_MERC\\M_R_RDY_DBASS_WALK.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
BGMWALK_D_RDY, "ANIMS\\M_MERC\\M_DBL_RDY_WALK.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGFWALK_P_RDY, "ANIMS\\F_MERC\\F_P_RDY_WALK.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGFWALK_R_RDY, "ANIMS\\F_MERC\\F_R_RDY_WALK.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGFWALK_D_RDY, "ANIMS\\F_MERC\\F_DBL_RDY_WALK.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
};
+26
View File
@@ -551,6 +551,32 @@ BGMWITHSTONE,
BGMPISTOL_RUN,
RGFPISTOL_RUN,
RGMSIDESTEP_P_RDY,
RGMSIDESTEP_R_RDY,
RGMSIDESTEP_D_RDY,
BGMSIDESTEP_P_RDY,
BGMSIDESTEP_R_RDY,
BGMSIDESTEP_R_RDY2,
BGMSIDESTEP_D_RDY,
RGFSIDESTEP_P_RDY,
RGFSIDESTEP_R_RDY,
RGFSIDESTEP_D_RDY,
RGMWALK_P_RDY,
RGMWALK_R_RDY,
RGMWALK_D_RDY,
BGMWALK_P_RDY,
BGMWALK_R_RDY,
BGMWALK_R_RDY2,
BGMWALK_D_RDY,
RGFWALK_P_RDY,
RGFWALK_R_RDY,
RGFWALK_D_RDY,
NUMANIMATIONSURFACETYPES
} AnimationSurfaceTypes;
+207 -9
View File
@@ -19,6 +19,16 @@
#include "GameSettings.h"
#endif
#ifdef JA2UB
#include "Explosion Control.h"
#include "Ja25_Tactical.h"
#include "Ja25 Strategic Ai.h"
#include "MapScreen Quotes.h"
#include "email.h"
#include "interface Dialogue.h"
#include "ub_config.h"
#endif
#include <list>
#define MIN_REPAIR_TIME_IN_MINUTES 15 // minutes
@@ -48,7 +58,12 @@ const ARMS_DEALER_INFO DefaultarmsDealerInfo[ NUM_ARMS_DEALERS ] =
/* Jake Cameron */ { 0.8f, 1.1f, JAKE, ARMS_DEALER_BUYS_SELLS, 2500, ARMS_DEALER_ONLY_USED_ITEMS | ARMS_DEALER_GIVES_CHANGE, 2500, 2500, 0, 1, 10, 0, 100, 1, 2, false, true },
/* Gabby Mulnick*/ { 1.0f, 1.0f, GABBY, ARMS_DEALER_BUYS_SELLS, 3000, ARMS_DEALER_GIVES_CHANGE , 3000, 3000, 0, 1, 10, 0, 100, 1, 2, false, true },
#ifdef JA2UB
/* Devin Connell*/ //ja25 ub Biggins//{ 0.75f, 1.25f, DEVIN, ARMS_DEALER_SELLS_ONLY, 5000, ARMS_DEALER_GIVES_CHANGE , 5000, 5000, 0, 3, 10, 0, 10, 2, 3, false, false },
#else
/* Devin Connell*/ { 0.75f, 1.25f, DEVIN, ARMS_DEALER_SELLS_ONLY, 5000, ARMS_DEALER_GIVES_CHANGE , 5000, 5000, 0, 3, 10, 0, 10, 2, 3, false, false },
#endif
/* Howard Filmore*/ { 1.0f, 1.0f, HOWARD, ARMS_DEALER_SELLS_ONLY, 3000, ARMS_DEALER_GIVES_CHANGE , 3000, 3000, 0, 1, 10, 0, 100, 1, 2, false, true },
/* Sam Rozen */ { 1.0f, 1.0f, SAM, ARMS_DEALER_SELLS_ONLY, 3000, ARMS_DEALER_GIVES_CHANGE , 3000, 3000, 0, 1, 10, 0, 100, 1, 2, false, true },
/* Frank */ { 1.0f, 1.0f, FRANK, ARMS_DEALER_SELLS_ONLY, 500, ARMS_DEALER_ACCEPTS_GIFTS , 500, 500, 0, 1, 10, 0, 100, 1, 2, false, true },
@@ -64,11 +79,20 @@ const ARMS_DEALER_INFO DefaultarmsDealerInfo[ NUM_ARMS_DEALERS ] =
//Speed Cost
/* Arnie Brunzwell*/{ 0.1f, 0.8f, ARNIE, ARMS_DEALER_REPAIRS, 1500, ARMS_DEALER_HAS_NO_INVENTORY | ARMS_DEALER_GIVES_CHANGE, 1500, 1500, 0, 1, 10, 1, 10, 1, 2, false, true },
/* Fredo */ { 0.6f, 0.6f, FREDO, ARMS_DEALER_REPAIRS, 1000, ARMS_DEALER_HAS_NO_INVENTORY | ARMS_DEALER_GIVES_CHANGE, 1000, 1000, 0, 1, 10, 1, 10, 1, 2, false, true },
#ifdef JA2UB
/* Raul */ { 0.80f, 1.8f, PERKO, ARMS_DEALER_BUYS_SELLS, 20000, ARMS_DEALER_SOME_USED_ITEMS | ARMS_DEALER_GIVES_CHANGE , 1000, 1000, 0, 1, 10, 1, 10, 1, 2, false, true },
#else
/* Perko */ { 1.0f, 0.4f, PERKO, ARMS_DEALER_REPAIRS, 1000, ARMS_DEALER_HAS_NO_INVENTORY | ARMS_DEALER_GIVES_CHANGE, 1000, 1000, 0, 1, 10, 1, 10, 1, 2, false, true },
#endif
/* Elgin */ { 1.0f, 1.0f, DRUGGIST, ARMS_DEALER_SELLS_ONLY, 500, ARMS_DEALER_ACCEPTS_GIFTS , 500, 500, 0, 1, 10, 1, 10, 1, 2, false, true },
/* Manny */ { 1.0f, 1.0f, MANNY, ARMS_DEALER_SELLS_ONLY, 500, ARMS_DEALER_ACCEPTS_GIFTS , 500, 500, 0, 1, 10, 1, 10, 1, 2, false, true },
#ifdef JA2UB
/* Betty */ { 0.75f, 1.25f, 73, ARMS_DEALER_BUYS_SELLS, 10000, ARMS_DEALER_SOME_USED_ITEMS | ARMS_DEALER_GIVES_CHANGE , 1000, 1000, 0, 1, 10, 1, 10, 1, 2, false, true },
#endif
};
std::vector<ARMS_DEALER_INFO> armsDealerInfo (NUM_ARMS_DEALERS);
@@ -92,9 +116,9 @@ BOOLEAN AdjustCertainDealersInventory();
void LimitArmsDealersInventory( UINT8 ubArmsDealer, UINT32 uDealerItemType, UINT8 ubMaxNumberOfItemType );
void GuaranteeAtLeastOneItemOfType( UINT8 ubArmsDealer, UINT32 uiDealerItemType );
void GuaranteeAtLeastXItemsOfIndex( UINT8 ubArmsDealer, UINT16 usItemIndex, UINT8 ubHowMany );
#ifdef JA2UB
void GuaranteeAtMostNumOfItemsForItem( UINT8 ubArmsDealer, INT16 sItemIndex, UINT8 ubAtMostNumItems );
#endif
void ArmsDealerGetsFreshStock( UINT8 ubArmsDealer, UINT16 usItemIndex, UINT8 ubNumItems );
BOOLEAN ItemContainsLiquid( UINT16 usItemIndex );
@@ -102,6 +126,13 @@ UINT8 DetermineDealerItemCondition( UINT8 ubArmsDealer, UINT16 usItemIndex );
BOOLEAN DoesItemAppearInDealerInventoryList( UINT8 ubArmsDealer, UINT16 usItemIndex, BOOLEAN fPurchaseFromPlayer );
#ifdef JA2UB
UINT8 GetFirstValidSpecialItemFromDealer( UINT8 ubArmsDealer, INT16 sItemIndex );
void AddTexsVideosToBettysInventory();
BOOLEAN CanThisItemBeSoldToSimulatedCustomer( UINT8 ubArmsDealerID, UINT16 usItemIndex );
#endif
void GuaranteeMinimumAlcohol( UINT8 ubArmsDealer );
BOOLEAN ItemIsARocketRifle( INT16 sItemIndex );
@@ -287,8 +318,11 @@ void DailyUpdateOfArmsDealersInventory()
SimulateArmsDealerCustomer();
//if there are some items that are out of stock, order some more
#ifdef JA2UB
DailyCheckOnItemQuantities( FALSE );
#else
DailyCheckOnItemQuantities();
#endif
//make sure certain items are in stock and certain limits are respected
AdjustCertainDealersInventory( );
}
@@ -327,6 +361,13 @@ void SimulateArmsDealerCustomer()
{
if ( Item[usItemIndex].usItemClass == 0 )
break;
#ifdef JA2UB
//JA25 UB//
if( !CanThisItemBeSoldToSimulatedCustomer( ubArmsDealer, usItemIndex ) )
{
continue;
}
#endif
//if there are some of these in stock
if( numPerfectItems[usItemIndex] > 0)
{
@@ -367,8 +408,11 @@ void SimulateArmsDealerCustomer()
}
}
#ifdef JA2UB
void DailyCheckOnItemQuantities( BOOLEAN fInstallyHaveItemsAppear )
#else
void DailyCheckOnItemQuantities()
#endif
{
UINT8 ubArmsDealer;
UINT16 usItemIndex;
@@ -409,6 +453,15 @@ void DailyCheckOnItemQuantities()
{
iter->ubQtyOnOrder = 0;
iter->uiOrderArrivalTime = 0;
#ifdef JA2UB
//JA25 UB if the dealer is RAUL
if( ubArmsDealer == ARMS_DEALER_RAUL )
{
//set the fact the raul refreshed his inventory
SetFactTrue( FACT_RAULS_INVENTORY_CHANGED_SINCE_LAST_VISIT );
}
#endif
}
}
}
@@ -435,7 +488,14 @@ void DailyCheckOnItemQuantities()
{
// figure out how many items to reorder (items are reordered an entire batch at a time)
ubNumItems = HowManyItemsToReorder( ubMaxSupply, numTotalItems[ usItemIndex ] );
#ifdef JA2UB
//if the dealer is betty, and we are to ADD the stuff instantly
if( ubArmsDealer == ARMS_DEALER_BETTY && fInstallyHaveItemsAppear &&
( usItemIndex == MEDICKIT || usItemIndex == FIRSTAIDKIT ) )
{
ubNumItems = ubMaxSupply + ubMaxSupply/2;
}
#endif
// if this is the first day the player is eligible to have access to this thing
if ( gArmsDealerStatus[ubArmsDealer].fPreviouslyEligible[ usItemIndex ] == false )
{
@@ -445,8 +505,19 @@ void DailyCheckOnItemQuantities()
}
else
{
ubReorderDays = ( UINT8) ( armsDealerInfo[ ubArmsDealer ].daysDelayMin + Random( armsDealerInfo[ ubArmsDealer ].daysDelayMax - armsDealerInfo[ ubArmsDealer ].daysDelayMin ) );
#ifdef JA2UB
if( fInstallyHaveItemsAppear )
{
ubReorderDays = 0;
}
else
{
ubReorderDays = ( UINT8) ( armsDealerInfo[ ubArmsDealer ].daysDelayMin + Random( armsDealerInfo[ ubArmsDealer ].daysDelayMax - armsDealerInfo[ ubArmsDealer ].daysDelayMin ) );
}
#else
ubReorderDays = ( UINT8) ( armsDealerInfo[ ubArmsDealer ].daysDelayMin + Random( armsDealerInfo[ ubArmsDealer ].daysDelayMax - armsDealerInfo[ ubArmsDealer ].daysDelayMin ) );
#endif
//Determine when the inventory should arrive
uiArrivalDay = GetWorldDay() + ubReorderDays; // consider changing this to minutes
// post new order
@@ -558,7 +629,42 @@ BOOLEAN AdjustCertainDealersInventory( )
{
GuaranteeAtLeastXItemsOfIndex( ARMS_DEALER_FRANZ, VIDEO_CAMERA, 1 );
}
#ifdef JA2UB
//------------UB---------------------
//if Raul hasnt yet sold the barret
if( !( gArmsDealerStatus[ ARMS_DEALER_RAUL ].ubSpecificDealerFlags & ARMS_DEALER_FLAG__RAUL_HAS_SOLD_BARRETT_TO_PLAYER ) )
{
//Guarentee at least 1 Barrett
GuaranteeAtLeastXItemsOfIndex( ARMS_DEALER_RAUL, BARRETT_UB, 1 );
}
//if the player hasnt done the "killed the annoying bloodcats" quest for betty,
if( gubQuest[ QUEST_FIX_LAPTOP ] != QUESTDONE && gGameUBOptions.LaptopQuestEnabled == TRUE )
{
//Guarntee 1 laptop transmitter to be at betty's
GuaranteeAtLeastXItemsOfIndex( ARMS_DEALER_BETTY, LAPTOP_TRANSMITTER , 1 ); //4500
}
else
{
GuaranteeAtMostNumOfItemsForItem( ARMS_DEALER_BETTY, LAPTOP_TRANSMITTER, 0 ); //4500
}
if( gubQuest[ QUEST_GET_RID_BLOODCATS_AT_BETTYS ] != QUESTDONE )
{
//make sure she doesnt sell these items just yet
GuaranteeAtMostNumOfItemsForItem( ARMS_DEALER_BETTY, FIRSTAIDKIT, 0 );
GuaranteeAtMostNumOfItemsForItem( ARMS_DEALER_BETTY, MEDICKIT, 0 );
GuaranteeAtMostNumOfItemsForItem( ARMS_DEALER_BETTY, COMPOUND18, 0 );
GuaranteeAtMostNumOfItemsForItem( ARMS_DEALER_BETTY, CERAMIC_PLATES, 0 );
GuaranteeAtMostNumOfItemsForItem( ARMS_DEALER_BETTY, LAME_BOY, 0 );
}
//Guarntee 1 laptop transmitter to be at betty's
GuaranteeAtLeastXItemsOfIndex( ARMS_DEALER_BETTY, PORNOS, 1 );
#endif
return( TRUE );
}
@@ -1163,11 +1269,19 @@ BOOLEAN CanDealerRepairItem( UINT8 ubArmsDealer, UINT16 usItemIndex )
{
return(FALSE);
}
//#ifdef JA2UB
//Ja25: TEMP!!!
// return( FALSE );
//#endif
switch ( ubArmsDealer )
{
case ARMS_DEALER_ARNIE:
#ifdef JA2UB
//Ja25 neither in exp.
#else
case ARMS_DEALER_PERKO:
#endif
// repairs ANYTHING non-electronic
// if ( !( uiFlags & ITEM_ELECTRONIC ) )
if ( !( Item[ usItemIndex ].electronic ) )
@@ -1619,6 +1733,9 @@ void RemoveRandomItemFromArmsDealerInventory( UINT8 ubArmsDealer, UINT16 usItemI
BOOLEAN AddDeadArmsDealerItemsToWorld( UINT8 ubMercID )
{
INT8 bArmsDealer;
#ifdef JA2UB
BOOLEAN fBoobyTrapItemsWhenDropping=FALSE;
#endif
//Get Dealer ID from from merc Id
bArmsDealer = GetArmsDealerIDFromMercID( ubMercID );
if( bArmsDealer == -1 )
@@ -1642,7 +1759,14 @@ BOOLEAN AddDeadArmsDealerItemsToWorld( UINT8 ubMercID )
Assert(0);
return( FALSE );
}
#ifdef JA2UB //RAUL
//Ja25 UB
//if Raul blew him,self up, dont drop any items
if( pSoldier->ubProfile == PERKO /* RAUL */ && IsJa25GeneralFlagSet( JA_GF__RAUL_BLOW_HIMSELF_UP ) )
{
return( TRUE );
}
#endif
//loop through all the items in the dealer's inventory, and drop them all where the dealer was set up.
for (DealerItemList::iterator iter = gArmsDealersInventory[bArmsDealer].begin();
iter != gArmsDealersInventory[bArmsDealer].end(); ++iter) {
@@ -2273,6 +2397,37 @@ UINT32 CalculateMinutesClosedBetween( UINT8 ubArmsDealer, UINT32 uiStartTime, UI
return ( uiMinutesClosed );
}
#ifdef JA2UB
//JA25 ub
void AddTexsVideosToBettysInventory()
{
GuaranteeAtLeastXItemsOfIndex( ARMS_DEALER_BETTY, TEX_MOVIE_ATTACK_CLYDESDALES, 1 );
GuaranteeAtLeastXItemsOfIndex( ARMS_DEALER_BETTY, TEX_MOVIE_WILD_EAST, 1 );
GuaranteeAtLeastXItemsOfIndex( ARMS_DEALER_BETTY, TEX_MOVIE_HAVE_HONDA, 1 );
}
BOOLEAN CanThisItemBeSoldToSimulatedCustomer( UINT8 ubArmsDealerID, UINT16 usItemIndex )
{
switch( ubArmsDealerID )
{
case ARMS_DEALER_BETTY:
//if the item is..
if( usItemIndex == TEX_MOVIE_ATTACK_CLYDESDALES || //1356 ||
usItemIndex == TEX_MOVIE_WILD_EAST || //1357 ||
usItemIndex == TEX_MOVIE_HAVE_HONDA || //1358 ||
usItemIndex == LAPTOP_TRANSMITTER )//1355 )
{
return( FALSE );
}
break;
}
return( TRUE );
}
void GuaranteeAtMostNumOfItemsForItem( UINT8 ubArmsDealer, INT16 sItemIndex, UINT8 ubAtMostNumItems )
{
@@ -2294,4 +2449,47 @@ void GuaranteeAtMostNumOfItemsForItem( UINT8 ubArmsDealer, INT16 sItemIndex, UIN
}
}
/* UINT16 usCnt=0;
UINT8 ubNumToRemove=0;
SPECIAL_ITEM_INFO SpclItemInfo;
UINT8 ubNumLeftToRemove=0;
INT8 bItemCondition=0;
UINT8 bElementToRemove=0;
//if the num items in stock is greater then the num past in
if( gArmsDealersInventory[ ubArmsDealer ][ sItemIndex ].ubTotalItems > ubAtMostNumItems )
{
ubNumToRemove = gArmsDealersInventory[ ubArmsDealer ][ sItemIndex ].ubTotalItems - ubAtMostNumItems;
ubNumLeftToRemove = ubNumToRemove;
//loop through the specified #of times
while( ubNumLeftToRemove > 0 )
{
SetSpecialItemInfoToDefaults( &SpclItemInfo );
//remove special ones first
if( gArmsDealersInventory[ ubArmsDealer ][ sItemIndex ].ubTotalItems > gArmsDealersInventory[ ubArmsDealer ][ sItemIndex ].ubPerfectItems )
{
bElementToRemove = GetFirstValidSpecialItemFromDealer( ubArmsDealer, sItemIndex );
RemoveSpecialItemFromArmsDealerInventoryAtElement( ubArmsDealer, sItemIndex, bElementToRemove );
ubNumLeftToRemove -= 1;
}
else
{
//lower the number to the required number
RemoveItemFromArmsDealerInventory( ubArmsDealer, sItemIndex, &SpclItemInfo, ubNumLeftToRemove );
ubNumLeftToRemove = 0;
}
}
}
*/
}
#endif
+30 -6
View File
@@ -8,13 +8,18 @@
//enums for the various arms dealers
enum
{
//Ja25 None are in exp.
ARMS_DEALER_TONY,
ARMS_DEALER_FRANZ,
ARMS_DEALER_KEITH,
ARMS_DEALER_JAKE,
ARMS_DEALER_GABBY,
#ifdef JA2UB
//no UB
#else
ARMS_DEALER_DEVIN,
#endif
ARMS_DEALER_HOWARD,
ARMS_DEALER_SAM,
ARMS_DEALER_FRANK,
@@ -28,7 +33,12 @@ enum
ARMS_DEALER_ARNIE,
ARMS_DEALER_FREDO,
#ifdef JA2UB
ARMS_DEALER_RAUL,
#else
ARMS_DEALER_PERKO,
#endif
// added only in GameVersion 54
ARMS_DEALER_ELGIN,
@@ -36,6 +46,10 @@ enum
// added only in GameVersion 55
ARMS_DEALER_MANNY,
#ifdef JA2UB
ARMS_DEALER_BETTY,
#endif
NUM_ARMS_DEALERS,
};
@@ -108,8 +122,13 @@ enum
#define ARMS_DEALER_ALL_WEAPONS ARMS_DEALER_ALL_GUNS | ARMS_DEALER_BLADE | ARMS_DEALER_LAUNCHER | ARMS_DEALER_KNIFECLASS
#ifdef JA2UB
//Raul
#define ARMS_DEALER_FLAG__RAUL_HAS_SOLD_BARRETT_TO_PLAYER 0x00000001 // Raul has sold the Barrett to the player
#define ARMS_DEALER_FLAG__RAUL_SAID_QUOTE_48 0x00000002 // Raul said the quote for when the player first puts the hand cannon down
#define ARMS_DEALER_FLAG__RAUL_SAID_QUOTE_49 0x00000004 // Quote for when player removes hand cannon from players offer area
#define ARMS_DEALER_FLAG__RAUL_SAID_QUOTE_50 0x00000008 // Quote for when player adds the hand cannon AGAIN into the players offer area
#endif
@@ -193,6 +212,8 @@ public:
BOOLEAN fRepairDelayBeenUsed; // Set when a repairman has missed his repair time estimate & given his excuse for it
BOOLEAN fUnusedKnowsPlayer; // Set if the shopkeeper has met with the player before [UNUSED]
UINT32 uiTimePlayerLastInSKI; // game time (in total world minutes) when player last talked to this dealer in SKI
BOOLEAN fHasSoldSomethingToPlayer; //If set, the player has at some point sold something to the player
UINT16 ubStrayAmmo[MAXITEMS]; // partially-depleted ammo mags are stored here as #bullets, and can be converted to full packs
BOOLEAN fPreviouslyEligible[MAXITEMS]; // whether or not dealer has been eligible to sell this item in days prior to today
@@ -303,9 +324,9 @@ extern const ARMS_DEALER_INFO DefaultarmsDealerInfo[ NUM_ARMS_DEALERS ];
extern std::vector<ARMS_DEALER_INFO> armsDealerInfo;
extern ARMS_DEALER_STATUS gArmsDealerStatus[ NUM_ARMS_DEALERS ];
#ifdef JA2UB
void AddTexsVideosToBettysInventory();
#endif
void InitAllArmsDealers();
@@ -362,6 +383,9 @@ UINT16 CalcValueOfItemToDealer( UINT8 ubArmsDealer, UINT16 usItemIndex, BOOLEAN
UINT32 CalculateOvernightRepairDelay( UINT8 ubArmsDealer, UINT32 uiTimeWhenFreeToStartIt, UINT32 uiMinutesToFix );
UINT32 CalculateMinutesClosedBetween( UINT8 ubArmsDealer, UINT32 uiStartTime, UINT32 uiEndTime );
#ifdef JA2UB
extern void DailyCheckOnItemQuantities( BOOLEAN fInstallyHaveItemsAppear ); //Ja25 UB
#endif
extern void GuaranteeAtLeastXItemsOfIndex( UINT8 ubArmsDealer, UINT16 usItemIndex, UINT8 ubHowMany );
+41 -7
View File
@@ -267,7 +267,12 @@ DEALER_POSSIBLE_INV gTonyInventory[MAXITEMS+1];// =
//
// Devin ( Explosives )
//
//Betty UB
#ifdef JA2UB
DEALER_POSSIBLE_INV gBettyInventory[MAXITEMS+1];// =
#else
DEALER_POSSIBLE_INV gDevinInventory[MAXITEMS+1];// =
#endif
//{
// { STUN_GRENADE, 3 },
// { TEARGAS_GRENADE, 3 },
@@ -665,7 +670,11 @@ DEALER_POSSIBLE_INV gArnieInventory[MAXITEMS+1];// =
//
// Perko ( REPAIR)
//
#ifdef JA2UB
DEALER_POSSIBLE_INV gRaulInventory[MAXITEMS+1];
#else
DEALER_POSSIBLE_INV gPerkoInventory[MAXITEMS+1];// =
#endif
//{
// // NO INVENTORY
//
@@ -694,6 +703,13 @@ INT8 GetDealersMaxItemAmount( UINT8 ubDealerID, UINT16 usItemIndex )
{
switch( ubDealerID )
{
#ifdef JA2UB
case ARMS_DEALER_BETTY:
return( GetMaxItemAmount( gBettyInventory, usItemIndex ) );
break;
#endif
// Ja25: Not in exp.
case ARMS_DEALER_TONY:
return( GetMaxItemAmount( gTonyInventory, usItemIndex ) );
break;
@@ -709,11 +725,15 @@ INT8 GetDealersMaxItemAmount( UINT8 ubDealerID, UINT16 usItemIndex )
case ARMS_DEALER_ARNIE:
return( GetMaxItemAmount( gArnieInventory, usItemIndex ) );
break;
#ifdef JA2UB
case ARMS_DEALER_RAUL:
return( GetMaxItemAmount( gRaulInventory, usItemIndex ) ); //
break;
#else
case ARMS_DEALER_PERKO:
return( GetMaxItemAmount( gPerkoInventory, usItemIndex ) );
break;
#endif
case ARMS_DEALER_KEITH:
return( GetMaxItemAmount( gKeithInventory, usItemIndex ) );
break;
@@ -757,11 +777,13 @@ INT8 GetDealersMaxItemAmount( UINT8 ubDealerID, UINT16 usItemIndex )
case ARMS_DEALER_GABBY:
return( GetMaxItemAmount( gGabbyInventory, usItemIndex ) );
break;
#ifdef JA2UB
//no ub
#else
case ARMS_DEALER_DEVIN:
return( GetMaxItemAmount( gDevinInventory, usItemIndex ) );
break;
#endif
case ARMS_DEALER_ELGIN:
return( GetMaxItemAmount( gElginInventory, usItemIndex ) );
break;
@@ -801,6 +823,11 @@ DEALER_POSSIBLE_INV *GetPointerToDealersPossibleInventory( UINT8 ubArmsDealerID
{
switch( ubArmsDealerID )
{
#ifdef JA2UB
case ARMS_DEALER_BETTY:
return( gBettyInventory );
break;
#endif
case ARMS_DEALER_TONY:
return( gTonyInventory );
break;
@@ -817,10 +844,15 @@ DEALER_POSSIBLE_INV *GetPointerToDealersPossibleInventory( UINT8 ubArmsDealerID
return( gArnieInventory );
break;
#ifdef JA2UB
case ARMS_DEALER_RAUL:
return( gRaulInventory );
break;
#else
case ARMS_DEALER_PERKO:
return( gPerkoInventory );
break;
#endif
case ARMS_DEALER_KEITH:
return( gKeithInventory );
break;
@@ -864,11 +896,13 @@ DEALER_POSSIBLE_INV *GetPointerToDealersPossibleInventory( UINT8 ubArmsDealerID
case ARMS_DEALER_GABBY:
return( gGabbyInventory );
break;
#ifdef JA2UB
//no UB
#else
case ARMS_DEALER_DEVIN:
return( gDevinInventory );
break;
#endif
case ARMS_DEALER_ELGIN:
return( gElginInventory );
break;
+10
View File
@@ -53,7 +53,13 @@ UINT8 GetDealerItemCategoryNumber( UINT16 usItemIndex );
BOOLEAN CanDealerItemBeSoldUsed( UINT16 usItemIndex );
extern DEALER_POSSIBLE_INV gTonyInventory[MAXITEMS+1];
#ifdef JA2UB
extern DEALER_POSSIBLE_INV gBettyInventory[MAXITEMS+1];
#else //ja25 ub Biggins
extern DEALER_POSSIBLE_INV gDevinInventory[MAXITEMS+1];
#endif
extern DEALER_POSSIBLE_INV gFranzInventory[MAXITEMS+1];
extern DEALER_POSSIBLE_INV gKeithInventory[MAXITEMS+1];
extern DEALER_POSSIBLE_INV gSamInventory[MAXITEMS+1];
@@ -69,7 +75,11 @@ extern DEALER_POSSIBLE_INV gAlbertoInventory[MAXITEMS+1];
extern DEALER_POSSIBLE_INV gCarloInventory[MAXITEMS+1];
extern DEALER_POSSIBLE_INV gMickyInventory[MAXITEMS+1];
extern DEALER_POSSIBLE_INV gArnieInventory[MAXITEMS+1];
#ifdef JA2UB
extern DEALER_POSSIBLE_INV gRaulInventory[MAXITEMS+1];
#else
extern DEALER_POSSIBLE_INV gPerkoInventory[MAXITEMS+1];
#endif
extern DEALER_POSSIBLE_INV gFredoInventory[MAXITEMS+1];
#endif
+183 -5
View File
@@ -37,6 +37,17 @@
#include "Tactical Save.h"
#endif
#ifdef JA2UB
#include "Explosion Control.h"
#include "Ja25_Tactical.h"
#include "Ja25 Strategic Ai.h"
#include "MapScreen Quotes.h"
#include "email.h"
#include "interface Dialogue.h"
#include "mercs.h"
#include "ub_config.h"
#endif
#include "email.h"
@@ -1327,12 +1338,22 @@ void HandleUnhiredMercDeaths( INT32 iProfileID )
gStrategicStatus.ubUnhiredMercDeaths++;
//send an email as long as the merc is from aim
#ifdef JA2UB
//ja25 ub
if( gubQuest[ QUEST_FIX_LAPTOP ] == QUESTDONE || gGameUBOptions.LaptopQuestEnabled == FALSE )
{
if ( gProfilesAIM[ iProfileID ].ProfilId == iProfileID && gGameUBOptions.fDeadMerc == TRUE ) //new profiles by Jazz
//send an email to the player telling the player that a merc died
AddEmailWithSpecialData(206, MERC_DIED_ON_OTHER_ASSIGNMENT_LENGTH, AIM_SITE, GetWorldTotalMin(), 0, iProfileID, TYPE_EMAIL_DEAD_MERC_AIM_SITE_EMAIL_JA2_EDT, TYPE_E_AIM_L1 );
}
#else
// if( iProfileID < BIFF )
if ( gProfilesAIM[ iProfileID ].ProfilId == iProfileID ) //new profiles by Jazz
{
//send an email to the player telling the player that a merc died
AddEmailWithSpecialData(MERC_DIED_ON_OTHER_ASSIGNMENT, MERC_DIED_ON_OTHER_ASSIGNMENT_LENGTH, AIM_SITE, GetWorldTotalMin(), 0, iProfileID );
AddEmailWithSpecialData(MERC_DIED_ON_OTHER_ASSIGNMENT, MERC_DIED_ON_OTHER_ASSIGNMENT_LENGTH, AIM_SITE, GetWorldTotalMin(), 0, iProfileID, TYPE_EMAIL_EMAIL_EDT, TYPE_E_NONE );
}
#endif
}
}
@@ -1347,6 +1368,11 @@ void HandleUnhiredMercDeaths( INT32 iProfileID )
// returns a number between 0-100, this is an estimate of how far a player has progressed through the game
UINT8 CurrentPlayerProgressPercentage(void)
{
#ifdef JA2UB
INT8 bFurthestSectorPlayerOwns=-1; //JA25 UB
UINT8 ubCurrentProgress;
#else
UINT32 uiCurrentIncome;
UINT32 uiPossibleIncome;
UINT16 usCurrentProgress;
@@ -1364,8 +1390,129 @@ UINT8 CurrentPlayerProgressPercentage(void)
UINT16 usMaxIncomeProgress;
UINT16 usMaxControlProgress;
UINT16 usMaxVisitProgress;
#endif
#ifdef JA2UB
//Get the furthest sector the player owns
bFurthestSectorPlayerOwns = GetTheFurthestSectorPlayerOwns();
//JA25 UB
switch( bFurthestSectorPlayerOwns )
{
//initial sector
case SEC_H7:
ubCurrentProgress = 44;
break;
case SEC_H8:
ubCurrentProgress = 45;
break;
//guard post
case SEC_H9:
ubCurrentProgress = 55;
break;
//field
case SEC_H10:
ubCurrentProgress = 58;
break;
//field
case SEC_I9:
ubCurrentProgress = 60;
break;
//first part of town
case SEC_I10:
ubCurrentProgress = 63;
break;
//second part of town
case SEC_I11:
ubCurrentProgress = 65;
break;
//field
case SEC_I12:
ubCurrentProgress = 68;
break;
//Abondoned mine
case SEC_I13:
ubCurrentProgress = 70;
break;
// cave under abondoned mine
/* case SEC_I13_1:
ubCurrentProgress = 72;
break;
*/
//field
case SEC_J11:
ubCurrentProgress = 70;
break;
//field
case SEC_J12:
ubCurrentProgress = 70;
break;
//power gen plant
case SEC_J13:
ubCurrentProgress = 75;
break;
/*
//power gen plant, sub level
case JA25_J13_1:
ubCurrentProgress = 75;
break;
//first part of tunnel
case JA25_J14_1:
ubCurrentProgress = 80;
break;
//second part of tunnel
case JA25_K14_1:
ubCurrentProgress = 82;
break;
//ground level of complex
case JA25_K15:
ubCurrentProgress = 90;
break;
//initial sector of complex
case JA25_K15_1:
ubCurrentProgress = 85;
break;
// 2nd level down of complex
case JA25_K15_2:
ubCurrentProgress = 95;
break;
//2nd last sector
case JA25_L15_2:
ubCurrentProgress = 98;
break;
//last sector
case JA25_L15_3:
ubCurrentProgress = 100;
break;
*/
default:
// OK, use percentage complete from map...
//Assert( 0 );
//ubCurrentProgress = SectorInfo[ bFurthestSectorPlayerOwns ].ubCurrentProgressValue;
ubCurrentProgress = 50;
break;
}
return(ubCurrentProgress);
#else
if( gfEditMode )
return 0;
@@ -1510,6 +1657,8 @@ UINT8 CurrentPlayerProgressPercentage(void)
return((UINT8)usCurrentProgress);
#endif
}
UINT8 HighestPlayerProgressPercentage(void)
@@ -1534,11 +1683,14 @@ void HourlyProgressUpdate(void)
// CJC: note when progress goes above certain values for the first time
// at 35% start the Madlab quest
if ( ubCurrentProgress >= gGameExternalOptions.ubGameProgressStartMadlabQuest && gStrategicStatus.ubHighestProgress <= gGameExternalOptions.ubGameProgressStartMadlabQuest )
#ifdef JA2UB
// no UB
#else
if ( ubCurrentProgress >= gGameExternalOptions.ubGameProgressStartMadlabQuest && gStrategicStatus.ubHighestProgress < gGameExternalOptions.ubGameProgressStartMadlabQuest )
{
HandleScientistAWOLMeanwhileScene();
}
#endif
// at 50% make Mike available to the strategic AI
if ( ubCurrentProgress >= gGameExternalOptions.ubGameProgressMikeAvailable && gStrategicStatus.ubHighestProgress <= gGameExternalOptions.ubGameProgressMikeAvailable )
{
@@ -1828,9 +1980,32 @@ UINT16 TotalVisitableSurfaceSectors( void )
void MERCMercWentUpALevelSendEmail( UINT8 ubMercMercIdValue )
{
#ifdef JA2UB
//JA25 UB
#else
UINT8 ubEmailOffset = 0;
int iMsgLength = 0;
UINT8 pMerc = 0;
UINT8 iMerc = 0;
UINT8 oMerc = 0;
// Read from EmailMercAvailable.xml
if ( ReadXMLEmail == TRUE )
{
oMerc = ubMercMercIdValue;
iMerc = oMerc * 1;
if ( oMerc != 0 )
pMerc = oMerc + 1;
else
pMerc = 0;
if ( gProfilesMERC[ubMercMercIdValue].ProfilId == ubMercMercIdValue )
AddEmailTypeXML( pMerc, iMerc, iMerc, GetWorldTotalMin(), -1 , TYPE_EMAIL_MERC_LEVEL_UP);
}
else
{
// Read from Email.edt and sender (nickname) from MercProfiles.xml
// WANNE: TODO: Tex, Biggins, Stoggy and Gaston have special handling because they are the new MERC merc in 1.13
// There is no letter template in Email.edt. We have them hardcoded in the source code.
if (ubMercMercIdValue == 124 || ubMercMercIdValue == 125 || ubMercMercIdValue == 126 || ubMercMercIdValue == 127)
@@ -1866,5 +2041,8 @@ void MERCMercWentUpALevelSendEmail( UINT8 ubMercMercIdValue )
ubEmailOffset = MERC_UP_LEVEL_BIFF + MERC_UP_LEVEL_LENGTH_BIFF * ( ubMercMercIdValue );
}
AddEmail( ubEmailOffset, iMsgLength, SPECK_FROM_MERC, GetWorldTotalMin(), -1, -1);
AddEmail( ubEmailOffset, iMsgLength, SPECK_FROM_MERC, GetWorldTotalMin(), -1, -1, TYPE_EMAIL_EMAIL_EDT_NAME_MERC);
}
#endif
}
+86 -6
View File
@@ -246,7 +246,9 @@ void ShutDownQuoteBox( BOOLEAN fForce )
gCivQuoteData.iDialogueBox = -1;
gCivQuoteData.bActive = FALSE;
#ifdef JA2UB
// no UB
#else
// do we need to do anything at the end of the civ quote?
if ( gCivQuoteData.pCiv && gCivQuoteData.pCiv->aiData.bAction == AI_ACTION_OFFER_SURRENDER )
{
@@ -261,6 +263,7 @@ void ShutDownQuoteBox( BOOLEAN fForce )
ActionDone( gCivQuoteData.pCiv );
}
}
#endif
}
}
@@ -480,11 +483,17 @@ void BeginCivQuote( SOLDIERTYPE *pCiv, UINT16 ubCivQuoteID, UINT16 ubEntryID, IN
UINT16 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT16 *pubCivHintToUse, BOOLEAN fCanUseHints )
{
UINT8 ubCivType;
#ifdef JA2UB
#else
INT8 bTownId;
BOOLEAN bCivLowLoyalty = FALSE;
BOOLEAN bCivHighLoyalty = FALSE;
INT8 bCivHint;
INT8 bMineId;
#endif
BOOLEAN bCivLowLoyalty = FALSE;
BOOLEAN bCivHighLoyalty = FALSE;
BOOLEAN bMiners = FALSE;
UINT16 iCounter2;
UINT16 FileEDTQUoteID;
@@ -496,7 +505,11 @@ UINT16 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT16 *pubCivHintToUse, BOOLE
for( iCounter2 = NON_CIV_GROUP; iCounter2 < NUM_CIV_GROUPS; iCounter2++ )
{
#ifdef JA2UB
if (pCiv->ubCivilianGroup > UNNAMED_CIV_GROUP_19 && pCiv->ubCivilianGroup == iCounter2)
#else
if (pCiv->ubCivilianGroup > QUEENS_CIV_GROUP && pCiv->ubCivilianGroup == iCounter2)
#endif
{
if ( pCiv->aiData.bNeutral )
{
@@ -508,7 +521,68 @@ UINT16 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT16 *pubCivHintToUse, BOOLE
}
}
}
#ifdef JA2UB
if( ubCivType != CIV_TYPE_ENEMY )
{
//if the civ is not an enemy
if ( pCiv->aiData.bNeutral )
{
return( CIV_QUOTE__CIV_NOT_ENEMY ); //43
}
else
{
//
//the civ is an enemy
//
//if the civ can fight
if( pCiv->ubBodyType == REGMALE || pCiv->ubBodyType == REGFEMALE || pCiv->ubBodyType == BIGMALE )
{
return( CIV_QUOTE__CIV_ENEMY_CAN_FIGHT); //40
}
else if( pCiv->stats.bLife < pCiv->stats.bLifeMax )
{
return( CIV_QUOTE__CIV_HURT ); //42
}
else
{
return( CIV_QUOTE__CIV_ENEMY_GENERIC ); //41
}
}
}
if( ubCivType == CIV_TYPE_ENEMY )
{
// Determine what type of quote to say...
// Are are we going to attack?
if ( pCiv->aiData.bAction == AI_ACTION_TOSS_PROJECTILE || pCiv->aiData.bAction == AI_ACTION_FIRE_GUN ||
pCiv->aiData.bAction == AI_ACTION_FIRE_GUN || pCiv->aiData.bAction == AI_ACTION_KNIFE_MOVE )
{
return( CIV_QUOTE_ENEMY_THREAT );
}
// Hurt?
else if ( pCiv->stats.bLife < 30 )
{
return( CIV_QUOTE_ENEMY_HURT );
}
// elite?
else if ( pCiv->ubSoldierClass == SOLDIER_CLASS_ELITE )
{
return( CIV_QUOTE_ENEMY_ELITE );
}
else
{
return( CIV_QUOTE_ENEMY_ADMIN );
}
}
return( 255 );
#else
if ( ubCivType == CIV_TYPE_ENEMY )
{
// Determine what type of quote to say...
@@ -785,7 +859,7 @@ UINT16 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT16 *pubCivHintToUse, BOOLE
{
return( CIV_QUOTE_KIDS_ALL_PURPOSE );
}
#endif
}
@@ -844,7 +918,13 @@ void StartCivQuote( SOLDIERTYPE *pCiv )
}
else
RandomVal = 15;
#ifdef JA2UB
if( ubCivQuoteID == 255 )
{
return;
}
#endif
// Determine entry id
// ATE: Try and get entry from soldier pointer....
+15 -1
View File
@@ -54,9 +54,23 @@ enum
CIV_QUOTE_ENEMY_OFFER_SURRENDER,
CIV_QUOTE_HICKS_SEE_US_AT_NIGHT,
CIV_QUOTE_DEIDRANNA_DEAD,
#ifdef JA2UB
//40
CIV_QUOTE__CIV_ENEMY_CAN_FIGHT,
CIV_QUOTE__CIV_ENEMY_GENERIC,
CIV_QUOTE__CIV_HURT,
CIV_QUOTE__CIV_NOT_ENEMY,
CIV_QUOTE_44,
CIV_QUOTE_45,
CIV_QUOTE_46,
CIV_QUOTE_47,
CIV_QUOTE_48,
CIV_QUOTE_49,
CIV_QUOTE_NEW = CIV_QUOTE_DEIDRANNA_DEAD + 990, // 500 reserved
#else
CIV_QUOTE_NEW = CIV_QUOTE_DEIDRANNA_DEAD + 1000, // 500 reserved
#endif
NUM_CIV_QUOTES
};
+335 -8
View File
@@ -61,6 +61,15 @@
#include "Auto Resolve.h"
#include "connect.h"
#ifdef JA2UB
#include "Intro.h"
#include "MapScreen Quotes.h"
#include "Ja25 Strategic Ai.h"
#include "Ja25_Tactical.h"
#include "Animation Control.h"
#endif
#include "ub_config.h"
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
@@ -128,6 +137,24 @@ std::vector<UINT32> uiExternalStaticNPCFaces;
// 157,
// 158,
//};
#ifdef JA2UB
UINT32 uiExternalStaticNPCFacesUB[ NUMBER_OF_EXTERNAL_NPC_FACES ];
UINT32 uiExternalFaceProfileIdsUB[ NUMBER_OF_EXTERNAL_NPC_FACES ]=
{
97,
106,
148,
156,
157,
158,
76, //Jerry Melo
};
BOOLEAN AreAllTheMercsFinishedSayingThereInitialHeliCrashQuotes();
void InitJerriesSpeechCallBack();
void HandlePlayerClosingMorrisNoteDisplayedOnScreen();
#endif
UINT8 gubMercValidPrecedentQuoteID[ NUMBER_VALID_MERC_PRECEDENT_QUOTES ] =
{ 80, 81, 82, 83, 86, 87, 88, 95, 97, 99, 100, 101, 102 };
@@ -217,6 +244,11 @@ void HandleTacticalSpeechUI( UINT8 ubCharacterNum, INT32 iFaceIndex );
void DisplayTextForExternalNPC( UINT8 ubCharacterNum, STR16 zQuoteStr );
void CreateTalkingUI( INT8 bUIHandlerID, INT32 iFaceIndex, UINT8 ubCharacterNum, SOLDIERTYPE *pSoldier, STR16 zQuoteStr );
#ifdef JA2UB
BOOLEAN AreAllTheMercsFinishedSayingThereInitialHeliCrashQuotes();
void InitJerriesSpeechCallBack();
void HandlePlayerClosingMorrisNoteDisplayedOnScreen();
#endif
void HandleExternNPCSpeechFace( INT32 iIndex );
@@ -310,6 +342,13 @@ void InitalizeStaticExternalNPCFaces( void )
//
// Code for loading miners' faces has been moved to LuaMines::InitMinerFaces ...
//
#ifdef JA2UB
for( iCounter = 0; iCounter < NUMBER_OF_EXTERNAL_NPC_FACES; iCounter++ )
{
uiExternalStaticNPCFacesUB[ iCounter ] = ( UINT32 )InitFace( ( UINT8 )( uiExternalFaceProfileIdsUB[ iCounter ] ), NOBODY, FACE_FORCE_SMALL );
}
#endif
//for( iCounter = 0; iCounter < NUMBER_OF_EXTERNAL_NPC_FACES; iCounter++ )
//{
// uiExternalStaticNPCFaces[ iCounter ] = ( UINT32 )InitFace( ( UINT8 )( uiExternalFaceProfileIds[ iCounter ] ), NOBODY, FACE_FORCE_SMALL );
@@ -336,6 +375,14 @@ void ShutdownStaticExternalNPCFaces( void )
//{
// DeleteFace( uiExternalStaticNPCFaces[ iCounter ] );
//}
#ifdef JA2UB
for( iCounter = 0; iCounter < NUMBER_OF_EXTERNAL_NPC_FACES; iCounter++ )
{
DeleteFace( uiExternalStaticNPCFacesUB[ iCounter ] );
}
#endif
for (std::vector<UINT32>::iterator face = uiExternalStaticNPCFaces.begin();
face != uiExternalStaticNPCFaces.end(); ++face)
{
@@ -425,6 +472,9 @@ void StopAnyCurrentlyTalkingSpeech( )
{
InternalShutupaYoFace( gpCurrentTalkingFace->iID, TRUE );
}
#ifdef JA2UB
RemoveJerryMiloBrokenLaptopOverlay();
#endif
}
@@ -664,6 +714,68 @@ void HandleDialogue( )
UnPauseGame();
}
#ifdef JA2UB
if ( iQSize == 0 )
{
if( gfMorrisShouldSayHi )
{
SOLDIERTYPE * pMorris;
SOLDIERTYPE * pSoldier;
INT16 sPlayerGridNo;
UINT8 ubPlayerID;
UINT8 ubQualifiedSoldierIDArray[ NUM_MERCS_WITH_NEW_QUOTES ];
UINT8 ubNumQualifiedMercs=0;
UINT8 ubCnt=0;
if( !( gMercProfiles[ 75 ].ubMiscFlags2 & PROFILE_MISC_FLAG2_SAID_FIRSTSEEN_QUOTE ) )
{
pMorris = FindSoldierByProfileID( 75, FALSE );
if ( pMorris && pMorris->stats.bLife >= OKLIFE )
{
sPlayerGridNo = ClosestPC( pMorris, NULL );
if (sPlayerGridNo != NOWHERE )
{
ubPlayerID = WhoIsThere2( sPlayerGridNo, 0 );
if (ubPlayerID != NOBODY)
{
InitiateConversation( pMorris, MercPtrs[ ubPlayerID ], NPC_INITIAL_QUOTE, 0 );
gMercProfiles[ pMorris->ubProfile ].ubMiscFlags2 |= PROFILE_MISC_FLAG2_SAID_FIRSTSEEN_QUOTE;
}
}
}
}
else
{
//Get the # of qualified mercs
ubNumQualifiedMercs = GetNumSoldierIdAndProfileIdOfTheNewMercsOnPlayerTeam( ubQualifiedSoldierIDArray, NULL );
//if there is some qualified mercs
if( ubNumQualifiedMercs != 0 )
{
//loop through all the mercs
for( ubCnt=0; ubCnt<ubNumQualifiedMercs; ubCnt++ )
{
pSoldier = MercPtrs[ ubQualifiedSoldierIDArray[ ubCnt ] ];
TacticalCharacterDialogue( pSoldier, QUOTE_JOINING_CAUSE_LEARNED_TO_LIKE_BUDDY_ON_TEAM );
pSoldier->usQuoteSaidExtFlags |= SOLDIER_QUOTE_SAID_EXT_MORRIS;
}
}
//Morris should say a new quote
// CharacterDialogue( MORRIS, QUOTE_ATTACKED_BY_MULTIPLE_CREATURES, gTalkPanel.iFaceIndex, DIALOGUE_NPC_UI, FALSE, FALSE );
TriggerNPCRecord( 75, 2 );
gfMorrisShouldSayHi = FALSE;
}
}
return;
}
#else //Ja25: no mike
if ( iQSize == 0 )
{
@@ -694,7 +806,7 @@ void HandleDialogue( )
return;
}
#endif
// ATE: Remove any civ quotes....
// ShutDownQuoteBoxIfActive( TRUE );
@@ -807,7 +919,15 @@ void HandleDialogue( )
// Setup face pointer
gpCurrentTalkingFace = &gFacesData[ QItem->iFaceIndex ];
gubCurrentTalkingID = QItem->ubCharacterNum;
#ifdef JA2UB
//Ja25: test
if( QItem->ubCharacterNum == 75 ) //MORRIS
{
if( QItem->usQuoteNum == 0 )
{
}
}
#endif
ExecuteCharacterDialogue( QItem->ubCharacterNum, QItem->usQuoteNum, QItem->iFaceIndex, QItem->bUIHandlerID, QItem->fFromSoldier );
}
@@ -1123,6 +1243,32 @@ void HandleDialogue( )
{
SetUpdateBoxFlag( TRUE );
}
#ifdef JA2UB
else if( QItem->uiSpecialEventFlag & DIALOGUE_SPECIAL_EVENT_JERRY_MILO )
{
//switch on the quote that is being spoken
switch( QItem->uiSpecialEventData )
{
case JM_SE__SHOW_RADIO_LOCATOR:
HandleShowingRadioLocatorsInMorrisArea();
break;
case JM_SE__HEADING_TO_TRACONA:
// play the heli crash video
SetIntroType( INTRO_HELI_CRASH );
//Go to the intro screen
RequestTriggerExitFromMapscreen( MAP_EXIT_TO_INTRO_SCREEN );
break;
default:
//nothing
break;
}
}
#else //Ja25: removed the flag, no militia
else if( QItem->uiSpecialEventFlag & DIALOGUE_SPECIAL_EVENT_CONTINUE_TRAINING_MILITIA )
{
// grab soldier ptr from profile ID
@@ -1134,6 +1280,7 @@ void HandleDialogue( )
HandleInterfaceMessageForContinuingTrainingMilitia( pSoldier );
}
}
#endif
else if( QItem->uiSpecialEventFlag & DIALOGUE_SPECIAL_EVENT_ENTER_MAPSCREEN )
{
if( !(guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) )
@@ -1168,6 +1315,49 @@ void HandleDialogue( )
}
else if( QItem->uiSpecialEventFlag & DIALOGUE_SPECIAL_EVENT_MULTIPURPOSE )
{
#ifdef JA2UB
//JA25 UB
if ( QItem->uiSpecialEventData & MULTIPURPOSE_SPECIAL_EVENT_TEAM_MEMBERS_DONE_TALKING )
{
HandleEveryoneDoneTheirEndGameQuotes();
}
else
{
// grab soldier ptr from profile ID
pSoldier = FindSoldierByProfileID( (UINT8)QItem->uiSpecialEventData, FALSE );
// Now, wake these sluts up and have them say quote...
pSoldier->fIgnoreGetupFromCollapseCheck = FALSE;
//Get the soldier up
pSoldier->bCollapsed = FALSE;
pSoldier->ChangeSoldierStance( ANIM_STAND );
//if the soldier is Jerry
if( FindSoldierByProfileID( 76, FALSE ) == pSoldier ) //JERRY
{
//Play the sound of the Antena breaking
PlayJA2SampleFromFile( "SOUNDS\\Metal Antenna Crunch.wav", RATE_11025, HIGHVOLUME, 1, MIDDLE );
}
//Turn off the flag saying we are doing the initial heli crash
gfFirstTimeInGameHeliCrash = FALSE;
//if all the mercs are done their talk
if( AreAllTheMercsFinishedSayingThereInitialHeliCrashQuotes() )
{
//Trigger Jerry Milo's script record 10 ( call action 301 )
//AA
//if ( gGameUBOptions.InGameHeliCrash == TRUE )
if ( gGameUBOptions.JerryQuotes == TRUE )
DelayedMercQuote( 76 , 0xffff, 4 ); //JERRY
//End the ui Lock
guiPendingOverrideEvent = LU_ENDUILOCK;
}
}
}
#else //Ja25 No queen
if ( QItem->uiSpecialEventData & MULTIPURPOSE_SPECIAL_EVENT_DONE_KILLING_DEIDRANNA )
{
HandleDoneLastKilledQueenQuote( );
@@ -1177,6 +1367,7 @@ void HandleDialogue( )
HandleDoneLastEndGameQuote( );
}
}
#endif
else if( QItem->uiSpecialEventFlag & DIALOGUE_SPECIAL_EVENT_SLEEP )
{
// no soldier, leave now
@@ -1317,11 +1508,14 @@ BOOLEAN TacticalCharacterDialogue( SOLDIERTYPE *pSoldier, UINT16 usQuoteNum )
return( FALSE );
}
#ifdef JA2UB
//Ja25 no meanwhiles
#else
if ( AreInMeanwhile( ) )
{
return( FALSE );
}
#endif
if (pSoldier->stats.bLife < CONSCIOUSNESS )
return( FALSE );
@@ -1784,7 +1978,7 @@ CHAR8 *GetDialogueDataFilename( UINT8 ubCharacterNum, UINT16 usQuoteNum, BOOLEAN
}
//else if ( ubCharacterNum >= FIRST_RPC && ubCharacterNum < GASTON &&
//new profiles by Jazz
else if ( ( gProfilesRPC[ubCharacterNum].ProfilId == ubCharacterNum || gProfilesNPC[ubCharacterNum].ProfilId == ubCharacterNum || gProfilesVehicle[ubCharacterNum].ProfilId == ubCharacterNum ) &&
else if ( ( gProfilesRPC[ubCharacterNum].ProfilId == ubCharacterNum || gProfilesNPC[ubCharacterNum].ProfilId == ubCharacterNum ) && //|| gProfilesVehicle[ubCharacterNum].ProfilId == ubCharacterNum ) &&
( !( gMercProfiles[ ubCharacterNum ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED )
|| ProfileCurrentlyTalkingInDialoguePanel( ubCharacterNum )
|| (gMercProfiles[ ubCharacterNum ].ubMiscFlags & PROFILE_MISC_FLAG_FORCENPCQUOTE) )
@@ -1832,12 +2026,32 @@ CHAR8 *GetDialogueDataFilename( UINT8 ubCharacterNum, UINT16 usQuoteNum, BOOLEAN
//new profiles by Jazz
if ( ( gProfilesRPC[ubCharacterNum].ProfilId == ubCharacterNum || gProfilesNPC[ubCharacterNum].ProfilId == ubCharacterNum || gProfilesVehicle[ubCharacterNum].ProfilId == ubCharacterNum ) && gMercProfiles[ ubCharacterNum ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED )
{
if ( gSoundProfileValue[ubCharacterNum].EnabledSound == TRUE )
{
sprintf( zFileName,"SPEECH\\r_%03d_%03d.ogg",ubCharacterNum,usQuoteNum );
//inshy: fix for UB-1.13 version only sprintf( zFileName,"SPEECH\\r_%03d_%03d.ogg",ubCharacterNum,usQuoteNum );
if ( gSoundProfileValue[ubCharacterNum].EnabledSound == TRUE )
{
//#ifdef JA2UB
sprintf( zFileName,"SPEECH\\%03d_%03d.ogg",ubCharacterNum,usQuoteNum );
if ( !FileExists( zFileName ) )
{
sprintf( zFileName,"SPEECH\\r_%03d_%03d.wav",ubCharacterNum,usQuoteNum );
sprintf( zFileName,"SPEECH\\%03d_%03d.ogg",ubCharacterNum,usQuoteNum );
}
//#else
// sprintf( zFileName,"SPEECH\\r_%03d_%03d.ogg",ubCharacterNum,usQuoteNum );
//#endif
if ( !FileExists( zFileName ) )
{
//inshy: fix for UB-1.13 version only sprintf( zFileName,"SPEECH\\r_%03d_%03d.wav",ubCharacterNum,usQuoteNum );
//#ifdef JA2UB
sprintf( zFileName,"SPEECH\\%03d_%03d.wav",ubCharacterNum,usQuoteNum );
if ( !FileExists( zFileName ) )
{
sprintf( zFileName,"SPEECH\\%03d_%03d.wav",ubCharacterNum,usQuoteNum );
}
//#else
// sprintf( zFileName,"SPEECH\\r_%03d_%03d.wav",ubCharacterNum,usQuoteNum );
//#endif
//<SB> Also check for Russian Gold sound files (identical to international ones)
if(! FileExists( zFileName ) )
{
@@ -2511,6 +2725,10 @@ void SayQuoteFromAnyBodyInSector( UINT16 usQuoteNum )
{
if ( gTacticalStatus.bNumFoughtInBattle[ ENEMY_TEAM ] == 0 )
{
#ifdef JA2UB
//Ja25 No Ira, Miguel etc.
#else
// quotes referring to Deidranna's men so we skip quote if there were no army guys fought
if ( (usQuoteNum == QUOTE_SECTOR_SAFE) && (pTeamSoldier->ubProfile == IRA || pTeamSoldier->ubProfile == MIGUEL || pTeamSoldier->ubProfile == SHANK ) )
{
@@ -2521,6 +2739,7 @@ void SayQuoteFromAnyBodyInSector( UINT16 usQuoteNum )
{
continue;
}
#endif
}
ubMercsInSector[ ubNumMercs ] = (UINT8)cnt;
@@ -2720,6 +2939,21 @@ void TextOverlayClickCallback( MOUSE_REGION * pRegion, INT32 iReason )
ShutDownLastQuoteTacticalTextBox( );
}
}
#ifdef JA2UB
//JA25 UB
//if we are in the heli crash sequence
else if( gJa25SaveStruct.fJerryBreakingLaptopOccuring )
{
InitJerriesSpeechCallBack();
}
//else the Commander morris note is being displayed
else if( gJa25SaveStruct.ubDisplayCommanderMorrisNote != DMN__NOT_TO_DISPLAY_IT ||
gJa25SaveStruct.ubDisplayCommanderMorrisNote != DMN__FINISHED )
{
HandlePlayerClosingMorrisNoteDisplayedOnScreen();
}
#endif
}
else if (iReason & MSYS_CALLBACK_REASON_LOST_MOUSE )
{
@@ -2981,3 +3215,96 @@ void SetExternMapscreenSpeechPanelXY( INT16 sXPos, INT16 sYPos )
gsExternPanelXPosition = sXPos;
gsExternPanelYPosition = sYPos;
}
#ifdef JA2UB
//JA25 UB
BOOLEAN AreAllTheMercsFinishedSayingThereInitialHeliCrashQuotes()
{
INT32 cnt;
SOLDIERTYPE *pSoldier;
// IF IT'S THE SELECTED GUY, MAKE ANOTHER SELECTED!
cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;
// look for all mercs on the same team,
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; cnt++,pSoldier++)
{
//if the merc is alive, in sector, etc...
if ( OK_CONTROLLABLE_MERC( pSoldier ) )
{
//if the merc is still not done the initial speech, and still prone
if( pSoldier->fIgnoreGetupFromCollapseCheck )
{
//we arent done
return( FALSE );
}
}
}
//See if Jerry is still waiting to get up
pSoldier = FindSoldierByProfileID( 76, FALSE );
if( pSoldier )
{
//if the merc is still not done the initial speech, and still prone
if( pSoldier->fIgnoreGetupFromCollapseCheck )
{
//we arent done
return( FALSE );
}
}
//all mercs on the team are done
return( TRUE );
}
void InitJerriesSpeechCallBack()
{
//Trigger Jerry Milo's script record 10 ( call action 301 )
TriggerNPCRecord( 76, 10 );
//Clear the overlay
RemoveJerryMiloBrokenLaptopOverlay();
}
void RemoveJerryMiloBrokenLaptopOverlay()
{
//if the overlay is up
if( gJa25SaveStruct.fJerryBreakingLaptopOccuring )
{
gJa25SaveStruct.fJerryBreakingLaptopOccuring = FALSE;
RemoveVideoOverlay( giTextBoxOverlay );
giTextBoxOverlay = -1;
if( fTextBoxMouseRegionCreated )
{
MSYS_RemoveRegion( &gTextBoxMouseRegion );
fTextBoxMouseRegionCreated = FALSE;
}
}
}
void HandlePlayerClosingMorrisNoteDisplayedOnScreen()
{
RemoveVideoOverlay( giTextBoxOverlay );
giTextBoxOverlay = -1;
if ( fTextBoxMouseRegionCreated )
{
MSYS_RemoveRegion( &gTextBoxMouseRegion );
fTextBoxMouseRegionCreated = FALSE;
}
if( gJa25SaveStruct.ubDisplayCommanderMorrisNote == DMN__DISPLAY_PART_2 )
{
gJa25SaveStruct.ubDisplayCommanderMorrisNote = DMN__FINISHED;
HandleShowingRadioLocatorsInMorrisArea();
}
else
{
DelayedMercQuote( gJa25SaveStruct.bNewMercProfileIDForSayingMorrisNote, DQ__MORRIS_NOTE_DISPLAY_NOTE_1, GetWorldTotalSeconds() + 1 );
}
}
#endif
+29
View File
@@ -163,6 +163,10 @@ enum DialogQuoteIDs
QUOTE_PERSONALITY_BIAS_WITH_MERC_2,
QUOTE_MERC_LEAVING_ALSUCO_SOON,
QUOTE_MERC_GONE_UP_IN_PRICE,
#ifdef JA2UB
QUOTE_ENTER_SECTOR_WITH_FAN_1,
QUOTE_ENTER_SECTOR_WITH_FAN_2,
#endif
@@ -194,7 +198,13 @@ enum DialogQuoteIDs
#define DIALOGUE_SPECIAL_EVENT_SHOW_UPDATE_MENU 0x00000400
#define DIALOGUE_SPECIAL_EVENT_ENABLE_AI 0x00000800
#define DIALOGUE_SPECIAL_EVENT_USE_ALTERNATE_FILES 0x00001000
#ifdef JA2UB
#define DIALOGUE_SPECIAL_EVENT_JERRY_MILO 0x00002000
#else
#define DIALOGUE_SPECIAL_EVENT_CONTINUE_TRAINING_MILITIA 0x00002000
#endif
#define DIALOGUE_SPECIAL_EVENT_CONTRACT_ENDING 0x00004000
#define DIALOGUE_SPECIAL_EVENT_MULTIPURPOSE 0x00008000
#define DIALOGUE_SPECIAL_EVENT_SLEEP 0x00010000
@@ -214,9 +224,20 @@ enum DialogQuoteIDs
#define DIALOGUE_SPECIAL_EVENT_CONTRACT_NOGO_TO_RENEW 0x40000000
#define DIALOGUE_SPECIAL_EVENT_CONTRACT_ENDING_NO_ASK_EQUIP 0x80000000
#ifdef JA2UB
#define MULTIPURPOSE_SPECIAL_EVENT_TEAM_MEMBERS_DONE_TALKING 0x20000000
#define MULTIPURPOSE_SPECIAL_EVENT_DONE_KILLING_DEIDRANNA 0x10000000
#else
#define MULTIPURPOSE_SPECIAL_EVENT_DONE_KILLING_DEIDRANNA 0x00000001
#define MULTIPURPOSE_SPECIAL_EVENT_TEAM_MEMBERS_DONE_TALKING 0x00000002
#endif
#ifdef JA2UB
enum{
JERRY_MELO_FACE = 6,
NUMBER_OF_EXTERNAL_NPC_FACES,
};
#endif
enum{
SKYRIDER_EXTERNAL_FACE =0,
@@ -236,6 +257,11 @@ enum{
UPDATE_BOX_REASON_SHOW_BOX,
};
#ifdef JA2UB
extern UINT32 uiExternalStaticNPCFacesUB[ ];
extern UINT32 uiExternalFaceProfileIdsUB[ ];
#endif
//extern UINT32 uiExternalStaticNPCFaces[ ];
extern std::vector<UINT32> uiExternalStaticNPCFaces;
//extern UINT32 uiExternalFaceProfileIds[ ];
@@ -358,5 +384,8 @@ void UnPauseDialogueQueue( void );
void SetExternMapscreenSpeechPanelXY( INT16 sXPos, INT16 sYPos );
#ifdef JA2UB
void RemoveJerryMiloBrokenLaptopOverlay();
#endif
#endif
+272 -4
View File
@@ -44,6 +44,23 @@
#include "screenids.h"
#endif
#ifdef JA2UB
#include "email.h"
#include "Game Clock.h"
#include "Ja25_Tactical.h"
#include "Game Init.h"
#include "interface Dialogue.h"
#include "ub_config.h"
void HandleAddingTheEndGameEmails();
void EndFadeToCredits( void );
void FadeToCredits( void );
void InFinalSectorAfterFadeIn( void );
void FadeOutToLaptopOnEndGame( void );
BOOLEAN gfPlayersLaptopWasntWorkingAtEndOfGame;
#endif
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
@@ -136,7 +153,9 @@ void ChangeO3SectorStatue( BOOLEAN fFromExplosion )
RecompileLocalMovementCostsFromRadius( 13830, 5 );
}
#ifdef JA2UB
//Ja25 no queen
#else
void DeidrannaTimerCallback( void )
{
HandleDeidrannaDeath( gpKillerSoldier, gsGridNo, gbLevel );
@@ -384,12 +403,15 @@ void DoneFadeOutEndCinematic( void )
SetIntroType( INTRO_ENDING );
}
#endif
// OK, end death UI - fade to smaker....
void HandleDoneLastEndGameQuote( )
{
EndQueenDeathEndgame( );
#ifdef JA2UB
//Ja25 No queen
#else
EndQueenDeathEndgame( );
#endif
gFadeOutDoneCallback = DoneFadeOutEndCinematic;
FadeOutGameScreen( );
@@ -399,9 +421,213 @@ void HandleDoneLastEndGameQuote( )
void QueenBitchTimerCallback( void )
{
#ifdef JA2UB
//no Ub
#else
HandleQueenBitchDeath( gpKillerSoldier, gsGridNo, gbLevel );
#endif
}
#ifdef JA2UB
void EndGameEveryoneSayTheirGoodByQuotes( void )
{
INT32 cnt;
SOLDIERTYPE *pSoldier;
// Start end cimimatic....
gTacticalStatus.uiFlags |= IN_ENDGAME_SEQUENCE;
//lock the interface
guiPendingOverrideEvent = LU_BEGINUILOCK;
HandleTacticalUI( );
//
// first thing is to loop through team and look for QUALIFIED mercs on the team to say special end game quote
//
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++)
{
// Are we in this sector, On the current squad?
if( pSoldier->bActive && pSoldier->stats.bLife >= OKLIFE && !AM_AN_EPC( pSoldier ) && IsSoldierQualifiedMerc( pSoldier ) )
{
TacticalCharacterDialogue( pSoldier, QUOTE_RENEWING_CAUSE_BUDDY_2_ON_TEAM );
}
}
//
// Next is to loop through ENTIRE team and say end quote...
//
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++)
{
// Are we in this sector, On the current squad?
if ( pSoldier->bActive && pSoldier->stats.bLife >= OKLIFE && !AM_AN_EPC( pSoldier ) )
{
TacticalCharacterDialogue( pSoldier, QUOTE_END_GAME_COMMENT );
}
}
// Add queue event to proceed w/ smacker cimimatic
SpecialCharacterDialogueEvent( DIALOGUE_SPECIAL_EVENT_MULTIPURPOSE, MULTIPURPOSE_SPECIAL_EVENT_TEAM_MEMBERS_DONE_TALKING, 0,0,0,0 );
}
void HandleAddingTheEndGameEmails()
{
BOOLEAN fMiguelAlive=FALSE;
BOOLEAN fManuelAlive=FALSE;
BOOLEAN fManuelHired=FALSE;
//Miguel alive
if( gubFact[ FACT_PLAYER_IMPORTED_SAVE_MIGUEL_DEAD ] )
fMiguelAlive = FALSE;
else
fMiguelAlive = TRUE;
//manuel alive
if( gMercProfiles[ 60 ].bMercStatus == MERC_IS_DEAD )
fManuelAlive = FALSE;
else
fManuelAlive = TRUE;
//manuel hired
if( gMercProfiles[ 60 ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED )
fManuelHired = TRUE;
else
fManuelHired = FALSE;
//
// Determine the EMAIL to be sent out to the player
//
// email # 12a - Miguel dead, Manuel never recruited
if( !fMiguelAlive && !fManuelHired )
{
AddEmail( EMAIL_CONGRATS, EMAIL_CONGRATS_LENGTH, MAIL_ENRICO, GetWorldTotalMin(),-1 ,-1, TYPE_EMAIL_EMAIL_EDT);
}
// email # 12b - Miguel alive, Manuel never recruited
else if( fMiguelAlive && !fManuelHired )
{
AddEmail( EMAIL_CONGRATSICK, EMAIL_CONGRATSICK_LENGTH, MAIL_ENRICO, GetWorldTotalMin(),-1 ,-1, TYPE_EMAIL_EMAIL_EDT);
}
// email # 12c - Miguel alive, Manuel dead
else if( fMiguelAlive && !fManuelAlive )
{
AddEmail( EMAIL_CONGRATMIGMANUELDEAD, EMAIL_CONGRATMIGMANUELDEAD_LENGTH, MAIL_ENRICO, GetWorldTotalMin() , -1, -1, TYPE_EMAIL_EMAIL_EDT);
}
// email # 12d - Miguel alive, Manuel recruited and alive
else if( fMiguelAlive && fManuelAlive && fManuelHired )
{
AddEmail( EMAIL_CONGRATMIGMANUELALIVE, EMAIL_CONGRATMIGMANUELALIVE_LENGTH, MAIL_ENRICO, GetWorldTotalMin() , -1, -1, TYPE_EMAIL_EMAIL_EDT);
}
// email # 12e - Miguel dead, Manuel dead
else if( !fMiguelAlive && !fManuelAlive )
{
AddEmail( EMAIL_CONGRATMANUELDEAD, EMAIL_CONGRATMANUELDEAD_LENGTH, MAIL_ENRICO, GetWorldTotalMin(), -1 , -1, TYPE_EMAIL_EMAIL_EDT);
}
// email # 12f - Miguel dead, Manuel recruited and alive
else if( !fMiguelAlive && fManuelAlive && fManuelHired )
{
AddEmail( EMAIL_CONGRATMANUELALIVE, EMAIL_CONGRATMANUELALIVE_LENGTH, MAIL_ENRICO, GetWorldTotalMin() , -1, -1, TYPE_EMAIL_EMAIL_EDT);
}
else
{
Assert( 0 );
}
}
void HandleEveryoneDoneTheirEndGameQuotes()
{
// UnLock UI!
guiPendingOverrideEvent = LU_ENDUILOCK;
HandleTacticalUI( );
//if laptop is still BROKEN
if( gubQuest[ QUEST_FIX_LAPTOP ] == QUESTINPROGRESS && gGameUBOptions.LaptopQuestEnabled == TRUE )
{
gfPlayersLaptopWasntWorkingAtEndOfGame = TRUE;
// otherwise, go to the credits screen
HandleJa25EndGameAndGoToCreditsScreen( TRUE );
}
else
{
gfPlayersLaptopWasntWorkingAtEndOfGame = FALSE;
gFadeOutDoneCallback = FadeOutToLaptopOnEndGame;
FadeOutGameScreen( );
}
}
void HandleJa25EndGameAndGoToCreditsScreen( BOOLEAN fFromTactical )
{
if( fFromTactical )
{
FadeToCredits( );
}
else
{
//Reset flag indicating we are in the end game sequence
gTacticalStatus.uiFlags &= ~IN_ENDGAME_SEQUENCE;
//We want to reinitialize the game
ReStartingGame();
}
}
void EnterTacticalInFinalSector()
{
gFadeInDoneCallback = InFinalSectorAfterFadeIn;
FadeInGameScreen( );
}
void InFinalSectorAfterFadeIn( void )
{
//Have everyone start talking
DelayedMercQuote( NOBODY, DQ__START_EVERYONE_TALKING_AT_END_OF_GAME, GetWorldTotalSeconds() + 2 );
}
void FadeToCredits( void )
{
gFadeOutDoneCallback = EndFadeToCredits;
FadeOutGameScreen( );
}
void EndFadeToCredits( void )
{
//then we can go strait to the laptop screen
InternalLeaveTacticalScreen( CREDIT_SCREEN );
//Reset flag indicating we are in the end game sequence
gTacticalStatus.uiFlags &= ~IN_ENDGAME_SEQUENCE;
//We want to reinitialize the game
ReStartingGame();
}
void FadeOutToLaptopOnEndGame( void )
{
//then we can go strait to the laptop screen
InternalLeaveTacticalScreen( LAPTOP_SCREEN );
//Add the end Game Emails
HandleAddingTheEndGameEmails();
}
#else //Ja25 no queen
void BeginHandleQueenBitchDeath( SOLDIERTYPE *pKillerSoldier, INT32 sGridNo, INT8 bLevel )
{
@@ -500,5 +726,47 @@ void HandleQueenBitchDeath( SOLDIERTYPE *pKillerSoldier, INT32 sGridNo, INT8 bLe
giNPCReferenceCount = 0;
}
}
#endif
#ifdef JA2UB
//JA25UB
void DoneFadeOutEndCinematic( void )
{
INT32 cnt;
SOLDIERTYPE *pSoldier;
//Change the currently selecter sector in mapscreen
//ChangeSelectedMapSector( 16, 11, 0 );
ChangeSelectedMapSector( gGameUBOptions.ubEndDefaultSectorX, gGameUBOptions.ubEndDefaultSectorY, gGameUBOptions.ubEndDefaultSectorZ );
//
// Loop through all the soldiers and move any of them that are in the complex to be in the safe sector near ther
//
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++)
{
// if the soldier was in the complex
if( pSoldier->bActive &&
pSoldier->sSectorX == 15 && ( pSoldier->sSectorY == 11 || pSoldier->sSectorY == 12 ) )
{
if ( GetGroup( pSoldier->ubGroupID ) )
{
//move them to the 'fake' sector
//PlaceGroupInSector( pSoldier->ubGroupID, 15, 11, 16, 11, 0, FALSE );
PlaceGroupInSector( pSoldier->ubGroupID, 15, 11, gGameUBOptions.ubEndDefaultSectorX, gGameUBOptions.ubEndDefaultSectorY, gGameUBOptions.ubEndDefaultSectorZ, FALSE );
}
else
{
pSoldier->sSectorX = gGameUBOptions.ubEndDefaultSectorX; //16;
pSoldier->sSectorY = gGameUBOptions.ubEndDefaultSectorY; //11;
pSoldier->bSectorZ = gGameUBOptions.ubEndDefaultSectorZ; //0;
}
}
}
//
// Go watch the movies
//
InternalLeaveTacticalScreen( INTRO_SCREEN );
SetIntroType( INTRO_ENDING );
}
#endif
+12 -6
View File
@@ -5,18 +5,24 @@
BOOLEAN DoesO3SectorStatueExistHere( INT32 sGridNo );
void ChangeO3SectorStatue( BOOLEAN fFromExplosion );
void HandleDoneLastKilledQueenQuote( );
void HandleDoneLastEndGameQuote( );
#ifdef JA2UB
void DoneFadeOutEndCinematic( void );
void HandleJa25EndGameAndGoToCreditsScreen( BOOLEAN fFromTactical );
void HandleEveryoneDoneTheirEndGameQuotes();
void EndGameEveryoneSayTheirGoodByQuotes( void );
void EnterTacticalInFinalSector();
extern BOOLEAN gfPlayersLaptopWasntWorkingAtEndOfGame;
#else
void HandleDeidrannaDeath( SOLDIERTYPE *pKillerSoldier, INT32 sGridNo, INT8 bLevel );
void BeginHandleDeidrannaDeath( SOLDIERTYPE *pKillerSoldier, INT32 sGridNo, INT8 bLevel );
void HandleDoneLastKilledQueenQuote( );
void EndQueenDeathEndgameBeginEndCimenatic( );
void EndQueenDeathEndgame( );
void HandleQueenBitchDeath( SOLDIERTYPE *pKillerSoldier, INT32 sGridNo, INT8 bLevel );
void BeginHandleQueenBitchDeath( SOLDIERTYPE *pKillerSoldier, INT32 sGridNo, INT8 bLevel );
void HandleDoneLastEndGameQuote( );
#endif
#endif
+51 -1
View File
@@ -214,6 +214,27 @@ INT32 InternalInitFace( UINT8 usMercProfileID, UINT8 ubSoldierID, UINT32 uiInitF
sprintf( VObjectDesc.ImageFile, "FACES\\b%02de.sti", iFaceFileID );
}
}
#ifdef JA2UB
else if ( usMercProfileID == 64 )
{
// SANDRO - old/new traits check (I am not sure if this is used at all)
if ( gGameOptions.fNewTraitSystem )
{
if ( ProfileHasSkillTrait( 64, RANGER_NT ) > 0 )
{
sprintf( VObjectDesc.ImageFile, "FACES\\B64c.sti" );
}
}
else
{
if ( ProfileHasSkillTrait( 64, CAMOUFLAGED_OT ) > 0 )
{
sprintf( VObjectDesc.ImageFile, "FACES\\B64c.sti" );
}
}
}
#else
else if ( usMercProfileID == TEX )
{
// SANDRO - old/new traits check (I am not sure if this is used at all)
@@ -232,6 +253,7 @@ INT32 InternalInitFace( UINT8 usMercProfileID, UINT8 ubSoldierID, UINT32 uiInitF
}
}
}
#endif
}
else
{
@@ -496,6 +518,31 @@ void GetFaceRelativeCoordinates( FACETYPE *pFace, UINT16 *pusEyesX, UINT16 *pusE
usEyesY = gMercProfiles[ usMercProfileID ].usEyesY;
usMouthY = gMercProfiles[ usMercProfileID ].usMouthY;
usMouthX = gMercProfiles[ usMercProfileID ].usMouthX;
#ifdef JA2UB
if ( gGameOptions.fNewTraitSystem )
{
if( usMercProfileID == 64 && ( gMercProfiles[ 64 ].bSkillTraits[0] == RANGER_NT || gMercProfiles[ 64 ].bSkillTraits[1] == RANGER_NT ) )
{
usEyesX = 13;
usEyesY = 34;
usMouthX = 13;
usMouthY = 55;
}
}
else
{
if( usMercProfileID == 64 && ( gMercProfiles[ 64 ].bSkillTraits[0] == CAMOUFLAGED_OT || gMercProfiles[ 64 ].bSkillTraits[1] == CAMOUFLAGED_OT ) )
{
usEyesX = 13;
usEyesY = 34;
usMouthX = 13;
usMouthY = 55;
}
}
#endif
// Use some other values for x,y, base on if we are a RPC!
if ( !( pFace->uiFlags & FACE_BIGFACE ) ||( pFace->uiFlags & FACE_FORCE_SMALL ))
@@ -2834,11 +2881,14 @@ BOOLEAN SetFaceTalking( INT32 iFaceIndex, CHAR8 *zSoundFile, STR16 zTextString,
pFace->fAnimatingTalking = TRUE;
pFace->fFinishTalking = FALSE;
#ifdef JA2UB
//Ja25: No Meanwhiles
#else
if ( !AreInMeanwhile( ) )
{
TurnOnSectorLocator( pFace->ubCharacterNum );
}
#endif
// Play sample
if( gGameSettings.fOptions[ TOPTION_SPEECH ] )
pFace->uiSoundID = PlayJA2GapSample( zSoundFile, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN, &(pFace->GapList ) );
+106 -3
View File
@@ -39,11 +39,26 @@
#include "fresh_header.h"
#include "connect.h"
#ifdef JA2UB
#include "Explosion Control.h"
#include "Ja25_Tactical.h"
#include "Ja25 Strategic Ai.h"
#include "MapScreen Quotes.h"
#include "email.h"
#include "interface Dialogue.h"
#include "mercs.h"
#include "ub_config.h"
#endif
BOOLEAN gfSetPerceivedDoorState = FALSE;
BOOLEAN HandleDoorsOpenClose( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE * pStructure, BOOLEAN fNoAnimations );
#ifdef JA2UB
void HandleForceingTheTunnelGate( UINT32 sGridNo ); //Ja25 UB
#endif
void HandleDoorChangeFromGridNo( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fNoAnimations )
{
STRUCTURE * pStructure;
@@ -601,7 +616,12 @@ BOOLEAN HandleOpenableStruct( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE *p
{
// it's locked....
pSoldier->ChangeSoldierState( GetAnimStateForInteraction( pSoldier, fDoor, END_OPEN_LOCKED_DOOR ), 0, FALSE );
#ifdef JA2UB
//JA25 UB
//If this is the tunnel sector, and the merc failed opening the fence door, play a quote
HandlePlayerSayingQuoteWhenFailingToOpenGateInTunnel( pSoldier, FALSE );
#endif
// Do we have a quote for locked stuff?
// Now just show on message bar
if ( !AM_AN_EPC( pSoldier ) )
@@ -622,7 +642,49 @@ BOOLEAN HandleOpenableStruct( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE *p
break;
}
break;
#ifdef JA2UB
case HANDLE_DOOR_FORCE:
// Set costs for these
sAPCost = GetAPsToOpenDoor( pSoldier ); // SANDRO
sBPCost = APBPConstants[BP_BOOT_DOOR];
// OK, using force, if we have no lock, just open the door!
if ( pDoor == NULL )
{
pSoldier->ChangeSoldierState( GetAnimStateForInteraction( pSoldier, fDoor, END_OPEN_DOOR ), 0, FALSE );
fHandleDoor = TRUE;
ScreenMsg( MSG_FONT_YELLOW, MSG_INTERFACE, TacticalStr[ DOOR_THERE_IS_NO_LOCK_STR ] );
}
else
{
//JA25 UB
//If this is the tunnel sector, and the merc failed opening the fence door, play a quote
if( HandlePlayerSayingQuoteWhenFailingToOpenGateInTunnel( pSoldier, TRUE ) )
{
}
else
{
// Attempt to force door
if ( AttemptToSmashDoor( pSoldier, pDoor ) )
{
//ScreenMsg( MSG_FONT_YELLOW, MSG_INTERFACE, TacticalStr[ DOOR_LOCK_DESTROYED_STR ] );
// pSoldier->DoMercBattleSound( BATTLE_SOUND_COOL1 );
fHandleDoor = TRUE;
}
else
{
//ScreenMsg( MSG_FONT_YELLOW, MSG_INTERFACE, TacticalStr[ DOOR_LOCK_NOT_DESTROYED_STR ] );
UpdateDoorPerceivedValue( pDoor );
}
ProcessImplicationsOfPCMessingWithDoor( pSoldier );
}
}
//Handle Special code for the gate in the tunnel
HandleForceingTheTunnelGate( sGridNo ); //JA25 UB
break;
#else
case HANDLE_DOOR_FORCE:
// Set costs for these
@@ -654,7 +716,7 @@ BOOLEAN HandleOpenableStruct( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE *p
ProcessImplicationsOfPCMessingWithDoor( pSoldier );
}
break;
#endif
case HANDLE_DOOR_CROWBAR:
@@ -738,7 +800,11 @@ BOOLEAN HandleOpenableStruct( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE *p
}
else
{
//ScreenMsg( MSG_FONT_YELLOW, MSG_INTERFACE, TacticalStr[ DOOR_LOCK_HAS_NOT_BEEN_PICKED_STR ] );
#ifdef JA2UB
//If this is the tunnel sector, and the merc failed opening the fence door, play a quote
HandlePlayerSayingQuoteWhenFailingToOpenGateInTunnel( pSoldier, FALSE );
#endif //ScreenMsg( MSG_FONT_YELLOW, MSG_INTERFACE, TacticalStr[ DOOR_LOCK_HAS_NOT_BEEN_PICKED_STR ] );
}
ProcessImplicationsOfPCMessingWithDoor( pSoldier );
}
@@ -761,6 +827,10 @@ BOOLEAN HandleOpenableStruct( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE *p
}
else
{
#ifdef JA2UB
//If this is the tunnel sector, and the merc failed opening the fence door, play a quote
HandlePlayerSayingQuoteWhenFailingToOpenGateInTunnel( pSoldier, FALSE ); //JA25 UB
#endif
if ( ExamineDoorForTraps( pSoldier, pDoor ) )
{
// We have a trap. Use door pointer to determine what type, etc
@@ -824,11 +894,23 @@ BOOLEAN HandleOpenableStruct( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE *p
// Now just show on message bar
//ScreenMsg( MSG_FONT_YELLOW, MSG_INTERFACE, TacticalStr[ DOOR_NOT_PROPER_KEY_STR ], pSoldier->name );
#ifdef JA2UB
//If this is the tunnel sector, and the merc failed opening the fence door, play a quote
if( HandlePlayerSayingQuoteWhenFailingToOpenGateInTunnel( pSoldier, FALSE ) ) //JA25 UB
{
// OK PLay damn battle sound
if ( Random( 2 ) )
{
pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 );
}
}
#else
// OK PLay damn battle sound
if ( Random( 2 ) )
{
pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 );
}
#endif
}
}
break;
@@ -1487,3 +1569,24 @@ void SetDoorString( INT32 sGridNo )
}
}
#ifdef JA2UB
//Ja25 UB
void HandleForceingTheTunnelGate( UINT32 sGridNo )
{
//if this isnt the Last sector of the tunnel
if( !( gWorldSectorX == 14 && gWorldSectorY == MAP_ROW_K && gbWorldSectorZ == 1 ) )
{
return;
}
//if it is not the right gridno
if( sGridNo != 4742 )
{
return;
}
//If the player blew up the fan, then the enemies can hear it in the tunnel and prepare for it.
gJa25SaveStruct.uiJa25GeneralFlags |= JA_GF__DID_PLAYER_MAKE_SOUND_GOING_THROUGH_TUNNEL_GATE;
}
#endif
+21 -7
View File
@@ -66,6 +66,11 @@
#include "Morale.h"
#endif
#ifdef JA2UB
#include "Ja25_Tactical.h"
#include "Ja25 Strategic Ai.h"
#endif
#define NUM_ITEMS_LISTED 8
#define NUM_ITEM_FLASH_SLOTS 50
#define MIN_LOB_RANGE 6
@@ -1799,7 +1804,9 @@ void SoldierGetItemFromWorld( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT32 sGr
BOOLEAN fShouldSayCoolQuote = FALSE;
BOOLEAN fDidSayCoolQuote = FALSE;
BOOLEAN fSaidBoobyTrapQuote = FALSE;
#ifdef JA2UB
UINT16 usItem=0;
#endif
// OK. CHECK IF WE ARE DOING ALL IN THIS POOL....
if ( iItemIndex == ITEM_PICKUP_ACTION_ALL || iItemIndex == ITEM_PICKUP_SELECTION )
{
@@ -2003,7 +2010,15 @@ void SoldierGetItemFromWorld( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT32 sGr
}
}
}
#ifdef JA2UB
//JA25 ub
//if the item is valid
if( usItem != 0 )
{
//handle the picking up of a new ja25 gun
HandleNewGunComment( pSoldier, usItem, TRUE );
}
#endif
// Aknowledge....
if( pSoldier->bTeam == OUR_TEAM && !fDidSayCoolQuote && !fSaidBoobyTrapQuote )
{
@@ -4639,7 +4654,7 @@ void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue )
{
// SANDRO was here, AP_DISARM_MINE changed to GetAPsToDisarmMine
if(EnoughPoints(gpBoobyTrapSoldier, GetAPsToDisarmMine( gpBoobyTrapSoldier ), APBPConstants[BP_DISARM_MINE], TRUE))
DeductPoints(gpBoobyTrapSoldier, GetAPsToDisarmMine( gpBoobyTrapSoldier ), APBPConstants[BP_DISARM_MINE]);
DeductPoints(gpBoobyTrapSoldier, GetAPsToDisarmMine( gpBoobyTrapSoldier ), APBPConstants[BP_DISARM_MINE], AFTERACTION_INTERRUPT);
else
return;
}
@@ -5719,9 +5734,7 @@ void SoldierStealItemFromSoldier( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent,
if ( gGameExternalOptions.fEnhancedCloseCombatSystem )
{
if (pSoldier->bActionPoints >= GetBasicAPsToPickupItem( pSoldier ) )
{
DeductPoints( pSoldier, GetBasicAPsToPickupItem( pSoldier ), 0 );
{
// Make copy of item
gTempObject = pOpponent->inv[pTempItemPool->iItemIndex];
if ( ItemIsCool( &gTempObject ) )
@@ -5737,7 +5750,8 @@ void SoldierStealItemFromSoldier( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent,
// add to merc records
if ( pSoldier->ubProfile != NO_PROFILE )
gMercProfiles[ pSoldier->ubProfile ].records.usItemsStolen++;
DeductPoints( pSoldier, GetBasicAPsToPickupItem( pSoldier ), 0, AFTERACTION_INTERRUPT );
}
else
{
+30 -6
View File
@@ -97,6 +97,8 @@
#endif
#include "teamturns.h"
#include "Options Screen.h"
#include "SaveLoadScreen.h"
//////////////////////////////////////////////////////////////////////////////
// SANDRO - In this file, all APBPConstants[AP_CROUCH] and APBPConstants[AP_PRONE] were changed to GetAPsCrouch() and GetAPsProne()
@@ -1225,6 +1227,8 @@ UINT32 UIHandleEnterPalEditMode( UI_EVENT *pUIEvent )
UINT32 UIHandleEndTurn( UI_EVENT *pUIEvent )
{
CHAR16 zString[128];
// CANCEL FROM PLANNING MODE!
if ( InUIPlanMode( ) )
{
@@ -1248,9 +1252,15 @@ UINT32 UIHandleEndTurn( UI_EVENT *pUIEvent )
//if( FileExists( "..\\AutoSave.pls" ) && CanGameBeSaved() )
if (gGameSettings.fOptions[TOPTION_USE_AUTO_SAVE] == TRUE && CanGameBeSaved() )
{
//Save the game
guiPreviousOptionScreen = guiCurrentScreen;
SaveGame( SAVE__END_TURN_NUM, L"End Turn Auto Save" );
//increment end turn number
guiLastSaveGameNum++;
if( guiLastSaveGameNum == 2 )
guiLastSaveGameNum = 0;
swprintf( zString, L"%s%d",pMessageStrings[ MSG_SAVE_END_TURN_SAVE_TEXT ], guiLastSaveGameNum + 1);
SaveGame(SAVE__END_TURN_NUM, zString );
}
////ddd îïòèìèçàöèÿ äëÿ õîäà äðàíèêîâ
@@ -1687,7 +1697,7 @@ UINT32 UIHandleMovementMenu( UI_EVENT *pUIEvent )
{
case MOVEMENT_MENU_RUN:
if ( pSoldier->usUIMovementMode != WALKING && pSoldier->usUIMovementMode != RUNNING )
if ( pSoldier->usUIMovementMode != WALKING && pSoldier->usUIMovementMode != RUNNING && pSoldier->usUIMovementMode != WALKING_PISTOL_RDY && pSoldier->usUIMovementMode != WALKING_RIFLE_RDY && pSoldier->usUIMovementMode != WALKING_DUAL_RDY )
{
UIHandleSoldierStanceChange( pSoldier->ubID, ANIM_STAND );
pSoldier->flags.fUIMovementFast = 1;
@@ -3869,6 +3879,9 @@ BOOLEAN HandleUIMovementCursor( SOLDIERTYPE *pSoldier, UINT32 uiCursorFlags, INT
switch ( pSoldier->usUIMovementMode )
{
case WALKING:
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
gUIDisplayActionPointsOffY = 10;
gUIDisplayActionPointsOffX = 10;
@@ -4632,6 +4645,9 @@ void SetMovementModeCursor( SOLDIERTYPE *pSoldier )
switch ( pSoldier->usUIMovementMode )
{
case WALKING:
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
guiNewUICursor = MOVE_WALK_UICURSOR;
break;
@@ -4692,6 +4708,9 @@ void SetConfirmMovementModeCursor( SOLDIERTYPE *pSoldier, BOOLEAN fFromMove )
switch ( pSoldier->usUIMovementMode )
{
case WALKING:
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
guiNewUICursor = ALL_MOVE_WALK_UICURSOR;
break;
@@ -4721,6 +4740,9 @@ void SetConfirmMovementModeCursor( SOLDIERTYPE *pSoldier, BOOLEAN fFromMove )
switch ( pSoldier->usUIMovementMode )
{
case WALKING:
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
guiNewUICursor = CONFIRM_MOVE_WALK_UICURSOR;
break;
@@ -4946,7 +4968,7 @@ BOOLEAN MakeSoldierTurn( SOLDIERTYPE *pSoldier, INT16 sXPos, INT16 sYPos )
// Setting "Last Target"
pSoldier->sLastTarget = sXPos + (MAXCOL * sYPos);
DeductPoints( pSoldier, sAPCost, 0 );
DeductPoints( pSoldier, sAPCost, 0, AFTERACTION_INTERRUPT );
return( TRUE );
}
@@ -5938,12 +5960,14 @@ BOOLEAN HandleTalkInit( )
ubQuoteNum = QUOTE_NEGATIVE_COMPANY;
break;
}
#ifdef JA2UB
// ja25 UB
#else
if ( pTSoldier->ubProfile == IRA )
{
ubQuoteNum = QUOTE_PASSING_DISLIKE;
}
#endif
TacticalCharacterDialogue( pTSoldier, ubQuoteNum );
return( FALSE );
+53 -24
View File
@@ -52,6 +52,13 @@
#include "GameSettings.h"
#endif
#include "connect.h"
#include "Text.h"
#ifdef JA2UB
#include "Dialogue Control.h"
#endif
/* I deleted here declaration of clock coords for tactical screen i will declare them
* in functions that Initialize coord for SMPanet and TEAMPanel
* any questions? joker
@@ -726,38 +733,57 @@ void RenderTopmostTacticalInterface( )
GetSoldierScreenPos( pSoldier, &sMercScreenX, &sMercScreenY );
GetSoldierAnimOffsets( pSoldier, &sOffsetX, &sOffsetY );
if ( pSoldier->ubBodyType == QUEENMONSTER )
{
sDamageX = sMercScreenX + pSoldier->sDamageX - pSoldier->sBoundingBoxOffsetX;
sDamageY = sMercScreenY + pSoldier->sDamageY - pSoldier->sBoundingBoxOffsetY;
if ( pSoldier->ubBodyType == QUEENMONSTER )
{
sDamageX = sMercScreenX + pSoldier->sDamageX - pSoldier->sBoundingBoxOffsetX;
sDamageY = sMercScreenY + pSoldier->sDamageY - pSoldier->sBoundingBoxOffsetY;
sDamageX += 25;
sDamageY += 10;
}
else
{
sDamageX = pSoldier->sDamageX + (INT16)(sMercScreenX + ( 2 * 30 / 3 ) );
sDamageY = pSoldier->sDamageY + (INT16)(sMercScreenY - 5 );
sDamageX += 25;
sDamageY += 10;
}
else
{
sDamageX = pSoldier->sDamageX + (INT16)(sMercScreenX + ( 2 * 30 / 3 ) );
sDamageY = pSoldier->sDamageY + (INT16)(sMercScreenY - 5 );
sDamageX -= sOffsetX;
sDamageY -= sOffsetY;
sDamageX -= sOffsetX;
sDamageY -= sOffsetY;
if ( sDamageY < gsVIEWPORT_WINDOW_START_Y )
{
sDamageY = ( sMercScreenY - sOffsetY );
}
}
SetFont( TINYFONT1 );
if ( sDamageY < gsVIEWPORT_WINDOW_START_Y )
{
sDamageY = ( sMercScreenY - sOffsetY );
}
}
SetFont( TINYFONT1 );
SetFontBackground( FONT_MCOLOR_BLACK );
SetFontForeground( FONT_MCOLOR_WHITE );
gprintfdirty( sDamageX, sDamageY, L"-%d", pSoldier->sDamage );
mprintf( sDamageX, sDamageY, L"-%d", pSoldier->sDamage );
bool showDamage = true;
if (gGameExternalOptions.ubEnemyHitCount > 0 && pSoldier->bTeam == ENEMY_TEAM || pSoldier->bTeam == CREATURE_TEAM)
showDamage = false;
if (showDamage)
{
gprintfdirty( sDamageX, sDamageY, L"-%d", pSoldier->sDamage );
mprintf( sDamageX, sDamageY, L"-%d", pSoldier->sDamage );
}
else
{
if (gGameExternalOptions.ubEnemyHitCount == 1)
{
gprintfdirty( sDamageX, sDamageY, L"%s", gzHiddenHitCountStr[0]);
mprintf( sDamageX, sDamageY, L"%s", gzHiddenHitCountStr[0]);
}
else
{
gprintfdirty( sDamageX, sDamageY, L"");
mprintf( sDamageX, sDamageY, L"");
}
}
}
}
}
}
if ( gusSelectedSoldier != NOBODY )
@@ -1017,6 +1043,9 @@ void EraseInterfaceMenus( BOOLEAN fIgnoreUIUnLock )
PopDownMovementMenu( );
PopDownOpenDoorMenu( );
DeleteTalkingMenu( );
#ifdef JA2UB
RemoveJerryMiloBrokenLaptopOverlay();
#endif
}
+723 -1
View File
@@ -81,6 +81,23 @@
#include "Overhead.h"
#endif
#include "LuaInitNPCs.h"
#include "Text.h"
#include "Luaglobal.h"
#ifdef JA2UB
#include "Explosion Control.h"
#include "Ja25_Tactical.h"
#include "Ja25 Strategic Ai.h"
#include "MapScreen Quotes.h"
#include "email.h"
#include "Soldier macros.h"
#include "LOS.h"
#include "Soldier Control.h"
#include "Ja25Update.h"
#endif
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
@@ -167,6 +184,29 @@ extern void EndGameMessageBoxCallBack( UINT8 ubExitValue );
extern INT32 FindNearestOpenableNonDoor( INT32 sStartGridNo );
extern void RecalculateOppCntsDueToBecomingNeutral( SOLDIERTYPE * pSoldier );
#ifdef JA2UB
//JA25 UB
void PerformJerryMiloAction301();
void PerformJerryMiloAction302();
void DelayedMercQuote( UINT16 usProfileID, UINT32 uiQuoteNum, UINT32 uiTimeTillQuoteSaid );
void DelayedSayingOfMercQuote( UINT32 uiParam );
void HandleSpecificQuoteWhenLeavingNpcTalkMenu();
void HaveQualifiedMercSayQuoteAboutNpcWhenLeavingTalkScreen( UINT8 ubNpcProfileID, UINT32 uiQuoteNum );
void CheckForValidQuotesWhenLeavingDealer( UINT8 ubProfile );
BOOLEAN IsMineEntranceInSectorI13AtThisGridNo( UINT32 sGridNo );
void HaveBiggensDetonatingExplosivesByTheMine();
void ReplaceMineEntranceGraphicWithCollapsedEntrance();
void HandleCannotAffordNpcMsgBox();
void CantAffordMercCallback( UINT8 ubExitValue );
void HandleMercArrivesQuotesFromHeliCrashSequence();
void HandleRaulBlowingHimselfUp();
void HandleTexFlushingToilet();
void HandleTexMakingHimselfAlreadyBeIntroduced();
void DisplayJerryBreakingLaptopTransmitterPopup();
void HaveNpcOpenUpDealerScreen( UINT8 ubProfileID );
void HandleTexBecomingCamoed();
#endif
UINT8 ubTalkMenuApproachIDs[] =
{
APPROACH_REPEAT,
@@ -212,6 +252,11 @@ INT32 giHospitalTempBalance; // stores amount of money for current doctoring
INT32 giHospitalRefund; // stores amount of money given to hospital for doctoring that wasn't used
INT8 gbHospitalPriceModifier; // stores discount being offered
#ifdef JA2UB
//ja25 ub
BOOLEAN gfDisplayMsgBoxSayingCantAffordNPC=FALSE;
#endif
enum
{
HOSPITAL_UNSET = 0,
@@ -1677,6 +1722,13 @@ void HandleNPCClosePanel( )
void HandleStuffForNPCEscorted( UINT8 ubNPC )
{
#ifdef LUA_INTERFACE_DIALOGUE
LetLuaInterfaceDialogue(ubNPC,0);
#else
SOLDIERTYPE * pSoldier;
switch( ubNPC )
@@ -1723,6 +1775,8 @@ void HandleStuffForNPCEscorted( UINT8 ubNPC )
}
break;
}
#endif
}
void HandleFactForNPCUnescorted( UINT8 ubNPC )
@@ -4044,13 +4098,22 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
{
// This is not the end, 'cause momma creature is still alive
TriggerNPCRecordImmediately( 136, 8 );
#ifdef JA2UB
//no Ub
#else
EndQueenDeathEndgame( );
#endif
}
else
{
// Continue with endgame cimematic..
DeleteTalkingMenu( );
#ifdef JA2UB
//no Ub
#else
EndQueenDeathEndgameBeginEndCimenatic( );
#endif
}
break;
@@ -4058,7 +4121,11 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
// Just end queen killed dequence.......
DeleteTalkingMenu( );
#ifdef JA2UB
// no UB
#else
EndQueenDeathEndgame( );
#endif
break;
case NPC_ACTION_MAKE_ESTONI_A_FUEL_SITE:
@@ -4308,10 +4375,51 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
TriggerNPCRecord( WALTER, 15 );
}
break;
#ifdef JA2UB
//JA25 UB
case NPC_ACTION_TRIGGER_JERRY_CONVERSATION_WITH_PGC_1:
PerformJerryMiloAction301();
break;
case NPC_ACTION_TRIGGER_JERRY_CONVERSATION_WITH_PGC_2:
PerformJerryMiloAction302();
break;
case NPC_ACTION_BIGGENS_DETONATES_BOMBS:
HaveBiggensDetonatingExplosivesByTheMine();
break;
case NPC_ACTION_LEAVING_NPC_TALK_MENU:
HandleSpecificQuoteWhenLeavingNpcTalkMenu();
break;
case NPC_ACTION_RAUL_BLOWS_HIMSELF_UP:
HandleRaulBlowingHimselfUp();
break;
case NPC_ACTION_TEX_FLUSHES_TOILET:
HandleTexFlushingToilet();
break;
case NPC_ACTION_MARK_TEX_AS_ALREADY_INTRODUCED_HIMSELF:
HandleTexMakingHimselfAlreadyBeIntroduced();
break;
case NPC_ACTION_MAKE_TEX_CAMOED:
HandleTexBecomingCamoed();
break;
case NPC_ACTION_HAVE_DEALER_OPEN_BUY_SELL_SCREEN:
HaveNpcOpenUpDealerScreen( ubTargetNPC );
break;
#endif
default:
ScreenMsg( FONT_MCOLOR_RED, MSG_TESTVERSION, L"No code support for NPC action %d", usActionCode );
break;
}
//Lua
// LuaHandleNPCDoAction( ubTargetNPC, usActionCode, ubQuoteNum , 0);
}
}
@@ -4554,6 +4662,36 @@ void DialogueMessageBoxCallBack( UINT8 ubExitValue )
break;
case NPC_ACTION_ASK_ABOUT_PAYING_RPC:
case NPC_ACTION_ASK_ABOUT_PAYING_RPC_WITH_DAILY_SALARY:
#ifdef JA2UB
if ( ubExitValue == MSG_BOX_RETURN_YES )
{
//if the player cannot afford to hire the npc
if( LaptopSaveInfo.iCurrentBalance < gMercProfiles[ubProfile].sSalary )
{
//Set a flag indicating that you cannot afford the merc
gfDisplayMsgBoxSayingCantAffordNPC = TRUE;
}
else
{
//First Deduct the money out of the players account
AddTransactionToPlayersBook( PAYMENT_TO_NPC, ubProfile, GetWorldTotalMin(), -gMercProfiles[ubProfile].sSalary );
TriggerNPCRecord( ubProfile, 1 );
//if the person is BIGGENS
if( ubProfile == 61 ) //BIGGENS
{
SetFactTrue( FACT_BIGGENS_IS_ON_TEAM );
}
}
}
else
{
TriggerNPCRecord( ubProfile, 0 );
}
#else
if ( ubExitValue == MSG_BOX_RETURN_YES )
{
TriggerNPCRecord( ubProfile, 1 );
@@ -4562,6 +4700,7 @@ void DialogueMessageBoxCallBack( UINT8 ubExitValue )
{
TriggerNPCRecord( ubProfile, 0 );
}
#endif
break;
case NPC_ACTION_REDUCE_CONRAD_SALARY_CONDITIONS:
if ( ubExitValue == MSG_BOX_RETURN_YES )
@@ -4971,6 +5110,12 @@ void TextRegionClickCallback( MOUSE_REGION * pRegion, INT32 iReason )
void CarmenLeavesSectorCallback( void )
{
#ifdef LUA_INTERFACE_DIALOGUE
LetLuaInterfaceDialogue(0,0);
#else
if (gWorldSectorX == 13 && gWorldSectorY == MAP_ROW_C && gbWorldSectorZ == 0)
{
TriggerNPCRecord( 78, 34 );
@@ -4983,5 +5128,582 @@ void CarmenLeavesSectorCallback( void )
{
TriggerNPCRecord( 78, 36 );
}
#endif
}
#ifdef JA2UB
//JA25 UB
void PerformJerryMiloAction301()
{
UINT8 ubMercsPresent[NUM_MERCS_WITH_NEW_QUOTES];
INT8 bNumMercsPresent=-1;
SOLDIERTYPE *pSoldier=NULL;
INT32 cnt;
UINT8 ubId;
//Get the number and array of the new soldiers
bNumMercsPresent = GetNumSoldierIdAndProfileIdOfTheNewMercsOnPlayerTeam( ubMercsPresent, NULL );
//Randomly choose one
/* //if there is at least 1 of the desired mercs found
if( bNumMercsPresent != -1 )
{
ubId = ubMercsPresent[ Random( bNumMercsPresent ) ];
pSoldier = MercPtrs[ ubId ];
TacticalCharacterDialogue( pSoldier, QUOTE_DEATH_RATE_REFUSAL );
}
*/
//Have them all say their quote
for( cnt=0; cnt<bNumMercsPresent; cnt++ )
{
ubId = ubMercsPresent[ cnt ];
pSoldier = MercPtrs[ ubId ];
TacticalCharacterDialogue( pSoldier, QUOTE_DEATH_RATE_REFUSAL );
}
//Trigger Jerry Milo's script record 11 ( call action 302 )
TriggerNPCRecord( 76, 11 );
//Close the dialogue panel
DeleteTalkingMenu();
}
void PerformJerryMiloAction302()
{
UINT8 ubMercsPresent[NUM_MERCS_WITH_NEW_QUOTES];
INT8 bNumMercsPresent=-1;
SOLDIERTYPE *pSoldier=NULL;
UINT8 ubId;
//off jazz
//Get the number and array of the new soldiers
bNumMercsPresent = GetNumSoldierIdAndProfileIdOfTheNewMercsOnPlayerTeam( ubMercsPresent, NULL );
//Randomly choose one
//if there is at least 1 of the desired mercs found
if( bNumMercsPresent != 0 )
{
UINT8 ubProfileID = NO_PROFILE;
UINT8 ubIdOfMercWhoSaidQuote;
ubIdOfMercWhoSaidQuote = Random( bNumMercsPresent );
ubId = ubMercsPresent[ ubIdOfMercWhoSaidQuote ];
pSoldier = MercPtrs[ ubId ];
TacticalCharacterDialogue( pSoldier, QUOTE_LAME_REFUSAL );
if( bNumMercsPresent == 1 )
ubProfileID = MercPtrs[ ubId ]->ubProfile;
else
{
BOOLEAN fDone=FALSE;
while( !fDone )
{
ubProfileID = Random( bNumMercsPresent );
if( ubProfileID != ubIdOfMercWhoSaidQuote )
{
ubId = ubMercsPresent[ ubProfileID ];
fDone = TRUE;
}
}
ubProfileID = MercPtrs[ ubId ]->ubProfile;
}
//Say the quote in 15 seconds
DelayedMercQuote( ubProfileID, QUOTE_DEPARTING_COMMENT_CONTRACT_NOT_RENEWED_OR_48_OR_MORE, GetWorldTotalSeconds( ) + 15 );
}
//handle the merc arrives quotes now
HandleMercArrivesQuotesFromHeliCrashSequence();
//Set the fact that we should show the destination dialog
gJa25SaveStruct.fShowMercDestinationDialogWhenHiringMerc = TRUE;
//Close the dialogue panel
DeleteTalkingMenu();
}
void DelayedMercQuote( UINT16 usProfileID, UINT32 uiQuoteNum, UINT32 uiTimeTillQuoteSaid )
{
UINT32 uiParam;
uiParam = usProfileID + ( uiQuoteNum << 16 );
AddStrategicEventUsingSeconds( EVENT_SAY_DELAYED_MERC_QUOTE, uiTimeTillQuoteSaid, uiParam );
}
void DelayedSayingOfMercQuote( UINT32 uiParam )
{
SOLDIERTYPE *pSoldier=NULL;
UINT16 usProfileID;
UINT16 usQuoteNum;
usProfileID = 0x0000FFFF & uiParam;
usQuoteNum = uiParam >> 16;
//if its a normal quote
if( usQuoteNum < DQ__NORMAL_DELAYED_QUOTE )
{
//Get the soldier that should say the quote
pSoldier = FindSoldierByProfileID( (UINT8)usProfileID, FALSE );
if( pSoldier == NULL )
return;
//
// Do Quote specific code here
//
if( usQuoteNum == QUOTE_DEPARTING_COMMENT_CONTRACT_NOT_RENEWED_OR_48_OR_MORE )
{
//if the soldier is saying the 'brr its cold' quote, and he has left the sector
if( pSoldier->sSectorX != JA2_5_START_SECTOR_X || pSoldier->sSectorY != JA2_5_START_SECTOR_Y && pSoldier->bSectorZ != 0 )
{
//dont say the quote
return;
}
}
//Say the quote
TacticalCharacterDialogue( pSoldier, usQuoteNum );
}
else
{
switch( usQuoteNum )
{
case DQ__JERRY_BROKE_TRANSMITTER:
//Display the popup saying Jerry broke the transmitter
DisplayJerryBreakingLaptopTransmitterPopup();
break;
case DQ__MORRIS_NOTE_NEW_MERC_DELAY:
HandleCommanderMorrisNewMercWantsNoteDelayedSpeech();
break;
case DQ__MORRIS_NOTE_DISPLAY_NOTE_1:
case DQ__MORRIS_NOTE_DISPLAY_NOTE_2:
{
//Get the soldier that should say the quote
pSoldier = FindSoldierByProfileID( (UINT8)usProfileID, FALSE );
if( pSoldier == NULL )
return;
DisplayCommanderMorrisNote( pSoldier );
}
break;
case DQ__SHOW_RADIO_LOCATOR:
BeginMultiPurposeLocator( usProfileID, 0, TRUE );
break;
case DQ__NEW_MERC_SAY_NOTE_QUOTES:
//Get the soldier that should say the quote
pSoldier = FindSoldierByProfileID( (UINT8)usProfileID, FALSE );
if( pSoldier == NULL )
return;
HandleNewMercSayingContentsOfMorrisNote( pSoldier );
break;
case DQ__START_EVERYONE_TALKING_AT_END_OF_GAME:
EndGameEveryoneSayTheirGoodByQuotes();
break;
case DQ__FADE_OUT_TO_END_GAME_CINEMATIC:
HandleFadingOutToEndGameCinematics();
break;
}
}
}
void HandleSpecificQuoteWhenLeavingNpcTalkMenu()
{
SetFactTrue( FACT_MERC_SAY_QUOTE_WHEN_TALK_MENU_CLOSES );
}
void HaveQualifiedMercSayQuoteAboutNpcWhenLeavingTalkScreen( UINT8 ubNpcProfileID, UINT32 uiQuoteNum )
{
INT8 bNumMercsPresent=-1;
UINT8 SoldierIdArray[NUM_MERCS_WITH_NEW_QUOTES];
UINT8 ValidSoldierIdArray[NUM_MERCS_WITH_NEW_QUOTES] = {0};
UINT8 ubNumValidSoldiers=0;
UINT8 ubCnt;
SOLDIERTYPE *pSoldier=NULL;
SOLDIERTYPE * pNPC;
pNPC = FindSoldierByProfileID( ubNpcProfileID, FALSE );
if( pNPC == NULL )
{
return;
}
//Get the number and array of the new soldiers
bNumMercsPresent = GetNumSoldierIdAndProfileIdOfTheNewMercsOnPlayerTeam( SoldierIdArray, NULL );
//if the player doesnt have any qualified players on the team
if( bNumMercsPresent == -1 )
{
return;
}
//loop through the mercs and see if there in range of the dealer
for( ubCnt=0; ubCnt<bNumMercsPresent; ubCnt++)
{
pSoldier = &Menptr[ SoldierIdArray[ ubCnt ] ];
// Add guy if he's a candidate...
if ( OK_INSECTOR_MERC( pSoldier ) && PythSpacesAway( pNPC->sGridNo, pSoldier->sGridNo ) < 10 && !AM_AN_EPC( pSoldier ) && !( pSoldier->flags.uiStatusFlags & SOLDIER_GASSED ) && !(AM_A_ROBOT( pSoldier )) && !pSoldier->flags.fMercAsleep &&
SoldierTo3DLocationLineOfSightTest( pSoldier, pNPC->sGridNo, 0, 0, (UINT8)MaxDistanceVisible(), TRUE ) )
{
ValidSoldierIdArray[ ubNumValidSoldiers ] = pSoldier->ubID;
ubNumValidSoldiers++;
}
}
//If there is a valid merc, pick a merc to say the quote
if( ubNumValidSoldiers > 0 )
{
UINT8 ubChosenMerc = (UINT8)Random( ubNumValidSoldiers );
TacticalCharacterDialogue( MercPtrs[ ValidSoldierIdArray[ ubChosenMerc ] ], (UINT16)uiQuoteNum );
}
SetFactFalse( FACT_MERC_SAY_QUOTE_WHEN_TALK_MENU_CLOSES );
}
void CheckForValidQuotesWhenLeavingDealer( UINT8 ubProfile )
{
//if the user is going to the dealer
if( gTalkPanel.bCurSelect != -1 && ubTalkMenuApproachIDs[ gTalkPanel.bCurSelect ] == APPROACH_BUYSELL )
{
return;
}
//if their scripting event going on, leave
if( gTacticalStatus.uiFlags & ENGAGED_IN_CONV )
{
return;
}
if( CheckFact( FACT_MERC_SAY_QUOTE_WHEN_TALK_MENU_CLOSES, 0 ) )
{
switch( ubProfile )
{
case 73 : //BETTY:
HaveQualifiedMercSayQuoteAboutNpcWhenLeavingTalkScreen( ubProfile, QUOTE_JOINING_CAUSE_BUDDY_1_ON_TEAM );
break;
case 74 : //RAUL:
//if the Raul is about to blow himself up
if( !IsJa25GeneralFlagSet( JA_GF__RAUL_BLOW_HIMSELF_UP ) )
{
//we can say the quote
HaveQualifiedMercSayQuoteAboutNpcWhenLeavingTalkScreen( ubProfile, QUOTE_JOINING_CAUSE_BUDDY_2_ON_TEAM );
}
break;
case 77: //RUDY:
HaveQualifiedMercSayQuoteAboutNpcWhenLeavingTalkScreen( ubProfile, QUOTE_REFUSAL_RENEW_DUE_TO_MORALE );
break;
default:
AssertMsg( 0, "Code has not been implemented to handle saying a quote when leaving this NPC" );
}
}
}
// This function checks if we should replace the mine entrance graphic
BOOLEAN IsMineEntranceInSectorI13AtThisGridNo( UINT32 sGridNo )
{
// First check current sector......
if( gWorldSectorX == 13 && gWorldSectorY == MAP_ROW_I && gbWorldSectorZ == 0 )
{
//if this is the right gridno
if( sGridNo == 12421 )
{
return( TRUE );
}
}
return( FALSE );
}
void HaveBiggensDetonatingExplosivesByTheMine()
{
SOLDIERTYPE *pSoldier = NULL;
UINT8 ubID=NOBODY;
pSoldier = FindSoldierByProfileID( 61 , FALSE ); //BIGGENS
if( pSoldier != NULL )
{
ubID = pSoldier->ubID;
}
//Have Biggens Triger the bombs by the cave wall
SetOffBombsByFrequency( ubID, FIRST_MAP_PLACED_FREQUENCY + 1 );
}
void ReplaceMineEntranceGraphicWithCollapsedEntrance()
{
UINT16 usTileIndex;
UINT32 usGridNo=12745;
//Make sure wed ont blow things up twice
//off
if( gJa25SaveStruct.fBiggensUsedDetonator )
return;
//Remeber that biggens detonated the explosives
gJa25SaveStruct.fBiggensUsedDetonator = TRUE;
// Turn on permenant changes....
ApplyMapChangesToMapTempFile( TRUE );
// Remove it!
// Get index for it...
GetTileIndexFromTypeSubIndex( FIRSTOSTRUCT, (INT8)( 1 ), &usTileIndex );
AddStructToHead( usGridNo, usTileIndex );
//remove the exit grid from the world
RemoveExitGridFromWorld( 12422 );
RemoveExitGridFromWorld( 12423 );
AddRemoveExitGridToUnloadedMapTempFile( 12422, 13, MAP_ROW_I, 0 );
AddRemoveExitGridToUnloadedMapTempFile( 12423, 13, MAP_ROW_I, 0 );
gpWorldLevelData[ usGridNo ].uiFlags |= MAPELEMENT_REVEALED;
// Re-render the world!
gTacticalStatus.uiFlags |= NOHIDE_REDUNDENCY;
// FOR THE NEXT RENDER LOOP, RE-EVALUATE REDUNDENT TILES
InvalidateWorldRedundency( );
SetRenderFlags(RENDER_FLAG_FULL);
// Redo movement costs....
RecompileLocalMovementCostsFromRadius( usGridNo, 5 );
//
// Apply changes to the underground mine
//
//Remove the old tunnel pieces first
//First half of entrance
usGridNo = 13057;
// Get index for it...
GetTileIndexFromTypeSubIndex( FIRSTDECORATIONS, (INT8)( 1 ), &usTileIndex );
RemoveStructFromUnLoadedMapTempFile( usGridNo, usTileIndex, 13, MAP_ROW_I, 1 );
// Get index for it...
GetTileIndexFromTypeSubIndex( FIRSTDECORATIONS, (INT8)( 5 ), &usTileIndex );
//Apply changes
AddStructToUnLoadedMapTempFile( usGridNo, usTileIndex, 13, MAP_ROW_I, 1 );
// 2nd half of entrance
usGridNo = 12897;
// Get index for it...
GetTileIndexFromTypeSubIndex( FIRSTDECORATIONS, (INT8)( 2 ), &usTileIndex );
RemoveStructFromUnLoadedMapTempFile( usGridNo, usTileIndex, 13, MAP_ROW_I, 1 );
// Get index for it...
GetTileIndexFromTypeSubIndex( FIRSTDECORATIONS, (INT8)( 6 ), &usTileIndex );
//Apply changes
AddStructToUnLoadedMapTempFile( usGridNo, usTileIndex, 13, MAP_ROW_I, 1 );
//Remove the exit grid
AddRemoveExitGridToUnloadedMapTempFile( usGridNo, 13, MAP_ROW_I, 1 );
// Turn off permenant changes....
ApplyMapChangesToMapTempFile( FALSE );
}
void HandleCannotAffordNpcMsgBox()
{
// CHAR16 zString[512];
if( !gfDisplayMsgBoxSayingCantAffordNPC )
{
return;
}
//display a msg box saying cant afford merc
// swprintf( zString, zNewTacticalMessages[ TACT_MSG__CANNOT_AFFORD_MERC ], gMercProfiles[ 61 ].zNickname ); //BIGGENS
// DoMessageBox( MSG_BOX_BASIC_STYLE, zString, GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_OK, CantAffordMercCallback, NULL );
gfDisplayMsgBoxSayingCantAffordNPC = FALSE;
}
void CantAffordMercCallback( UINT8 ubExitValue )
{
//Make the RPC say a quote
TriggerNPCRecord( 61, 0 ); //BIGGENS
}
void HandleMercArrivesQuotesFromHeliCrashSequence()
{
UINT32 uiCnt;
SOLDIERTYPE *pSoldier=NULL;
uiCnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
// look for all mercs on the same team,
for ( pSoldier = MercPtrs[ uiCnt ]; uiCnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; uiCnt++,pSoldier++)
{
if ( pSoldier->bActive && pSoldier->stats.bLife >= OKLIFE && pSoldier->bInSector )
{
HandleMercArrivesQuotes( pSoldier );
}
}
}
void HandleRaulBlowingHimselfUp()
{
SOLDIERTYPE *pSoldier=NULL;
UINT16 usItem=0;
//Find Raul
pSoldier = FindSoldierByProfileID( 74, FALSE );
//if he exists
if( pSoldier )
{
//First lower his life, artificially
pSoldier->stats.bLife = 5;
//blow himself up with, hmmm, lets say TNT. :)
usItem = HAND_GRENADE;
IgniteExplosion( 74, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, usItem, pSoldier->pathing.bLevel );
SetJa25GeneralFlag( JA_GF__RAUL_BLOW_HIMSELF_UP );
}
}
void HandleTexFlushingToilet()
{
PlayJA2SampleFromFile( "SOUNDS\\ToiletFlush.wav", RATE_11025, HIGHVOLUME, 1, MIDDLE );
}
void HandleTexMakingHimselfAlreadyBeIntroduced()
{
gMercProfiles[ 64 ].ubLastDateSpokenTo = GetWorldDay( );
}
void HandleTexBecomingCamoed()
{
SOLDIERTYPE *pSoldier=NULL;
//Find TEX
pSoldier = FindSoldierByProfileID( 64, FALSE );
//if we found him
if( pSoldier != NULL )
{
//make him camoed
pSoldier->bCamo = 100;
pSoldier->CreateSoldierPalettes( );
}
//Then set him to be camo'ed in the profile ( cause he is still an RPC and we are just about to hire him )
// SANDRO - old/new traits check (I am not sure if this is used at all)
if ( gGameOptions.fNewTraitSystem )
{
gMercProfiles[ 64 ].bSkillTraits[0] = RANGER_NT;
}
else
{
gMercProfiles[ 64 ].bSkillTraits[0] = CAMOUFLAGED_OT;
}
//Close down the talking menu...
DeleteTalkingMenu( );
// InitTalkingMenu( pSoldier->ubProfile, pSoldier->sGridNo );
// Trigger Tex to say the quote, this will cause the radio locater to come up giving a pause to make it appear that he
// put on camoflauge
TriggerNPCRecord( 64, 15 );
}
void DisplayJerryBreakingLaptopTransmitterPopup()
{
CHAR16 zString[512];
INT8 bID=-1;
UINT32 uiStartLoc=0;
#define LANGMESSAGEFILE "BinaryData\\TacticalMessages.EDT"
#define EDT_SIZE 400 * 2
if( gJa25SaveStruct.fJerryBreakingLaptopOccuring )
{
return;
}
//get a random ID for a mercs name
bID = RandomSoldierIdForAnyMercInSector();
if( bID == -1 )
{
//Assert( 0 );
return;
}
/*
if ( FileExists(LANGMESSAGEFILE) )
{
uiStartLoc = EDT_SIZE * 10;
LoadEncryptedDataFromFile(LANGMESSAGEFILE, sText, uiStartLoc, EDT_SIZE);
swprintf( zString, sText, Menptr[ bID ].name );
}
else
{
//Create the string
swprintf( zString, zNewTacticalMessages[ TCTL_MSG__JERRY_BREAKIN_LAPTOP_ANTENA ], Menptr[ bID ].name );
}
*/
#ifdef UBMODSHADYJOB //See file builddefines.h
swprintf( zString, XMLTacticalMessages[0] ); //Shady Job
#else
swprintf( zString, zNewTacticalMessages[TCTL_MSG__JERRY_BREAKIN_LAPTOP_ANTENA], Menptr[ bID ].name ); //UB
#endif
//Display it
ExecuteTacticalTextBox( 110, zString );
gJa25SaveStruct.fJerryBreakingLaptopOccuring = TRUE;
}
void HaveNpcOpenUpDealerScreen( UINT8 ubProfileID )
{
DeleteTalkingMenu( );
//Enter the shopkeeper interface
EnterShopKeeperInterfaceScreen( gTalkPanel.ubCharNum );
}
#endif
+35 -14
View File
@@ -81,6 +81,12 @@
// BOB : quick attachment popup
#include "popup_class.h"
#endif
#ifdef JA2UB
#include "Ja25_Tactical.h"
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - all "APBPConstants[AP_PICKUP_ITEM]" were replaced by GetBasicAPsToPickupItem()
////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1278,15 +1284,15 @@ BOOLEAN InitInvSlotInterface( INV_REGION_DESC *pRegionDesc , INV_REGION_DESC *pC
// Kaiden: Vehicle Inventory change - Added two new STI's for Vehicle Inventory
// Feel free to change them to more appropriate pictures, I just blanked out
// the body image for now, I'm no graphics artist.
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
FilenameForBPP("INTERFACE\\inventory_figure_Vehicle.sti",
VObjectDesc.ImageFile);
CHECKF( AddVideoObject( &VObjectDesc, &(guiBodyInvVO[ 4 ][ 0 ] ) ) );
//VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
//FilenameForBPP("INTERFACE\\inventory_figure_Vehicle.sti",
//VObjectDesc.ImageFile);
//CHECKF( AddVideoObject( &VObjectDesc, &(guiBodyInvVO[ 4 ][ 0 ] ) ) );
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
FilenameForBPP("INTERFACE\\inventory_figure_Vehicle_h.sti",
VObjectDesc.ImageFile);
CHECKF( AddVideoObject( &VObjectDesc, &(guiBodyInvVO[ 4 ][ 1 ] ) ) );
//VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
//FilenameForBPP("INTERFACE\\inventory_figure_Vehicle_h.sti",
//VObjectDesc.ImageFile);
//CHECKF( AddVideoObject( &VObjectDesc, &(guiBodyInvVO[ 4 ][ 1 ] ) ) );
// add gold key graphic
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
@@ -1410,12 +1416,12 @@ void ShutdownInvSlotInterface( )
DeleteVideoObjectFromIndex( guiBodyInvVO[ 2 ][ 0 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 1 ][ 0 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 3 ][ 0 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 4 ][ 0 ] );
//DeleteVideoObjectFromIndex( guiBodyInvVO[ 4 ][ 0 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 0 ][ 1 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 2 ][ 1 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 1 ][ 1 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 3 ][ 1 ] );
DeleteVideoObjectFromIndex( guiBodyInvVO[ 4 ][ 1 ] );
//DeleteVideoObjectFromIndex( guiBodyInvVO[ 4 ][ 1 ] );
DeleteVideoObjectFromIndex( guiGoldKeyVO );
@@ -1441,7 +1447,7 @@ void RenderInvBodyPanel( SOLDIERTYPE *pSoldier, INT16 sX, INT16 sY )
// the original statement
if ( (gGameExternalOptions.fVehicleInventory) && (pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiBodyInvVO[4][0], 0, sX, sY, VO_BLT_SRCTRANSPARENCY, NULL );
//BltVideoObjectFromIndex( guiSAVEBUFFER, guiBodyInvVO[4][0], 0, sX, sY, VO_BLT_SRCTRANSPARENCY, NULL );
}
else
{
@@ -2487,7 +2493,7 @@ void DegradeNewlyAddedItems( )
{
guiNewlyPlacedItemTimer = uiTime;
for ( cnt2 = 0; cnt2 < NUM_TEAM_SLOTS; cnt2++ )
for ( cnt2 = 0; cnt2 < gGameOptions.ubSquadSize; cnt2++ )
{
// GET SOLDIER
if ( gTeamPanel[ cnt2 ].fOccupied )
@@ -6738,8 +6744,8 @@ BOOLEAN HandleItemPointerClick( INT32 usMapPos )
}
// Charge AP values...
DeductPoints( pSoldier, 3, 0 );
DeductPoints( gpItemPointerSoldier, 3, 0 );
DeductPoints( pSoldier, 3, 0, UNTRIGGERED_INTERRUPT );
DeductPoints( gpItemPointerSoldier, 3, 0, UNTRIGGERED_INTERRUPT );
usItem = gpItemPointer->usItem;
@@ -7709,6 +7715,21 @@ BOOLEAN LoadTileGraphicForItem( INVTYPE *pItem, UINT32 *puiVo )
sprintf( zName, "p2item%d", ubGraphic );
}
}
/*
#ifdef JA2UB
else if ( pItem->ubGraphicType == 9 ) // UB Items
{
if ( ubGraphic < 10 )
{
sprintf( zName, "GUN_UB0%d", ubGraphic );
}
else
{
sprintf( zName, "GUN_UB%d", ubGraphic );
}
}
#endif
*/
else
{
if ( ubGraphic < 10 )
+52 -31
View File
@@ -3363,11 +3363,11 @@ BOOLEAN UIHandleItemPlacement( UINT8 ubHandPos, UINT16 usOldItemIndex, UINT16 us
// Deduct points
if ( gpItemPointerSoldier->stats.bLife >= CONSCIOUSNESS )
{
DeductPoints( gpItemPointerSoldier, 2, 0 );
DeductPoints( gpItemPointerSoldier, 2, 0, UNTRIGGERED_INTERRUPT );
}
if ( gpSMCurrentMerc->stats.bLife >= CONSCIOUSNESS )
{
DeductPoints( gpSMCurrentMerc, 2, 0 );
DeductPoints( gpSMCurrentMerc, 2, 0, UNTRIGGERED_INTERRUPT );
}
}
@@ -4725,11 +4725,11 @@ BOOLEAN InitializeTEAMPanelCoords( )
TM_APPANEL_HEIGHT = 56;
TM_APPANEL_WIDTH = 16;
TM_ENDTURN_X = (SCREEN_WIDTH - 133); //( 507 + INTERFACE_START_X );
TM_ENDTURN_X = (SCREEN_WIDTH - 131); //( 507 + INTERFACE_START_X );
TM_ENDTURN_Y = ( 9 + INTERFACE_START_Y );
TM_ROSTERMODE_X = (SCREEN_WIDTH - 133); //( 507 + INTERFACE_START_X );
TM_ROSTERMODE_X = (SCREEN_WIDTH - 131); //( 507 + INTERFACE_START_X );
TM_ROSTERMODE_Y = ( 45 + INTERFACE_START_Y );
TM_DISK_X = (SCREEN_WIDTH - 133); //( 507 + INTERFACE_START_X );
TM_DISK_X = (SCREEN_WIDTH - 131); //( 507 + INTERFACE_START_X );
TM_DISK_Y = ( 81 + INTERFACE_START_Y );
TM_NAME_WIDTH = 60;
@@ -4882,17 +4882,38 @@ BOOLEAN InitializeTEAMPanel( )
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
if (iResolution == 0)
//SQUAD10 FIX: Use panels with more slots if SquadSize at current resolution is > 6
switch (iResolution)
{
FilenameForBPP("INTERFACE\\bottom_bar.sti", VObjectDesc.ImageFile);
}
else if (iResolution == 1)
{
FilenameForBPP("INTERFACE\\bottom_bar_800x600.sti", VObjectDesc.ImageFile);
}
else if (iResolution == 2)
{
FilenameForBPP("INTERFACE\\bottom_bar_1024x768.sti", VObjectDesc.ImageFile);
case 0:
FilenameForBPP("INTERFACE\\bottom_bar.sti", VObjectDesc.ImageFile);
break;
case 1:
if (gGameOptions.ubSquadSize > 6)
{
FilenameForBPP("INTERFACE\\bottom_bar_8_800x600.sti", VObjectDesc.ImageFile);
}
else
{
FilenameForBPP("INTERFACE\\bottom_bar_800x600.sti", VObjectDesc.ImageFile);
}
break;
case 2:
if (gGameOptions.ubSquadSize > 8)
{
FilenameForBPP("INTERFACE\\bottom_bar_10_1024x768.sti", VObjectDesc.ImageFile);
}
else if (gGameOptions.ubSquadSize > 6)
{
FilenameForBPP("INTERFACE\\bottom_bar_8_1024x768.sti", VObjectDesc.ImageFile);
}
else
{
FilenameForBPP("INTERFACE\\bottom_bar_1024x768.sti", VObjectDesc.ImageFile);
}
break;
default:
FilenameForBPP("INTERFACE\\bottom_bar.sti", VObjectDesc.ImageFile);
}
CHECKF( AddVideoObject( &VObjectDesc, &guiTEAMPanel ) );
@@ -4919,7 +4940,7 @@ BOOLEAN InitializeTEAMPanel( )
// Add region
MSYS_AddRegion( &gTEAM_PanelRegion);
for ( posIndex = 0, cnt = 0; cnt < NUM_TEAM_SLOTS; cnt++, posIndex +=2 )
for ( posIndex = 0, cnt = 0; cnt < gGameOptions.ubSquadSize; cnt++, posIndex +=2 )
{
MSYS_DefineRegion( &gTEAM_FaceRegions[ cnt ], sTEAMFacesXY[ posIndex ], sTEAMFacesXY[ posIndex + 1 ] ,(INT16)(sTEAMFacesXY[ posIndex ] + TM_FACE_WIDTH ), (INT16)(sTEAMFacesXY[ posIndex + 1 ] + TM_FACE_HEIGHT), MSYS_PRIORITY_NORMAL,
MSYS_NO_CURSOR, MercFacePanelMoveCallback, MercFacePanelCallback );
@@ -5056,7 +5077,7 @@ void RenderTEAMPanel( BOOLEAN fDirty )
RestoreExternBackgroundRect( INTERFACE_START_X, INTERFACE_START_Y, SCREEN_WIDTH - INTERFACE_START_X , INTERFACE_HEIGHT );
// LOOP THROUGH ALL MERCS ON TEAM PANEL
for ( cnt = 0, posIndex = 0; cnt < NUM_TEAM_SLOTS; cnt++, posIndex+= 2 )
for ( cnt = 0, posIndex = 0; cnt < gGameOptions.ubSquadSize; cnt++, posIndex+= 2 )
{
// GET SOLDIER
if ( !gTeamPanel[ cnt ].fOccupied )
@@ -5180,7 +5201,7 @@ void RenderTEAMPanel( BOOLEAN fDirty )
}
// Loop through all mercs and make go
for ( cnt = 0, posIndex = 0; cnt < NUM_TEAM_SLOTS; cnt++, posIndex+= 2 )
for ( cnt = 0, posIndex = 0; cnt < gGameOptions.ubSquadSize; cnt++, posIndex+= 2 )
{
// GET SOLDIER
if ( gTeamPanel[ cnt ].fOccupied )
@@ -6345,7 +6366,7 @@ BOOLEAN PlayerExistsInSlot( UINT8 ubID )
{
INT32 cnt;
for ( cnt = 0; cnt < NUM_TEAM_SLOTS; cnt++ )
for ( cnt = 0; cnt < gGameOptions.ubSquadSize; cnt++ )
{
if ( gTeamPanel[ cnt ].fOccupied )
{
@@ -6364,7 +6385,7 @@ INT8 GetTeamSlotFromPlayerID( UINT8 ubID )
{
INT8 cnt;
for ( cnt = 0; cnt < NUM_TEAM_SLOTS; cnt++ )
for ( cnt = 0; cnt < gGameOptions.ubSquadSize; cnt++ )
{
if ( gTeamPanel[ cnt ].fOccupied )
{
@@ -6383,7 +6404,7 @@ BOOLEAN RemovePlayerFromTeamSlotGivenMercID( UINT8 ubMercID )
{
INT32 cnt;
for ( cnt = 0; cnt < NUM_TEAM_SLOTS; cnt++ )
for ( cnt = 0; cnt < gGameOptions.ubSquadSize; cnt++ )
{
if ( gTeamPanel[ cnt ].fOccupied )
{
@@ -6412,7 +6433,7 @@ void AddPlayerToInterfaceTeamSlot( UINT8 ubID )
if ( !PlayerExistsInSlot( ubID ) )
{
// Find a free slot
for ( cnt = 0; cnt < NUM_TEAM_SLOTS; cnt++ )
for ( cnt = 0; cnt < gGameOptions.ubSquadSize; cnt++ )
{
if ( !gTeamPanel[ cnt ].fOccupied )
{
@@ -6438,7 +6459,7 @@ BOOLEAN InitTEAMSlots( )
{
INT32 cnt;
for ( cnt = 0; cnt < NUM_TEAM_SLOTS; cnt++ )
for ( cnt = 0; cnt < gGameOptions.ubSquadSize; cnt++ )
{
gTeamPanel[ cnt ].fOccupied = FALSE;
gTeamPanel[ cnt ].ubID = NOBODY;
@@ -6451,7 +6472,7 @@ BOOLEAN InitTEAMSlots( )
BOOLEAN GetPlayerIDFromInterfaceTeamSlot( UINT8 ubPanelSlot, UINT8 *pubID )
{
if ( ubPanelSlot >= NUM_TEAM_SLOTS )
if ( ubPanelSlot >= gGameOptions.ubSquadSize )
{
return( FALSE );
}
@@ -6471,7 +6492,7 @@ void RemoveAllPlayersFromSlot( )
{
int cnt;
for ( cnt = 0; cnt < NUM_TEAM_SLOTS; cnt++ )
for ( cnt = 0; cnt < gGameOptions.ubSquadSize; cnt++ )
{
RemovePlayerFromInterfaceTeamSlot( (UINT8)cnt );
}
@@ -6480,7 +6501,7 @@ void RemoveAllPlayersFromSlot( )
BOOLEAN RemovePlayerFromInterfaceTeamSlot( UINT8 ubPanelSlot )
{
if ( ubPanelSlot >= NUM_TEAM_SLOTS )
if ( ubPanelSlot >= gGameOptions.ubSquadSize )
{
return( FALSE );
}
@@ -6623,7 +6644,7 @@ UINT8 FindNextMercInTeamPanel( SOLDIERTYPE *pSoldier, BOOLEAN fGoodForLessOKLife
return( pSoldier->ubID );
}
for ( cnt = ( bFirstID + 1 ); cnt < NUM_TEAM_SLOTS; cnt++ )
for ( cnt = ( bFirstID + 1 ); cnt < gGameOptions.ubSquadSize; cnt++ )
{
if ( gTeamPanel[ cnt ].fOccupied )
{
@@ -7004,11 +7025,11 @@ void KeyRingSlotInvClickCallback( MOUSE_REGION * pRegion, INT32 iReason )
// Deduct points
if ( gpItemPointerSoldier->stats.bLife >= CONSCIOUSNESS )
{
DeductPoints( gpItemPointerSoldier, 2, 0 );
DeductPoints( gpItemPointerSoldier, 2, 0, UNTRIGGERED_INTERRUPT );
}
if ( gpItemPopupSoldier->stats.bLife >= CONSCIOUSNESS )
{
DeductPoints( gpItemPopupSoldier, 2, 0 );
DeductPoints( gpItemPopupSoldier, 2, 0, UNTRIGGERED_INTERRUPT );
}
}
@@ -7047,11 +7068,11 @@ void KeyRingSlotInvClickCallback( MOUSE_REGION * pRegion, INT32 iReason )
// Deduct points
if ( gpItemPointerSoldier && gpItemPointerSoldier->stats.bLife >= CONSCIOUSNESS )
{
DeductPoints( gpItemPointerSoldier, 2, 0 );
DeductPoints( gpItemPointerSoldier, 2, 0, UNTRIGGERED_INTERRUPT );
}
if ( gpSMCurrentMerc->stats.bLife >= CONSCIOUSNESS )
{
DeductPoints( gpSMCurrentMerc, 2, 0 );
DeductPoints( gpSMCurrentMerc, 2, 0, UNTRIGGERED_INTERRUPT );
}
}
+1 -1
View File
@@ -34,7 +34,7 @@ typedef enum
#define NEW_ITEM_CYCLE_COUNT 19
#define NEW_ITEM_CYCLES 4
#define NUM_TEAM_SLOTS 6
#define NUM_TEAM_SLOTS 10
#define PASSING_ITEM_DISTANCE_OKLIFE 3
+35 -6
View File
@@ -58,7 +58,9 @@ enum{
};
// the ids for the car portraits
INT32 giCarPortraits[ 4 ] = { -1, -1, -1, -1 };
//INT32 giCarPortraits[ 4 ] = { -1, -1, -1, -1 };
INT32 giCarPortraits[ NUM_PROFILES ];
// the car portrait file names
STR pbCarPortraitFileNames[ ]={
@@ -74,17 +76,31 @@ BOOLEAN LoadCarPortraitValues( void )
{
INT32 iCounter = 0;
VOBJECT_DESC VObjectDesc;
/*
if( giCarPortraits[ 0 ] != -1 )
{
return FALSE;
}
*/
for( iCounter = 0; iCounter < NUM_PROFILES; iCounter++ )
{
if ( gProfilesVehicle[ iCounter ].ProfilId == iCounter )
{
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
strcpy( VObjectDesc.ImageFile, gNewVehicle[ iCounter ].szIconFace );
CHECKF( AddVideoObject( &VObjectDesc, (UINT32 *)&giCarPortraits[ iCounter ] ) );
}
}
/*
for( iCounter = 0; iCounter < NUMBER_CAR_PORTRAITS; iCounter++ )
{
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
sprintf( VObjectDesc.ImageFile, pbCarPortraitFileNames[ iCounter ] );
CHECKF( AddVideoObject( &VObjectDesc, (UINT32 *)&giCarPortraits[ iCounter ] ) );
}
}*/
return( TRUE );
}
@@ -94,15 +110,27 @@ void UnLoadCarPortraits( void )
INT32 iCounter = 0;
// car protraits loaded?
/*
if( giCarPortraits[ 0 ] == -1 )
{
return;
}
for( iCounter = 0; iCounter < NUMBER_CAR_PORTRAITS; iCounter++ )
{
DeleteVideoObjectFromIndex( giCarPortraits[ iCounter ] );
giCarPortraits[ iCounter ] = -1;
}
*/
for( iCounter = 0; iCounter < NUM_PROFILES; iCounter++ )
{
if ( gProfilesVehicle[ iCounter ].ProfilId == iCounter )
{
DeleteVideoObjectFromIndex( giCarPortraits[ iCounter ] );
}
}
return;
}
@@ -444,7 +472,7 @@ void DrawItemUIBarEx( OBJECTTYPE *pObject, UINT8 ubStatus, INT16 sXPos, INT16 sY
void RenderSoldierFace( SOLDIERTYPE *pSoldier, INT16 sFaceX, INT16 sFaceY, BOOLEAN fAutoFace )
{
BOOLEAN fDoFace = FALSE;
UINT8 ubVehicleType = 0;
// UINT8 ubVehicleType = 0;
if ( pSoldier->bActive )
@@ -453,10 +481,11 @@ void RenderSoldierFace( SOLDIERTYPE *pSoldier, INT16 sFaceX, INT16 sFaceY, BOOLE
if( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
{
// get the type of vehicle
ubVehicleType = pVehicleList[ pSoldier->bVehicleID ].ubVehicleType;
// ubVehicleType = pVehicleList[ pSoldier->bVehicleID ].ubVehicleType;
// just draw the vehicle
BltVideoObjectFromIndex( guiSAVEBUFFER, giCarPortraits[ ubVehicleType ], 0, sFaceX, sFaceY, VO_BLT_SRCTRANSPARENCY, NULL );
// BltVideoObjectFromIndex( guiSAVEBUFFER, giCarPortraits[ ubVehicleType ], 0, sFaceX, sFaceY, VO_BLT_SRCTRANSPARENCY, NULL );
BltVideoObjectFromIndex( guiSAVEBUFFER, giCarPortraits[ pSoldier->ubProfile ], 0, sFaceX, sFaceY, VO_BLT_SRCTRANSPARENCY, NULL );
RestoreExternBackgroundRect( sFaceX, sFaceY, FACE_WIDTH, FACE_HEIGHT );
return;
+120 -14
View File
@@ -64,6 +64,16 @@
#endif
#include "InterfaceItemImages.h"
#ifdef JA2UB
#include "Explosion Control.h"
#include "Ja25_Tactical.h"
#include "Ja25 Strategic Ai.h"
#include "MapScreen Quotes.h"
#include "email.h"
#include "interface Dialogue.h"
#include "mercs.h"
#include "ub_config.h"
#endif
#include "connect.h"
//const UINT32 INTERFACE_START_X = 0;
@@ -1888,7 +1898,8 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
//Legion
if (pSoldier->ubBodyType == TANK_NE || pSoldier->ubBodyType == TANK_NW)
{
swprintf( NameStr, pVehicleStrings[4] );
swprintf( NameStr, gNewVehicle[164].NewVehicleStrings );
//swprintf( NameStr, pVehicleStrings[4] );
}
else if (zHiddenNames[pSoldier->ubProfile].Hidden == TRUE)
{
@@ -1925,7 +1936,8 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
//Legion
if (pSoldier->ubBodyType == TANK_NE || pSoldier->ubBodyType == TANK_NW)
{
swprintf( NameStr, pVehicleStrings[4] );
//swprintf( NameStr, pVehicleStrings[4] );
swprintf( NameStr, gNewVehicle[164].NewVehicleStrings );
}
else if (zHiddenNames[pSoldier->ubProfile].Hidden == TRUE)
{
@@ -3840,11 +3852,47 @@ void BtnDoorMenuCallback(GUI_BUTTON *btn,INT32 reason)
{
// OK, set cancle code!
gOpenDoorMenu.fMenuHandled = 2;
#ifdef JA2UB
//Handle someone trying to open the door in the tunnel gate`
HandlePlayerSayingQuoteWhenFailingToOpenGateInTunnel( gOpenDoorMenu.pSoldier, FALSE ); //Ja25 UB
#endif
}
// Switch on command....
if ( uiBtnID == iActionIcons[ OPEN_DOOR_ICON ] )
{
#ifdef JA2UB
//Handle someone trying to open the door in the tunnel gate`
if( HandlePlayerSayingQuoteWhenFailingToOpenGateInTunnel( gOpenDoorMenu.pSoldier, TRUE ) ) //Ja25 UB
{
// OK, set cancle code!
gOpenDoorMenu.fMenuHandled = 2;
}
else
{
// Open door normally...
// Check APs
if ( EnoughPoints( gOpenDoorMenu.pSoldier, APBPConstants[AP_OPEN_DOOR], APBPConstants[BP_OPEN_DOOR], FALSE ) )
{
// Set UI
SetUIBusy( (UINT8)gOpenDoorMenu.pSoldier->ubID );
if ( gOpenDoorMenu.fClosingDoor )
{
gOpenDoorMenu.pSoldier->ChangeSoldierState( GetAnimStateForInteraction( gOpenDoorMenu.pSoldier, TRUE, CLOSE_DOOR ), 0 , FALSE );
}
else
{
InteractWithClosedDoor( gOpenDoorMenu.pSoldier, HANDLE_DOOR_OPEN );
}
}
else
{
// OK, set cancel code!
gOpenDoorMenu.fMenuHandled = 2;
}
}
#else
// Open door normally...
// Check APs
// SANDRO - changed APs for opening dorrs calc
@@ -3867,6 +3915,7 @@ void BtnDoorMenuCallback(GUI_BUTTON *btn,INT32 reason)
// OK, set cancel code!
gOpenDoorMenu.fMenuHandled = 2;
}
#endif
}
if ( uiBtnID == iActionIcons[ BOOT_DOOR_ICON ] )
@@ -3939,6 +3988,30 @@ void BtnDoorMenuCallback(GUI_BUTTON *btn,INT32 reason)
if ( uiBtnID == iActionIcons[ EXPLOSIVE_DOOR_ICON ] )
{
#ifdef JA2UB
//Handle someone trying to open the door in the tunnel gate`
if( HandlePlayerSayingQuoteWhenFailingToOpenGateInTunnel( gOpenDoorMenu.pSoldier, TRUE ) ) //Ja25 UB
{
// OK, set cancle code!
gOpenDoorMenu.fMenuHandled = 2;
}
else
{
// Explode
if ( EnoughPoints( gOpenDoorMenu.pSoldier, APBPConstants[AP_EXPLODE_DOOR], APBPConstants[BP_EXPLODE_DOOR], FALSE ) )
{
// Set UI
SetUIBusy( (UINT8)gOpenDoorMenu.pSoldier->ubID );
InteractWithClosedDoor( gOpenDoorMenu.pSoldier, HANDLE_DOOR_EXPLODE );
}
else
{
// OK, set cancle code!
gOpenDoorMenu.fMenuHandled = 2;
}
}
#else
// Explode
if ( EnoughPoints( gOpenDoorMenu.pSoldier, GetAPsToBombDoor( gOpenDoorMenu.pSoldier ), APBPConstants[BP_EXPLODE_DOOR], FALSE ) ) // SANDRO
{
@@ -3952,6 +4025,7 @@ void BtnDoorMenuCallback(GUI_BUTTON *btn,INT32 reason)
// OK, set cancle code!
gOpenDoorMenu.fMenuHandled = 2;
}
#endif
}
if ( uiBtnID == iActionIcons[ UNTRAP_DOOR_ICON ] )
@@ -3973,6 +4047,30 @@ void BtnDoorMenuCallback(GUI_BUTTON *btn,INT32 reason)
if ( uiBtnID == iActionIcons[ USE_CROWBAR_ICON ] )
{
#ifdef JA2UB
//Handle someone trying to open the door in the tunnel gate`
if( HandlePlayerSayingQuoteWhenFailingToOpenGateInTunnel( gOpenDoorMenu.pSoldier, TRUE ) ) //JA25 UB
{
// OK, set cancle code!
gOpenDoorMenu.fMenuHandled = 2;
}
else
{
// Explode
if ( EnoughPoints( gOpenDoorMenu.pSoldier, APBPConstants[AP_USE_CROWBAR], APBPConstants[BP_USE_CROWBAR], FALSE ) )
{
// Set UI
SetUIBusy( (UINT8)gOpenDoorMenu.pSoldier->ubID );
InteractWithClosedDoor( gOpenDoorMenu.pSoldier, HANDLE_DOOR_CROWBAR );
}
else
{
// OK, set cancle code!
gOpenDoorMenu.fMenuHandled = 2;
}
}
#else
// Explode
if ( EnoughPoints( gOpenDoorMenu.pSoldier, APBPConstants[AP_USE_CROWBAR], APBPConstants[BP_USE_CROWBAR], FALSE ) )
{
@@ -3986,6 +4084,7 @@ void BtnDoorMenuCallback(GUI_BUTTON *btn,INT32 reason)
// OK, set cancle code!
gOpenDoorMenu.fMenuHandled = 2;
}
#endif
}
HandleOpenDoorMenu( );
@@ -4866,24 +4965,31 @@ void DoorMenuBackregionCallback( MOUSE_REGION * pRegion, INT32 iReason )
STR16 GetSoldierHealthString( SOLDIERTYPE *pSoldier )
{
INT32 cnt, cntStart;
if( pSoldier->stats.bLife == pSoldier->stats.bLifeMax )
if (gGameExternalOptions.fHideEnemyHealthText && (pSoldier->bTeam == ENEMY_TEAM || pSoldier->bTeam == CREATURE_TEAM))
{
cntStart = 4;
return L"";
}
else
else
{
cntStart = 0;
}
//Show health on others.........
for ( cnt = cntStart; cnt < 6; cnt ++ )
{
if ( pSoldier->stats.bLife < bHealthStrRanges[ cnt ] )
INT32 cnt, cntStart;
if( pSoldier->stats.bLife == pSoldier->stats.bLifeMax )
{
break;
cntStart = 4;
}
else
{
cntStart = 0;
}
//Show health on others.........
for ( cnt = cntStart; cnt < 6; cnt ++ )
{
if ( pSoldier->stats.bLife < bHealthStrRanges[ cnt ] )
{
break;
}
}
return zHealthStr[ cnt ];
}
return zHealthStr[ cnt ];
}
+9 -1
View File
@@ -57,6 +57,11 @@
#include "math.h"
#endif
#ifdef JA2UB
#include "Ja25_Tactical.h"
#include "Ja25 Strategic Ai.h"
#endif
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
@@ -5797,7 +5802,10 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
}
// Lesh: end
#ifdef JA2UB
//handle the placing up of a new ja25 gun
HandleNewGunComment( pSoldier, pObj->usItem, FALSE );
#endif
pInSlot = &(pSoldier->inv[bPos]);
//we are placing an object, how we handle this depends on what is in the slot already
File diff suppressed because it is too large Load Diff
+141
View File
@@ -0,0 +1,141 @@
#ifndef _JA25_TACTICAL__H_
#define _JA25_TACTICAL__H_
#ifdef JA2UB
#include "MapScreen Quotes.h"
#define PGF__FAN_EXIT_GRID_GRIDNO 10979
#define NUM_MERCS_WITH_NEW_QUOTES 20//7
#define DQ__NORMAL_DELAYED_QUOTE 0xff00
#define DQ__JERRY_BROKE_TRANSMITTER 0xffff
#define DQ__MORRIS_NOTE_NEW_MERC_DELAY 0xfffe
#define DQ__MORRIS_NOTE_DISPLAY_NOTE_1 0xfffd
#define DQ__MORRIS_NOTE_DISPLAY_NOTE_2 0xfffc
#define DQ__SHOW_RADIO_LOCATOR 0xfffb
#define DQ__NEW_MERC_SAY_NOTE_QUOTES 0xfffa
#define DQ__START_EVERYONE_TALKING_AT_END_OF_GAME 0xfff0
#define DQ__FADE_OUT_TO_END_GAME_CINEMATIC 0xfff9
enum
{
JM_SE__HEADING_TO_TRACONA =MILO_QUOTE__HEADED_TO_TRACONA_QUOTE,
JM_SE__SHOW_RADIO_LOCATOR = MILO_NO_QUOTE-10,
};
/*
// things that need to be saved in the exp in tactical
typedef struct
{
} JA25_TACTICAL_SAVE_STRUCT;
*/
extern BOOLEAN gfFirstTimeInGameHeliCrash;
INT8 RandomProfileIdFromNewMercsOnPlayerTeam();
INT8 RandomSoldierIdFromNewMercsOnPlayerTeam();
INT8 GetNumSoldierIdAndProfileIdOfTheNewMercsOnPlayerTeam( UINT8 *pSoldierIdArray, UINT8 *pProfileIdArray );
BOOLEAN IsSoldierQualifiedMerc( SOLDIERTYPE *pSoldier );
BOOLEAN IsSoldierQualifiedInitialHireMerc( SOLDIERTYPE *pSoldier );
BOOLEAN IsSoldierQualifiedMercForSeeingPowerGenFan( SOLDIERTYPE *pSoldier );
BOOLEAN SayQuoteFromAllNewHiredMercButDoGastonLast( UINT8 ubProfile, UINT32 uiQuoteNum );
//Pass in an array of size NUM_MERCS_WITH_NEW_QUOTES, array will be filled with
//random soldier IDs of the qualified mercs
INT8 RandomArrayOfQualifiedMercs( UINT8 *pRandomSoldierIdArray );
extern UINT8 Get3RandomQualifiedMercs( UINT8 *pSoldierId1, UINT8 *pSoldierId2, UINT8 *pSoldierId3 );
void HandleWhenCertainPercentageOfEnemiesDie();
void StartFanBackUpAgain();
void AddExitGridForFanToPowerGenSector();
void HandleAddingPowerGenFanSound();
void HandleRemovingPowerGenFanSound();
void HandleStartingFanBackUp();
void HandlePowerGenAlarm();
BOOLEAN HandlePlayerSayingQuoteWhenFailingToOpenGateInTunnel( SOLDIERTYPE *pSoldier, BOOLEAN fSayQuoteOnlyOnce );
extern void HandleHowPlayerGotThroughFan();
//void RevealAllDroppedEnemyItems();
void HandlePlayingQuoteWhenHiringNpc( UINT8 ubProfile );
BOOLEAN LoadJa25TacticalInfoFromSavedGame( HWFILE hFile );
BOOLEAN SaveJa25TacticalInfoToSaveGame( HWFILE hFile );
BOOLEAN HandleNewGunComment( SOLDIERTYPE *pSoldier, INT32 iItemIndex, BOOLEAN fFromGround );
void HandleDeathInPowerGenSector( SOLDIERTYPE *pSoldier );
void HandleJa25EnemyExpLevelModifier( );
INT8 RandomSoldierIdForAnyMercInSector();
void HandleFanStartingAtEndOfCombat();
extern void HandleInitialEventsInHeliCrash();
void HandleCommanderMorrisNewMercWantsNoteDelayedSpeech();
void DisplayCommanderMorrisNote( SOLDIERTYPE *pSoldier );
void HandleShowingRadioLocatorsInMorrisArea();
void HandleNewMercSayingContentsOfMorrisNote( SOLDIERTYPE *pSoldier );
void HandlePlayerHittingSwitchToLaunchMissles();
void HandleStartingEveryoneTalkingAtEndOfGame();
void HandleFadingOutToEndGameCinematics();
void HandleOpenControlPanelToRevealSwitchInMorrisArea();
void InitNewGunArray();
extern BOOLEAN useOldJA2Inventory;
extern UINT32 TEX_MOVIE_ATTACK_CLYDESDALES;
extern UINT32 TEX_MOVIE_WILD_EAST;
extern UINT32 TEX_MOVIE_HAVE_HONDA;
extern UINT32 LAPTOP_TRANSMITTER;
extern UINT32 CHE_GUEVARA_CANTEEN;
extern UINT32 MERC_WRISTWATCH;
extern UINT32 SAM_GARVER_COMBAT_KNIFE;
extern UINT32 MERC_UMBRELLA_OLD;
extern UINT32 MORRIS_INSTRUCTION_NOTE;
extern UINT32 HAND_CANNON;
extern UINT32 HARTFORD_6_SHOOTER;
extern UINT32 MERC_UMBRELLA;
extern UINT32 CLIP_CANNON_BALL;
extern UINT32 BARRETT_UB;
extern UINT32 CALICO_960_UB;
extern UINT32 PSG1_UB;
extern UINT32 L85_UB;
extern UINT32 TAR21_UB;
extern UINT32 VAL_SILENT_UB;
extern UINT32 MICRO_UZI_UB;
extern UINT32 CALICO_950_UB;
extern UINT32 CALICO_900_UB;
extern void Old_UB_Inventory ();
extern void New_UB_Inventory ();
extern void InitGridNoUB();
#endif
#endif
+17 -2
View File
@@ -45,6 +45,10 @@
#include "Overhead.h"
#endif
#ifdef JA2UB
#include "ub_config.h"
#endif
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
@@ -479,9 +483,15 @@ void HandleHeliDrop( )
for ( cnt = gbCurDrop; cnt < gbNumHeliSeatsOccupied; cnt++ )
{
// Add merc to sector
#ifdef JA2UB
//MercPtrs[ gusHeliSeats[ cnt ] ]->ubStrategicInsertionCode = INSERTION_CODE_NORTH;
MercPtrs[ gusHeliSeats[ cnt ] ]->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
MercPtrs[ gusHeliSeats[ cnt ] ]->usStrategicInsertionData = gGameUBOptions.LOCATEGRIDNO;
#else
//MercPtrs[ gusHeliSeats[ cnt ] ]->ubStrategicInsertionCode = INSERTION_CODE_NORTH;
MercPtrs[ gusHeliSeats[ cnt ] ]->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
MercPtrs[ gusHeliSeats[ cnt ] ]->usStrategicInsertionData = gGameExternalOptions.iInitialMercArrivalLocation;
#endif
// HEADROCK HAM 3.5: Externalized!
UpdateMercInSector( MercPtrs[ gusHeliSeats[ cnt ] ], gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY, startingZ );
@@ -617,10 +627,15 @@ void HandleHeliDrop( )
MercPtrs[ gusHeliSeats[ gbCurDrop ] ]->EVENT_InitNewSoldierAnim( HELIDROP, 0 , FALSE );
// Change insertion code
#ifdef JA2UB
//MercPtrs[ gusHeliSeats[ gbCurDrop ] ]->ubStrategicInsertionCode = INSERTION_CODE_NORTH;
MercPtrs[ gusHeliSeats[ gbCurDrop ] ]->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
MercPtrs[ gusHeliSeats[ gbCurDrop ] ]->usStrategicInsertionData = gGameUBOptions.LOCATEGRIDNO;
#else
//MercPtrs[ gusHeliSeats[ gbCurDrop ] ]->ubStrategicInsertionCode = INSERTION_CODE_NORTH;
MercPtrs[ gusHeliSeats[ gbCurDrop ] ]->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
MercPtrs[ gusHeliSeats[ gbCurDrop ] ]->usStrategicInsertionData = gGameExternalOptions.iInitialMercArrivalLocation;
#endif
// HEADROCK HAM 3.5: Externalized!
UpdateMercInSector( MercPtrs[ gusHeliSeats[ gbCurDrop ] ], gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY, startingZ );
//EVENT_SetSoldierPosition( MercPtrs[ gusHeliSeats[ gbCurDrop ] ], sWorldX, sWorldY );
@@ -828,7 +843,7 @@ void HandleFirstHeliDropOfGame( )
// Move to header file...
// HEADROCK HAM 3.5: Externalized!
AddExtraItems( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY, startingZ, true );
AddExtraItems( (UINT8)gGameExternalOptions.ubDefaultArrivalSectorX, (UINT8)gGameExternalOptions.ubDefaultArrivalSectorY, startingZ, true );
// HEADROCK HAM 3.5: Starting sector externalized - might not contain enemies at all!
if (NumEnemyInSector( ) > 0)
+343 -8
View File
@@ -60,6 +60,18 @@
#include "GameSettings.h"
#endif
#include "connect.h"
#ifdef JA2UB
#include "Soldier Control.h"
#include "Ja25 Strategic Ai.h"
#include "Ja25_Tactical.h"
#include "Campaign Types.h"
#include "MapScreen Quotes.h"
#include "opplist.h"
#include "Ja25Update.h"
#include "ub_config.h"
#endif
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
@@ -84,7 +96,37 @@ INT16 gsMercArriveSectorY = gGameExternalOptions.ubDefaultArrivalSectorY;
void CheckForValidArrivalSector( );
#ifdef JA2UB
void AddItemToMerc( UINT8 ubNewMerc, INT16 sItemType );
#define NUM_INITIAL_GRIDNOS_FOR_HELI_CRASH 7
UINT32 gsInitialHeliGridNo[ NUM_INITIAL_GRIDNOS_FOR_HELI_CRASH ] =
{
0,
0,
0,
0,
0,
0,
0,
};
INT16 gsInitialHeliRandomTimes[ NUM_INITIAL_GRIDNOS_FOR_HELI_CRASH ] =
{
0,
0,
0,
0,
0,
0,
0
};
UINT32 GetInitialHeliGridNo( );
UINT16 GetInitialHeliRandomTime();
#endif
INT8 HireMerc( MERC_HIRE_STRUCT *pHireMerc)
{
SOLDIERTYPE *pSoldier;
@@ -136,6 +178,37 @@ INT8 HireMerc( MERC_HIRE_STRUCT *pHireMerc)
return( MERC_HIRE_FAILED );
}
#ifdef JA2UB
//JA25 UB
//MErc mercs come with an umbrella
if ( gProfilesMERC[ubCurrentSoldier].ProfilId == ubCurrentSoldier )
// if( ( ubCurrentSoldier >= 40 && ubCurrentSoldier <= 50 ) || ubCurrentSoldier == 58 /*GASTON*/ || ubCurrentSoldier == 59 /*STOGIE*/ )
{
AddItemToMerc( iNewIndex, MERC_UMBRELLA ); //1361
}
//if this is an AIM or MERC merc
if( gJa25SaveStruct.fHaveAimandMercOffferItems )
{
//if its an aim merc
//if( ubCurrentSoldier < 40 )
if ( gProfilesAIM[ubCurrentSoldier].ProfilId == ubCurrentSoldier )
{
//give the mercs one of the promo items
AddItemToMerc( iNewIndex, SAM_GARVER_COMBAT_KNIFE ); //1353
}
// if its a merc merc
else if ( gProfilesMERC[ubCurrentSoldier].ProfilId == ubCurrentSoldier )
//else if( ubCurrentSoldier <= 50 || ubCurrentSoldier == 58 /*GASTON*/ || ubCurrentSoldier == 59 /*STOGIE*/ )
{
//give the mercs one of the promo items
AddItemToMerc( iNewIndex, CHE_GUEVARA_CANTEEN ); //1359
AddItemToMerc( iNewIndex, MERC_WRISTWATCH ); //1360
AddItemToMerc( iNewIndex, SAM_GARVER_COMBAT_KNIFE ); //1353
}
}
#else //ja25: No enrico, therefore, no email
if( DidGameJustStart() )
{
// OK, CHECK FOR FIRST GUY, GIVE HIM SPECIAL ITEM!
@@ -160,7 +233,7 @@ INT8 HireMerc( MERC_HIRE_STRUCT *pHireMerc)
// ATE: Insert for demo , not using the heli sequence....
pHireMerc->ubInsertionCode = INSERTION_CODE_CHOPPER;
}
#endif
//record how long the merc will be gone for
pMerc->bMercStatus = (UINT8)pHireMerc->iTotalContractLength;
@@ -202,11 +275,47 @@ INT8 HireMerc( MERC_HIRE_STRUCT *pHireMerc)
{
if( DidGameJustStart() )
{
pHireMerc->uiTimeTillMercArrives = ( gGameExternalOptions.iGameStartingTime + gGameExternalOptions.iFirstArrivalDelay ) / NUM_SEC_IN_MIN;
#ifdef JA2UB
//ja25ub
//set a flag so we know we are doing the heli crash
if ( gGameUBOptions.InGameHeliCrash == TRUE || gGameUBOptions.InGameHeli == FALSE)
gfFirstTimeInGameHeliCrash = TRUE; //AA FALSE ??
else
gfFirstTimeInGameHeliCrash = FALSE;
// Set time of initial merc arrival in minutes
#endif
pHireMerc->uiTimeTillMercArrives = ( gGameExternalOptions.iGameStartingTime + gGameExternalOptions.iFirstArrivalDelay ) / NUM_SEC_IN_MIN;
#ifdef JA2UB
if ( gGameUBOptions.InGameHeli == FALSE )
{
// Set the gridno for the soldier
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
pSoldier->usStrategicInsertionData = GetInitialHeliGridNo( );
//Set a "code" to enable the merc to be in the direction we set!
pSoldier->ubInsertionDirection = Random( NUM_WORLD_DIRECTIONS ) + 100;
if( pSoldier->ubStrategicInsertionCode == 0 )
{
Assert( 0 );
}
pSoldier->fWaitingToGetupFromJA25Start = TRUE;
pSoldier->fIgnoreGetupFromCollapseCheck = TRUE;
RESETTIMECOUNTER( pSoldier->GetupFromJA25StartCounter, GetInitialHeliRandomTime() );
}
else
{
pHireMerc->ubInsertionCode = INSERTION_CODE_CHOPPER;
}
#else
// Set insertion for first time in chopper
pHireMerc->ubInsertionCode = INSERTION_CODE_CHOPPER;
#endif
//set when the merc's contract is finished
pSoldier->iEndofContractTime = GetMidnightOfFutureDayInMinutes( pSoldier->iTotalContractLength ) + ( GetHourWhenContractDone( pSoldier ) * 60 );
}
@@ -302,7 +411,10 @@ INT8 HireMerc( MERC_HIRE_STRUCT *pHireMerc)
pSoldier->ubWhatKindOfMercAmI = MERC_TYPE__NPC;
//pSoldier->iTotalContractCharge = -1;
}
#ifdef JA2UB
//Ja25: Need to set start time for all mercs
pSoldier->iStartContractTime = GetWorldDay( );
#endif
//remove the merc from the Personnel screens departed list ( if they have never been hired before, its ok to call it )
RemoveNewlyHiredMercFromPersonnelDepartedList( pSoldier->ubProfile );
@@ -364,7 +476,11 @@ void MercArrivesCallback( UINT8 ubSoldierID )
// OK, If this sector is currently loaded, and guy does not have CHOPPER insertion code....
// ( which means we are at beginning of game if so )
// Setup chopper....
if ( pSoldier->ubStrategicInsertionCode != INSERTION_CODE_CHOPPER && pSoldier->sSectorX == 9 && pSoldier->sSectorY == 1 )
#ifdef JA2UB
if ( pSoldier->ubStrategicInsertionCode != INSERTION_CODE_CHOPPER && pSoldier->sSectorX == gGameExternalOptions.ubDefaultArrivalSectorX && pSoldier->sSectorY == gGameExternalOptions.ubDefaultArrivalSectorY && gGameUBOptions.InGameHeli == TRUE )
#else
if ( pSoldier->ubStrategicInsertionCode != INSERTION_CODE_CHOPPER && pSoldier->sSectorX == gGameExternalOptions.ubDefaultArrivalSectorX && pSoldier->sSectorY == gGameExternalOptions.ubDefaultArrivalSectorY )
#endif
{
gfTacticalDoHeliRun = TRUE;
@@ -385,9 +501,15 @@ void MercArrivesCallback( UINT8 ubSoldierID )
else
{
// OK, otherwise, set them in north area, so once we load again, they are here.
#ifdef JA2UB
//pSoldier->ubStrategicInsertionCode = INSERTION_CODE_NORTH;
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
pSoldier->usStrategicInsertionData = gGameUBOptions.LOCATEGRIDNO;
#else
//pSoldier->ubStrategicInsertionCode = INSERTION_CODE_NORTH;
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
pSoldier->usStrategicInsertionData = gGameExternalOptions.iInitialMercArrivalLocation;
#endif
}
if ( pSoldier->ubStrategicInsertionCode != INSERTION_CODE_CHOPPER )
@@ -404,7 +526,14 @@ void MercArrivesCallback( UINT8 ubSoldierID )
gsSectorLocatorY = pSoldier->sSectorY;
TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_MINESECTOREVENT, 2, 0 );
//ja25ub
#ifdef JA2UB
//if its the first time in, dont say anything
if( !gfFirstTimeInGameHeliCrash )
#endif
TacticalCharacterDialogue( pSoldier, QUOTE_MERC_REACHED_DESTINATION );
TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_MINESECTOREVENT, 3, 0 );
TacticalCharacterDialogueWithSpecialEventEx( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_UNSET_ARRIVES_FLAG, 0, 0, 0 );
}
@@ -514,7 +643,14 @@ void HandleMercArrivesQuotes( SOLDIERTYPE *pSoldier )
{
INT8 cnt, bHated, bLastTeamID;
SOLDIERTYPE *pTeamSoldier;
#ifdef JA2UB
//if we are at the begining of the game going through the initial heli scequence
if( pSoldier->fWaitingToGetupFromJA25Start )
{
//we can "leave" this function cause we dont want to do anything with buddy system
return;
}
#endif
// If we are approaching with helicopter, don't say any ( yet )
if ( pSoldier->ubStrategicInsertionCode != INSERTION_CODE_CHOPPER )
{
@@ -657,8 +793,8 @@ void CheckForValidArrivalSector( )
INT16 sLeft, sRight;
INT16 cnt1, cnt2, sGoodX, sGoodY;
UINT8 ubRadius = 4;
INT32 leftmost;
INT32 sSectorGridNo, sSectorGridNo2;
UINT32 leftmost;
UINT32 sSectorGridNo, sSectorGridNo2;
INT32 uiRange, uiLowestRange = 999999;
BOOLEAN fFound = FALSE;
CHAR16 sString[ 1024 ];
@@ -724,4 +860,203 @@ void CheckForValidArrivalSector( )
}
}
#ifdef JA2UB
UINT32 GetInitialHeliGridNo( )
{
UINT8 ubCnt;
UINT32 sGridNo;
for( ubCnt=0; ubCnt<NUM_INITIAL_GRIDNOS_FOR_HELI_CRASH-1; ubCnt++)
{
if( gsInitialHeliGridNo[ ubCnt ] != 0 )
{
sGridNo = gsInitialHeliGridNo[ ubCnt ];
gsInitialHeliGridNo[ ubCnt ] = 0;
return( sGridNo );
}
}
return( 16233 );
}
UINT16 GetInitialHeliRandomTime()
{
BOOLEAN fDone=FALSE;
UINT8 ubRandom;
UINT16 usTime;
UINT16 usCounter=0;
while( !fDone )
{
ubRandom = Random( NUM_INITIAL_GRIDNOS_FOR_HELI_CRASH-1 );
if( gsInitialHeliRandomTimes[ ubRandom ] != 0 )
{
usTime = gsInitialHeliRandomTimes[ ubRandom ];
gsInitialHeliRandomTimes[ ubRandom ] = 0;
return( usTime );
}
if( usCounter > 1000 )
fDone = TRUE;
usCounter++;
}
return( 1000 + Random( 2000 ) );
}
void InitializeHeliGridnoAndTime( BOOLEAN fLoading )
{
Assert( NUM_INITIAL_GRIDNOS_FOR_HELI_CRASH == 7 );
if( !fLoading )
{
gfFirstTimeInGameHeliCrash = FALSE;
}
gsInitialHeliGridNo[ 0 ] = gGameUBOptions.InitialHeliGridNo[ 0 ];//14947;
gsInitialHeliGridNo[ 1 ] = gGameUBOptions.InitialHeliGridNo[ 1 ];//15584;//16067;
gsInitialHeliGridNo[ 2 ] = gGameUBOptions.InitialHeliGridNo[ 2 ];//15754;
gsInitialHeliGridNo[ 3 ] = gGameUBOptions.InitialHeliGridNo[ 3 ];//16232;
gsInitialHeliGridNo[ 4 ] = gGameUBOptions.InitialHeliGridNo[ 4 ];//16067;
gsInitialHeliGridNo[ 5 ] = gGameUBOptions.InitialHeliGridNo[ 5 ];//16230;
gsInitialHeliGridNo[ 6 ] = gGameUBOptions.InitialHeliGridNo[ 6 ];//15272;
gsInitialHeliRandomTimes[ 0 ] = gGameUBOptions.InitalHeliRandomTimes[ 0 ];//1300;
gsInitialHeliRandomTimes[ 1 ] = gGameUBOptions.InitalHeliRandomTimes[ 1 ];//2000;
gsInitialHeliRandomTimes[ 2 ] = gGameUBOptions.InitalHeliRandomTimes[ 2 ];//2750;
gsInitialHeliRandomTimes[ 3 ] = gGameUBOptions.InitalHeliRandomTimes[ 3 ];//3400;
gsInitialHeliRandomTimes[ 4 ] = gGameUBOptions.InitalHeliRandomTimes[ 4 ];//4160;
gsInitialHeliRandomTimes[ 5 ] = gGameUBOptions.InitalHeliRandomTimes[ 5 ];//4700;
gsInitialHeliRandomTimes[ 6 ] = gGameUBOptions.InitalHeliRandomTimes[ 6 ];//5630;
}
void InitJerryMiloInfo()
{
if ( gGameUBOptions.InJerry == TRUE )
{
// return; //AA
//Set Jerry Milo's Gridno h7
gMercProfiles[ 76 ].sSectorX = JA2_5_START_SECTOR_X;
gMercProfiles[ 76 ].sSectorY = JA2_5_START_SECTOR_Y;
gMercProfiles[ 76 ].bSectorZ = 0;
gMercProfiles[ 76 ].sGridNo = gGameUBOptions.JerryGridNo; //15109;
gMercProfiles[ 76 ].fUseProfileInsertionInfo = TRUE;
gMercProfiles[ 76 ].ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
gMercProfiles[ 76 ].usStrategicInsertionData = gGameUBOptions.JerryGridNo; //15109;
}
if ( gGameUBOptions.InGameHeliCrash == TRUE )
{
//init Jerry Milo quotes
InitJerryQuotes();
}
}
void UpdateJerryMiloInInitialSector()
{
SOLDIERTYPE *pSoldier = NULL;
SOLDIERTYPE *pJerrySoldier=NULL;
//SectorInfo[ SEC_H7 ].fSurfaceWasEverPlayerControlled = TRUE;
SectorInfo[ (UINT8)SECTOR( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY ) ].fSurfaceWasEverPlayerControlled = TRUE;
//SectorInfo[ SEC_H7 ].ubNumAdmins = 2;
StrategicMap[ (UINT8)SECTOR( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY ) ].fEnemyControlled = FALSE;
if ( gGameUBOptions.InGameHeli == TRUE )
return; //AA
if ( gGameUBOptions.InGameHeliCrash == TRUE )
{
//if it is the first sector we are loading up, place Jerry in the map
if( !gfFirstTimeInGameHeliCrash )
return;
if ( gGameUBOptions.InJerry == TRUE )
{
pSoldier = FindSoldierByProfileID( 76, FALSE ); //JERRY
if( pSoldier == NULL )
{
Assert( 0 );
}
}
//the internet part of the laptop isnt working. It gets broken in the heli crash.
if ( gGameUBOptions.LaptopQuestEnabled == TRUE )
StartQuest( QUEST_FIX_LAPTOP, -1, -1 );
//Record the initial sector as ours
//SectorInfo[ SEC_H7 ].fSurfaceWasEverPlayerControlled = TRUE;
SectorInfo[ (UINT8)SECTOR( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY ) ].fSurfaceWasEverPlayerControlled = TRUE;
StrategicMap[ (UINT8)SECTOR( gGameExternalOptions.ubDefaultArrivalSectorX, gGameExternalOptions.ubDefaultArrivalSectorY ) ].fEnemyControlled = FALSE;
if ( gGameUBOptions.InJerry == TRUE )
{
//Set some variable so Jerry will be on the ground
pSoldier->fWaitingToGetupFromJA25Start = TRUE;
pSoldier->fIgnoreGetupFromCollapseCheck = TRUE;
//pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO; //to by³o wy³¹czone
//pSoldier->usStrategicInsertionData = GetInitialHeliGridNo( ); //to by³o wy³¹czone
RESETTIMECOUNTER( pSoldier->GetupFromJA25StartCounter, gsInitialHeliRandomTimes[ 6 ] + 800 + Random( 400 ) );
//should we be on our back or tummy
if( Random( 100 ) < 50 )
pSoldier->EVENT_InitNewSoldierAnim( STAND_FALLFORWARD_STOP, 1, TRUE );
else
pSoldier->EVENT_InitNewSoldierAnim( FALLBACKHIT_STOP, 1, TRUE );
}
//Wont work cause it gets reset every frame
//make sure we can see Jerry
if ( gGameUBOptions.InJerry == TRUE )
{
pJerrySoldier = FindSoldierByProfileID(76, FALSE );//JERRY
if( pJerrySoldier != NULL )
{
//Make sure we can see the pilot
gbPublicOpplist[OUR_TEAM][ pJerrySoldier->ubID ] = SEEN_CURRENTLY;
pJerrySoldier->bVisible = TRUE;
}
}
//Lock the interface
guiPendingOverrideEvent = LU_BEGINUILOCK;
}
}
void AddItemToMerc( UINT8 ubNewMerc, INT16 sItemType )
{
// OK, give this item to our merc!
OBJECTTYPE gTempObject;
BOOLEAN fReturn=FALSE;
// make an objecttype
CreateItem(sItemType, 100, &gTempObject);
// Give it
fReturn = AutoPlaceObject( MercPtrs[ ubNewMerc ], &gTempObject, FALSE );
if(!fReturn && (UsingNewInventorySystem() == true))
{
(MercPtrs[ubNewMerc]->inv[NUM_INV_SLOTS-1]) = gTempObject;
fReturn=TRUE;
}
Assert( fReturn );
}
#endif
+9 -1
View File
@@ -41,6 +41,9 @@ typedef struct
extern INT16 gsMercArriveSectorX;
extern INT16 gsMercArriveSectorY;
//ja25ub
//extern BOOLEAN gfFirstTimeInGameHeliCrash;
INT8 HireMerc( MERC_HIRE_STRUCT *pHireMerc);
void MercArrivesCallback( UINT8 ubSoldierID );
@@ -55,4 +58,9 @@ void UpdateAnyInTransitMercsWithGlobalArrivalSector( );
UINT32 GetMercArrivalTimeOfDay( );
extern INT16 StrategicPythSpacesAway(INT16 sOrigin, INT16 sDest);
#endif
#ifdef JA2UB
void UpdateJerryMiloInInitialSector();
void InitializeHeliGridnoAndTime( BOOLEAN fLoading );
void InitJerryMiloInfo();
#endif
#endif
+370 -16
View File
@@ -119,6 +119,13 @@
#include "Luaglobal.h"
#include "LuaInitNPCs.h"
#include "Interface.h"
#include "Vehicles.h"
#ifdef JA2UB
#include "Ja25 Strategic Ai.h"
#include "Ja25_Tactical.h"
#include "Soldier Control.h"
#include "ub_config.h"
#endif
// OJW - 20090419
UINT8 giMAXIMUM_NUMBER_OF_PLAYER_MERCS = CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS;
@@ -194,6 +201,13 @@ extern UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndRead
extern void PlayStealthySoldierFootstepSound( SOLDIERTYPE *pSoldier );
#ifdef JA2UB
BOOLEAN CanMsgBoxForPlayerToBeNotifiedOfSomeoneElseInSector();
extern void PlayStealthySoldierFootstepSound( SOLDIERTYPE *pSoldier );
//extern BOOLEAN gfFirstTimeInGameHeliCrash; //JA25 UB
#endif
extern BOOLEAN gfSurrendered;
// GLOBALS
@@ -1087,7 +1101,46 @@ BOOLEAN ExecuteOverhead( )
*/
}
}
#ifdef JA2UB
//Ja25 UB
// ATE: JA25 additon - poll for getting up from start of game...
if( pSoldier->fWaitingToGetupFromJA25Start )
{
if( !DialogueActive( ) )
{
///if the timer is done, AND no one is talking
if( TIMECOUNTERDONE( pSoldier->GetupFromJA25StartCounter, 0 ) )
{
//make sure they wont say this again
pSoldier->fWaitingToGetupFromJA25Start = FALSE;
//
//Get the soldier that should say the quote
//
//if the merc is one of the mercs who has Quote 80, say that
if( pSoldier->ubProfile == 58 ||//GASTON
pSoldier->ubProfile == 59 ||//STOGIE
pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__PLAYER_CHARACTER )
{
TacticalCharacterDialogue( pSoldier, QUOTE_REPUTATION_REFUSAL );
}
else
{
// Now make them say their curse sound
pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 );
}
SpecialCharacterDialogueEvent( DIALOGUE_SPECIAL_EVENT_MULTIPURPOSE, pSoldier->ubProfile, 0, 0, pSoldier->iFaceIndex, 0 );
}
}
else
{
pSoldier->GetupFromJA25StartCounter += giTimerDiag;
}
}
#endif
// Checkout fading
if ( pSoldier->flags.fBeginFade )
{
@@ -1333,6 +1386,21 @@ BOOLEAN ExecuteOverhead( )
// Cancel reverse
pSoldier->bReverse = FALSE;
BOOLEAN fAimAfterMove = FALSE;
if ( pSoldier->usAnimState == SIDE_STEP_PISTOL_RDY || pSoldier->usAnimState == SIDE_STEP_RIFLE_RDY ||
pSoldier->usAnimState == WALKING_PISTOL_RDY || pSoldier->usAnimState == WALKING_RIFLE_RDY )
{
fAimAfterMove = TRUE;
pSoldier->usPendingAnimation = AIM_RIFLE_STAND;
pSoldier->ubPendingDirection = pSoldier->ubDirection;
}
else if ( pSoldier->usAnimState == SIDE_STEP_DUAL_RDY || pSoldier->usAnimState == WALKING_DUAL_RDY )
{
fAimAfterMove = TRUE;
pSoldier->usPendingAnimation = AIM_DUAL_STAND;
pSoldier->ubPendingDirection = pSoldier->ubDirection;
}
// OK, if we are the selected soldier, refresh some UI stuff
if ( pSoldier->ubID == (UINT8)gusSelectedSoldier )
{
@@ -1591,7 +1659,10 @@ BOOLEAN ExecuteOverhead( )
{
UnSetUIBusy( pSoldier->ubID );
pSoldier->SoldierGotoStationaryStance( );
if ( !fAimAfterMove ) // SANDRO - don't do this after movement with weapon raised
{
pSoldier->SoldierGotoStationaryStance( );
}
}
}
}
@@ -1740,7 +1811,10 @@ BOOLEAN ExecuteOverhead( )
dAngle = gdRadiansForAngle[ pSoldier->bMovementDirection ];
// For walking, base it on body type!
if ( pSoldier->usAnimState == WALKING )
if ( pSoldier->usAnimState == WALKING ||
pSoldier->usAnimState == WALKING_PISTOL_RDY ||
pSoldier->usAnimState == WALKING_RIFLE_RDY ||
pSoldier->usAnimState == WALKING_DUAL_RDY )
{
pSoldier->MoveMerc( gubAnimWalkSpeeds[ pSoldier->ubBodyType ].dMovementChange, dAngle, TRUE );
@@ -1814,6 +1888,37 @@ BOOLEAN ExecuteOverhead( )
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - hack! - resolve possible pending interrupt
if(GetSoldier(&pSoldier, gusSelectedSoldier) && gGameExternalOptions.fImprovedInterruptSystem )
{
if ( pSoldier->bActive )
{
if ( ResolvePendingInterrupt( pSoldier, UNDEFINED_INTERRUPT ) )
{
fKeepMoving = FALSE;
pSoldier->AdjustNoAPToFinishMove( TRUE );
pSoldier->usPendingAnimation = NO_PENDING_ANIMATION;
pSoldier->ubPendingDirection = NO_PENDING_DIRECTION;
// "artificially" set lock ui flag in this case
if (pSoldier->bTeam == gbPlayerNum)
{
AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, Message[STR_INTERRUPT] );
guiPendingOverrideEvent = LU_BEGINUILOCK;
HandleTacticalUI( );
}
// return early
gubNPCAPBudget = 0;
gubNPCDistLimit = 0;
return( TRUE );
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Turn off auto bandage if we need to...
if ( gTacticalStatus.fAutoBandageMode )
{
@@ -2442,8 +2547,8 @@ BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLE
}
else
{
// Adjust AP/Breathing points to move
DeductPoints( pSoldier, sAPCost, sBPCost );
// Adjust AP/Breathing points to move
DeductPoints( pSoldier, sAPCost, sBPCost, MOVEMENT_INTERRUPT );
}
// OK, let's check for monsters....
@@ -2702,7 +2807,7 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving )
// Set "interrupt occurred" flag to false so that we will know whether *this
// particular call* to HandleSight caused an interrupt
gTacticalStatus.fInterruptOccurred = FALSE;
gTacticalStatus.fInterruptOccurred = FALSE;
if ( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
{
@@ -2724,6 +2829,17 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving )
HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO | SIGHT_INTERRUPT);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - if pending interrupt flag was set for movement type of interupt, resolve it here
if ( gGameExternalOptions.fImprovedInterruptSystem )
{
if ( ResolvePendingInterrupt( pSoldier, MOVEMENT_INTERRUPT ) )
{
AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, Message[STR_INTERRUPT] );
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ATE: Check if we have sighted anyone, if so, don't do anything else...
// IN other words, we have stopped from sighting...
if (gTacticalStatus.fInterruptOccurred)
@@ -2860,7 +2976,7 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving )
pSoldier->EVENT_StopMerc( pSoldier->sGridNo, pSoldier->ubDirection );
SetFactTrue( FACT_SKYRIDER_CLOSE_TO_CHOPPER );
TriggerNPCRecord( SKYRIDER, 15 );
SetUpHelicopterForPlayer( 13, MAP_ROW_B, SKYRIDER );
SetUpHelicopterForPlayer( 13, MAP_ROW_B, gNewVehicle[ HELICOPTER ].NewPilot, HELICOPTER );
}
break;
@@ -3368,6 +3484,9 @@ void HandlePlayerTeamMemberDeath( SOLDIERTYPE *pSoldier )
// handle stuff for Carmen if Slay is killed
switch( pSoldier->ubProfile )
{
#ifdef JA2UB
//Ja25 No carmen
#else
case SLAY:
pTeamSoldier = FindSoldierByProfileID( CARMEN, FALSE );
if (pTeamSoldier && pTeamSoldier->aiData.bAttitude == ATTACKSLAYONLY && !TileIsOutOfBounds(ClosestPC( pTeamSoldier, NULL )) )
@@ -3376,6 +3495,7 @@ void HandlePlayerTeamMemberDeath( SOLDIERTYPE *pSoldier )
TriggerNPCRecord( CARMEN, 29 );
}
break;
#endif
case ROBOT:
if (CheckFact( FACT_FIRST_ROBOT_DESTROYED, 0 ) == FALSE )
{
@@ -3450,8 +3570,10 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
if (pSoldierOld->bTeam == CIV_TEAM )
{
#ifdef JA2UB
#else
SOLDIERTYPE * pOther;
#endif
// ATE: Added string to player
if ( bVisible != -1 && pSoldierOld->ubProfile != NO_PROFILE )
{
@@ -3460,6 +3582,24 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
switch( pSoldierOld->ubProfile )
{
#ifdef JA2UB
case 75: //MORRIS
{
INT8 bSoldierID;
//Geta a random soldier ID
bSoldierID = RandomSoldierIdFromNewMercsOnPlayerTeam();
//if there is any
if( bSoldierID != -1 )
{
//say the MORRIS dead quote
TacticalCharacterDialogue( &Menptr[ bSoldierID ], QUOTE_LEARNED_TO_HATE_MERC_1_ON_TEAM_WONT_RENEW );
}
}
break;
#else //Ja25: none of these characters are in the exp.
case BRENDA:
SetFactTrue( FACT_BRENDA_DEAD );
{
@@ -3598,13 +3738,22 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
HandleNPCDoAction( DOREEN, NPC_ACTION_FREE_KIDS, 0 );
}
break;
// SANDRO - Check if queen bitch is dead
#endif
#ifdef JA2UB
#else
// SANDRO - Check if queen bitch is dead
case QUEEN:
// Muhahahahaaa, QUEST COMPLETED! Give us everything!! Exp, glory, fame!
EndQuest( QUEST_KILL_DEIDRANNA, pSoldierOld->sSectorX, pSoldierOld->sSectorY );
break;
break;
#endif
}
#ifdef JA2UB
// Ja25no queen
#else
// Are we looking at the queen?
if ( pSoldierOld->ubProfile == QUEEN )
{
@@ -3615,7 +3764,7 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
BeginHandleDeidrannaDeath( pKiller, pSoldierOld->sGridNo, pSoldierOld->pathing.bLevel );
}
#endif
// crows/cows are on the civilian team, but none of the following applies to them
if ( ( pSoldierOld->ubBodyType != CROW ) && ( pSoldierOld->ubBodyType != COW ) )
{
@@ -3663,6 +3812,10 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
}
else // enemies and creatures... should any of this stuff not be called if a creature dies?
{
#ifdef JA2UB
//no queen, or queen monster
#else
if ( pSoldierOld->ubBodyType == QUEENMONSTER )
{
SOLDIERTYPE *pKiller = NULL;
@@ -3674,7 +3827,7 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
BeginHandleQueenBitchDeath( pKiller, pSoldierOld->sGridNo, pSoldierOld->pathing.bLevel );
}
}
#endif
if ( pSoldierOld->bTeam == ENEMY_TEAM )
{
gTacticalStatus.ubArmyGuysKilled++;
@@ -3695,7 +3848,9 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
// reset the chosen one!
gTacticalStatus.ubTheChosenOne = NOBODY;
}
#ifdef JA2UB
//no queen, or queen monster
#else
if ( pSoldierOld->ubProfile == QUEEN )
{
HandleMoraleEvent( NULL, MORALE_DEIDRANNA_KILLED, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
@@ -3710,6 +3865,7 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
HandleNPCDoAction( 0, NPC_ACTION_GRANT_EXPERIENCE_5, 0 );
}
#endif
}
@@ -3778,10 +3934,39 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
//if the NPC is a dealer, add the dealers items to the ground
AddDeadArmsDealerItemsToWorld( pSoldierOld->ubProfile );
#ifdef JA2UB
HandleDeathInPowerGenSector( pSoldierOld ); //ja25 ub
HandleWhenCertainPercentageOfEnemiesDie(); //ja25 ub
#endif
//The queen AI layer must process the event by subtracting forces, etc.
ProcessQueenCmdImplicationsOfDeath( pSoldierOld );
#ifdef JA2UB
//------------------- ja25 ub -------------------------
//if the person was Raul, and we are to say the blown up quotes
if( pSoldierOld->ubProfile == PERKO /*RAUL */ && IsJa25GeneralFlagSet( JA_GF__RAUL_BLOW_HIMSELF_UP ) )
{
UINT8 SoldierId1;
UINT8 SoldierId2;
//Get some random Soldier ID's of the valid mercs
if( Get3RandomQualifiedMercs( &SoldierId1, &SoldierId2, NULL ) != 0 )
{
//Say the "he blew himself up quote"
TacticalCharacterDialogue( &Menptr[SoldierId1], QUOTE_GREETING );
//if there isnt a second soldier
if( SoldierId2 == NOBODY )
{
SoldierId2 = SoldierId1;
}
//say the "darn he took the inventoruy with him"
TacticalCharacterDialogue( &Menptr[SoldierId2], QUOTE_SMALL_TALK );
}
}
#endif
// OK, check for existence of any more badguys!
CheckForEndOfBattle( FALSE );
}
@@ -3905,10 +4090,14 @@ void MakeCivHostile( SOLDIERTYPE *pSoldier, INT8 bNewSide )
switch( pSoldier->ubProfile )
{
#ifdef JA2UB
//Ja25 No Ira, miguel, etc
#else
case IRA:
case DIMITRI:
case MIGUEL:
case CARLOS:
#endif
case MADLAB:
case DYNAMO:
case SHANK:
@@ -3989,6 +4178,16 @@ void MakeCivHostile( SOLDIERTYPE *pSoldier, INT8 bNewSide )
{
CheckForPotentialAddToBattleIncrement( pSoldier );
}
//uses Lua
PROFILLUA2_ubProfile = pSoldier->ubProfile;
PROFILLUA2_sSectorX = pSoldier->sSectorX;
PROFILLUA2_sSectorY = pSoldier->sSectorY;
PROFILLUA2_bSectorZ = pSoldier->bSectorZ;
PROFILLUA2_sGridNo = pSoldier->sGridNo;
//LetLuaMyCustomHandleAtNewGridNo(bNewSide,NULL, 1);
}
UINT8 CivilianGroupMembersChangeSidesWithinProximity( SOLDIERTYPE * pAttacked )
@@ -5703,6 +5902,7 @@ void CommonEnterCombatModeCode( )
gTacticalStatus.fLastBattleWon = FALSE;
gTacticalStatus.fItemsSeenOnAttack = FALSE;
gTacticalStatus.ubInterruptPending = DISABLED_INTERRUPT;
// ATE: If we have an item pointer end it!
CancelItemPointer( );
@@ -5748,6 +5948,9 @@ void CommonEnterCombatModeCode( )
// carryover for this battle. So we'll hit it again.
pSoldier->CalcNewActionPoints( );
// SANDRO - Improved Interrupt System - reset interrupt counter
memset(pSoldier->aiData.ubInterruptCounter,0,sizeof(pSoldier->aiData.ubInterruptCounter));
if ( pSoldier->ubProfile != NO_PROFILE )
{
if ( pSoldier->bTeam == CIV_TEAM && pSoldier->aiData.bNeutral )
@@ -5971,6 +6174,11 @@ void ExitCombatMode( )
// since this would be the same as what would happen at the end of the turn
gTacticalStatus.uiTimeSinceLastOpplistDecay = __max( 0, GetWorldTotalSeconds() - TIME_BETWEEN_RT_OPPLIST_DECAYS );
NonCombatDecayPublicOpplist( GetWorldTotalSeconds() );
#ifdef JA2UB
//if we are in J13 and the fan is stopped, handle it
HandleFanStartingAtEndOfCombat();
#endif
}
@@ -5989,7 +6197,14 @@ void SetEnemyPresence( )
// Change music modes..
// If we are just starting game, don't do this!
#ifdef JA2UB
//Ja25: no meanwhiles
if ( !DidGameJustStart() )
#else
if ( !DidGameJustStart() && !AreInMeanwhile( ) )
#endif
{
SetMusicMode( MUSIC_TACTICAL_ENEMYPRESENT );
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("SetEnemyPresence: warnings = false"));
@@ -6512,7 +6727,11 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated )
SetFactTrue( FACT_FIRST_BATTLE_FOUGHT );
SetFactFalse( FACT_FIRST_BATTLE_BEING_FOUGHT );
SetTheFirstBattleSector( (INT16) (gWorldSectorX + gWorldSectorY * MAP_WORLD_X) );
#ifdef JA2UB
//Ja25 no meanwhile
#else
HandleFirstBattleEndingWhileInTown( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, FALSE );
#endif
}
if( NumEnemyInSectorExceptCreatures() )
@@ -6766,7 +6985,11 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated )
SetFactTrue( FACT_FIRST_BATTLE_WON );
SetFactFalse( FACT_FIRST_BATTLE_BEING_FOUGHT );
SetTheFirstBattleSector( (INT16) (gWorldSectorX + gWorldSectorY * MAP_WORLD_X) );
#ifdef JA2UB
//Ja25 no meanwhile
#else
HandleFirstBattleEndingWhileInTown( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, FALSE );
#endif
}
}
@@ -7932,6 +8155,10 @@ BOOLEAN ProcessImplicationsOfPCAttack( SOLDIERTYPE * pSoldier, SOLDIERTYPE ** pp
}
else
{
#ifdef JA2UB
//Ja25: No carmen
#else
if (pTarget->ubProfile == CARMEN)// Carmen
{
// Special stuff for Carmen the bounty hunter
@@ -7941,7 +8168,7 @@ BOOLEAN ProcessImplicationsOfPCAttack( SOLDIERTYPE * pSoldier, SOLDIERTYPE ** pp
pTarget->aiData.bAttitude = AGGRESSIVE;
}
}
#endif
if ( pTarget->ubCivilianGroup && ( (pTarget->bTeam == gbPlayerNum) || pTarget->aiData.bNeutral ) )
{
#ifdef JA2TESTVERSION
@@ -8184,7 +8411,9 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( )
return( NULL );
}
}
#ifdef JA2UB
//Ja25 no queen
#else
// ATE: IN MEANWHILES, we have 'combat' in realtime....
// this is so we DON'T call freeupattacker() which will cancel
// the AI guy's meanwhile NPC stuff.
@@ -8193,7 +8422,7 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( )
{
return( NULL );
}
#endif
#if 0
// 0verhaul: This is moved to the end loop where everybody's state is reset for the next action
if (pTarget)
@@ -8334,7 +8563,11 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( )
// Go into combat!
// If we are in a meanwhile... don't enter combat here...
#ifdef JA2UB
//Ja25 no meanwhiles
#else
if ( !AreInMeanwhile( ) )
#endif
{
EnterCombatMode( pSoldier->bTeam );
}
@@ -8427,6 +8660,25 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( )
pSoldier->sLastTarget = pSoldier->sTargetGridNo;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - if pending interrupt flag was set for after-shot type of interupt, try to resolve it now
if ( gGameExternalOptions.fImprovedInterruptSystem )
{
if ( ResolvePendingInterrupt( pSoldier, AFTERSHOT_INTERRUPT ) )
{
pSoldier->usPendingAnimation = NO_PENDING_ANIMATION;
pSoldier->ubPendingDirection = NO_PENDING_DIRECTION;
// "artificially" set lock ui flag
if (pSoldier->bTeam == gbPlayerNum)
{
AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, Message[STR_INTERRUPT] );
guiPendingOverrideEvent = LU_BEGINUILOCK;
HandleTacticalUI( );
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Reset various flags and values that should be 0 once the action is overwith
for (cnt = 0; cnt < guiNumMercSlots; cnt++)
{
@@ -9199,3 +9451,105 @@ INT8 CheckStatusNearbyFriendlies( SOLDIERTYPE *pSoldier )
return(sModifier);
}
#ifdef JA2UB
void SetMsgBoxForPlayerBeNotifiedOfSomeoneElseInSector()
{
//if the player in the same sector as MANUEL
if( !CanMsgBoxForPlayerToBeNotifiedOfSomeoneElseInSector() )
{
return;
}
gJa25SaveStruct.fShouldMsgBoxComeUpSayingSomeoneImportantIsInSector = TRUE;
}
void HandleThePlayerBeNotifiedOfSomeoneElseInSector()
{
//if we shouldnt be here, get out
if( !gJa25SaveStruct.fShouldMsgBoxComeUpSayingSomeoneImportantIsInSector )
{
return;
}
//if somehting else is going on, leave
if( gTacticalStatus.fAutoBandageMode ||
DialogueActive( ) ||
gTacticalStatus.fAutoBandagePending ||
guiPendingScreen == MSG_BOX_SCREEN ||
guiCurrentScreen == MSG_BOX_SCREEN ||
AreWeInAUIMenu( )
)
{
return;
}
gJa25SaveStruct.fShouldMsgBoxComeUpSayingSomeoneImportantIsInSector = FALSE;
//if the player in the same sector as MANUEL
if( !CanMsgBoxForPlayerToBeNotifiedOfSomeoneElseInSector() )
{
return;
}
DoMessageBox( MSG_BOX_BASIC_STYLE, zNewTacticalMessages[ TACT_MSG__SOMEONE_ELSE_IN_SECTOR ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_OK, NULL, NULL );
}
BOOLEAN CanMsgBoxForPlayerToBeNotifiedOfSomeoneElseInSector()
{
// ATE: if this is a custom map, return
/* if ( gbWorldSectorZ == 0 )
{
if ( SectorInfo[ SECTOR( gWorldSectorY, gWorldSectorX ) ].fCustomSector )
{
return( FALSE );
}
}
*/
if( ( gWorldSectorX == gMercProfiles[ 60 ].sSectorX && gWorldSectorY == gMercProfiles[ 60 ].sSectorY && gbWorldSectorZ == gMercProfiles[ 60 ].bSectorZ ) )
{
//IF MANUEL is already hired
if( gMercProfiles[ 60 ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED )
{
//then we shouldnt display the message
return( FALSE );
}
return( TRUE );
}
return( FALSE );
}
INT8 NumMercsOnPlayerTeam( )
{
INT32 cnt;
SOLDIERTYPE *pSoldier;
UINT8 ubCount = 0;
cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;
// look for all mercs on the same team,
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; cnt++,pSoldier++)
{
if( pSoldier->bActive && pSoldier->stats.bLife > 0 )
{
ubCount++;
}
}
return( ubCount );
}
void HandleDisplayingOfPlayerLostDialogue( void )
{
//if the laptop transmitter is broken, and the player doesnt have any other team members
if( gubQuest[ QUEST_FIX_LAPTOP ] != QUESTDONE && NumMercsOnPlayerTeam( ) == 0 && gGameUBOptions.LaptopQuestEnabled == TRUE )
{
gJa25SaveStruct.ubDisplayPlayerLostMsgBox = 1;
}
}
#endif
+14 -1
View File
@@ -179,8 +179,9 @@ typedef struct
UINT8 ubMorePadding;
UINT16 sCreatureTenseQuoteDelay;
UINT32 uiCreatureTenseQuoteLastUpdate;
// SANDRO - added this
// SANDRO - added these
UINT8 ubLastRequesterSurgeryTargetID;
UINT8 ubInterruptPending;
// PADDING GONE!!!!!
@@ -366,6 +367,18 @@ UINT8 NumPCsInSector( void );
void SetSoldierNonNeutral( SOLDIERTYPE * pSoldier );
void SetSoldierNeutral( SOLDIERTYPE * pSoldier );
#ifdef JA2UB
void HandleThePlayerBeNotifiedOfSomeoneElseInSector();
void SetMsgBoxForPlayerBeNotifiedOfSomeoneElseInSector();
void HandleDisplayingOfPlayerLostDialogue( void );
// UTILITY FUNCTIONS
INT8 NumActiveAndConsciousTeamMembers( UINT8 ubTeam );
UINT8 NumEnemyInSector( );
UINT8 NumCapableEnemyInSector( );
INT8 NumMercsOnPlayerTeam( );
#endif
extern BOOLEAN sniperwarning;
extern BOOLEAN biggunwarning;
+41 -1
View File
@@ -3539,7 +3539,18 @@ if(!GridNoOnVisibleWorldTile(iDestination))
ubAPCost += APBPConstants[AP_MODIFIER_RUN];
//ubAPCost = (INT16)(DOUBLE)( (sTileCost / RUNDIVISOR) ); break;
break;
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
ubAPCost += APBPConstants[AP_MODIFIER_WALK] + APBPConstants[AP_MODIFIER_READY]; //WALKCOST);
break;
case WALKING:
ubAPCost += APBPConstants[AP_MODIFIER_WALK]; //WALKCOST);
if (!(s->MercInWater()) && ( (gAnimControl[ s->usAnimState ].uiFlags & ANIM_FIREREADY ) || (gAnimControl[ s->usAnimState ].uiFlags & ANIM_FIRE ) ))
{
ubAPCost += APBPConstants[AP_MODIFIER_READY]; //WALKCOST);
}
break;
case ROBOT_WALK:
ubAPCost += APBPConstants[AP_MODIFIER_WALK]; //WALKCOST);
break;
@@ -3573,6 +3584,9 @@ if(!GridNoOnVisibleWorldTile(iDestination))
{
case RUNNING:
case WALKING :
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
// Here pessimistically assume the path will continue after hopping the fence
ubAPCost += GetAPsCrouch( s, TRUE ); // SANDRO - changed
break;
@@ -3595,6 +3609,9 @@ if(!GridNoOnVisibleWorldTile(iDestination))
{
case RUNNING:
case WALKING :
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
// charge crouch APs for ducking head!
ubAPCost += GetAPsCrouch( s, TRUE ); // SANDRO - changed
break;
@@ -4452,6 +4469,9 @@ INT32 PlotPath( SOLDIERTYPE *pSold, INT32 sDestGridNo, INT8 bCopyRoute, INT8 bPl
{
case RUNNING:
case WALKING :
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
// Add here cost to go from crouch to stand AFTER fence hop....
// Since it's AFTER.. make sure we will be moving after jump...
@@ -4493,6 +4513,9 @@ INT32 PlotPath( SOLDIERTYPE *pSold, INT32 sDestGridNo, INT8 bCopyRoute, INT8 bPl
{
case RUNNING:
case WALKING :
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
// charge crouch APs for ducking head!
sExtraCostStand += GetAPsCrouch(pSold, TRUE); // changed by SANDRO
break;
@@ -4513,7 +4536,19 @@ INT32 PlotPath( SOLDIERTYPE *pSold, INT32 sDestGridNo, INT8 bCopyRoute, INT8 bPl
sMovementAPsCost = sTileCost + APBPConstants[AP_MODIFIER_RUN];
break;
case WALKING:
sMovementAPsCost = sTileCost + APBPConstants[AP_MODIFIER_WALK];
if (!(pSold->MercInWater()) && ( (gAnimControl[ pSold->usAnimState ].uiFlags & ANIM_FIREREADY ) || (gAnimControl[ pSold->usAnimState ].uiFlags & ANIM_FIRE ) ))
{
sMovementAPsCost = sTileCost + APBPConstants[AP_MODIFIER_WALK] + APBPConstants[AP_MODIFIER_READY];
}
else
{
sMovementAPsCost = sTileCost + APBPConstants[AP_MODIFIER_WALK];
}
break;
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
sMovementAPsCost = sTileCost + APBPConstants[AP_MODIFIER_WALK] + APBPConstants[AP_MODIFIER_READY];
break;
case SWATTING:
sMovementAPsCost = sTileCost + APBPConstants[AP_MODIFIER_SWAT];
@@ -4593,6 +4628,11 @@ INT32 PlotPath( SOLDIERTYPE *pSold, INT32 sDestGridNo, INT8 bCopyRoute, INT8 bPl
sPointsSwat += sMovementAPsCost + APBPConstants[AP_MODIFIER_SWAT];
sPointsRun += sMovementAPsCost + APBPConstants[AP_MODIFIER_RUN];
}
// walking with weapon raised?
if (!(pSold->MercInWater()) && ( (gAnimControl[ pSold->usAnimState ].uiFlags & ANIM_FIREREADY ) || (gAnimControl[ pSold->usAnimState ].uiFlags & ANIM_FIRE ) ))
{
sPointsWalk += APBPConstants[AP_MODIFIER_READY];
}
// Check for stealth mode
if ( pSold->bStealthMode || bStealth )
{
+153 -3
View File
@@ -34,6 +34,8 @@
#include "Map Information.h"
#include "Interface Items.h"
#include "Soldier Control.h" // added by SANDRO
#include "opplist.h" // added by SANDRO
#include "lighting.h" // added by SANDRO
#endif
#include "connect.h"
//rain
@@ -275,6 +277,11 @@ INT16 TerrainBreathPoints(SOLDIERTYPE * pSoldier, INT32 sGridNo, INT8 bDir, UINT
return(0);
}
if ( ubMovementCost == WALKING_PISTOL_RDY || ubMovementCost == WALKING_RIFLE_RDY || ubMovementCost == WALKING_DUAL_RDY )
{
iPoints += APBPConstants[BP_MOVEMENT_READY];
}
iPoints = iPoints * BreathPointAdjustmentForCarriedWeight( pSoldier ) / 100;
// ATE - MAKE MOVEMENT ALWAYS WALK IF IN WATER
@@ -293,9 +300,15 @@ INT16 TerrainBreathPoints(SOLDIERTYPE * pSoldier, INT32 sGridNo, INT8 bDir, UINT
iPoints *= APBPConstants[BP_RUN_ENERGYCOSTFACTOR]; break;
case SIDE_STEP:
case SIDE_STEP_PISTOL_RDY:
case SIDE_STEP_RIFLE_RDY:
case SIDE_STEP_DUAL_RDY:
case WALK_BACKWARDS:
case BLOODCAT_WALK_BACKWARDS:
case MONSTER_WALK_BACKWARDS:
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
case WALKING : iPoints *= APBPConstants[BP_WALK_ENERGYCOSTFACTOR]; break;
case START_SWAT:
@@ -310,7 +323,7 @@ INT16 TerrainBreathPoints(SOLDIERTYPE * pSoldier, INT32 sGridNo, INT8 bDir, UINT
// SANDRO - STOMP traits - Athletics reduce breath points spent for moving
if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, ATHLETICS_NT ))
{
iPoints = max(1, (INT16)((iPoints * (100 - gSkillTraitValues.ubATAPsMovementReduction) / 100) + 0.5));
iPoints = max(1, (INT16)((iPoints * (100 - gSkillTraitValues.ubATBPsMovementReduction) / 100) + 0.5));
}
// ATE: Adjust these by realtime movement
@@ -378,6 +391,18 @@ INT16 ActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, UINT16 u
case LARVAE_WALK:
case WALKING :
sPoints = sTileCost + APBPConstants[AP_MODIFIER_WALK];
if ( usMovementMode == WALKING && !(pSoldier->MercInWater()) && ( (gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FIREREADY ) || (gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FIRE ) ))
{
sPoints += APBPConstants[AP_MODIFIER_READY];
}
break;
case SIDE_STEP_PISTOL_RDY:
case SIDE_STEP_RIFLE_RDY:
case SIDE_STEP_DUAL_RDY:
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
sPoints = sTileCost + APBPConstants[AP_MODIFIER_WALK] + APBPConstants[AP_MODIFIER_READY];
break;
case START_SWAT:
case SWAT_BACKWARDS:
@@ -435,8 +460,14 @@ INT16 ActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, UINT16 u
{
case RUNNING:
case WALKING :
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
case LARVAE_WALK:
case SIDE_STEP:
case SIDE_STEP_PISTOL_RDY:
case SIDE_STEP_RIFLE_RDY:
case SIDE_STEP_DUAL_RDY:
case WALK_BACKWARDS:
// charge crouch APs for ducking head!
sPoints += GetAPsCrouch(pSoldier, TRUE); // SANDRO changed
@@ -501,6 +532,18 @@ INT16 EstimateActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir,
case LARVAE_WALK:
case WALKING :
sPoints = sTileCost + APBPConstants[AP_MODIFIER_WALK];
if (!(pSoldier->MercInWater()) && ( (gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FIREREADY ) || (gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FIRE ) ))
{
sPoints += APBPConstants[AP_MODIFIER_READY];
}
break;
case SIDE_STEP_PISTOL_RDY:
case SIDE_STEP_RIFLE_RDY:
case SIDE_STEP_DUAL_RDY:
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
sPoints = sTileCost + APBPConstants[AP_MODIFIER_WALK] + APBPConstants[AP_MODIFIER_READY];
break;
case START_SWAT:
case SWAT_BACKWARDS:
@@ -564,9 +607,15 @@ INT16 EstimateActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir,
switch(usMovementMode)
{
case SIDE_STEP:
case SIDE_STEP_PISTOL_RDY:
case SIDE_STEP_RIFLE_RDY:
case SIDE_STEP_DUAL_RDY:
case WALK_BACKWARDS:
case RUNNING:
case WALKING :
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
// Add here cost to go from crouch to stand AFTER fence hop....
// Since it's AFTER.. make sure we will be moving after jump...
@@ -596,7 +645,13 @@ INT16 EstimateActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir,
{
case RUNNING:
case WALKING :
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
case SIDE_STEP:
case SIDE_STEP_PISTOL_RDY:
case SIDE_STEP_RIFLE_RDY:
case SIDE_STEP_DUAL_RDY:
case WALK_BACKWARDS:
// charge crouch APs for ducking head!
sPoints += GetAPsCrouch(pSoldier, TRUE); // SANDRO changed..
@@ -670,7 +725,7 @@ BOOLEAN EnoughPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost, BOOLE
}
void DeductPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost,BOOLEAN fProactive )
void DeductPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost, UINT8 ubInterruptType )
{
INT16 sNewAP = 0;
INT8 bNewBreath;
@@ -733,7 +788,7 @@ void DeductPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost,BOOLEAN f
// Snap: award some health and strength for exertion
// Do 4 StatChange rolls for health (2 for strength) per 10 breath points spent?
// NB: The scale of iBPCost is 100 per breath point (APBPConstants[BP_RATIO_RED_PTS_TO_NORMAL])
if ( PTR_OURTEAM && iBPCost >= APBPConstants[BP_MOVEMENT_GRASS] && fProactive
if ( PTR_OURTEAM && iBPCost >= APBPConstants[BP_MOVEMENT_GRASS] && ubInterruptType != DISABLED_INTERRUPT
&& (INT32) PreRandom( 10 * APBPConstants[BP_RATIO_RED_PTS_TO_NORMAL] ) < iBPCost )
{
StatChange(pSoldier, HEALTHAMT, 4, FALSE);
@@ -791,6 +846,95 @@ void DeductPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost,BOOLEAN f
// UPDATE BAR
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL1 );
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - Interrupt counter
if( gGameExternalOptions.fImprovedInterruptSystem && sAPCost > 0 && ubInterruptType != DISABLED_INTERRUPT )
{
UINT8 ubPointsRegistered = 0;
UINT16 uCnt = 0;
SOLDIERTYPE *pOpponent;
BOOLEAN fFoundInterrupter = FALSE;
for ( uCnt = 0; uCnt <= MAX_NUM_SOLDIERS; uCnt++ )
{
// first find all guys who watch us
pOpponent = MercPtrs[ uCnt ];
if ( pOpponent == NULL)
continue; // not here or not even breathing -> next!
if ( pOpponent->stats.bLife < OKLIFE || pOpponent->bCollapsed || !pOpponent->bActive )
continue; // not here or not even breathing -> next!
if ( pSoldier->bTeam == pOpponent->bTeam )
continue; // same team? -> next!
if ( pSoldier->bSide == pOpponent->bSide )
continue; // not enemy
if ( CONSIDERED_NEUTRAL( pSoldier, pOpponent ) )
continue; // neutral
// if we see or hear him
// dunno if this is the best solution yet, probably yes
if ( pOpponent->aiData.bOppList[pSoldier->ubID] == SEEN_CURRENTLY ||
pOpponent->aiData.bOppList[pSoldier->ubID] == HEARD_THIS_TURN)
//if (SoldierToSoldierLineOfSightTest( pOpponent, pSoldier, TRUE, CALC_FROM_WANTED_DIR ) != 0)
{
// calculate how much points do we "register" (let's try to avoid chance-based calc to not inspire save-load mania)
// Experience says how well is the observer able to notice and percieve the environment around him, i.e. gives us the actual chance per AP
if ( pOpponent->aiData.bOppList[pSoldier->ubID] == HEARD_THIS_TURN )
{
// if we only heard him, keep it lower
ubPointsRegistered = (gGameExternalOptions.ubBasicPercentRegisterValueIIS - 20)
+ (gGameExternalOptions.ubPercentRegisterValuePerLevelIIS * EffectiveExpLevel( pOpponent )); // base 40% + 4% per level
}
else
{
ubPointsRegistered = gGameExternalOptions.ubBasicPercentRegisterValueIIS
+ (gGameExternalOptions.ubPercentRegisterValuePerLevelIIS * EffectiveExpLevel( pOpponent )); // base 60% + 4% per level
}
// adjust by range to target
//INT32 iRange = GetRangeInCellCoordsFromGridNoDiff( pOpponent->sGridNo, pSoldier->sGridNo ); // calculate actual range
//INT16 iDistVisible = (pOpponent->GetMaxDistanceVisible(pOpponent->sGridNo, pOpponent->bTargetLevel, CALC_FROM_ALL_DIRS ) * CELL_X_SIZE); // how far do we see
ubPointsRegistered -= ( 25 * GetRangeInCellCoordsFromGridNoDiff( pOpponent->sGridNo, pSoldier->sGridNo ) /
(pOpponent->GetMaxDistanceVisible(pOpponent->sGridNo, pOpponent->bTargetLevel, CALC_FROM_ALL_DIRS ) * CELL_X_SIZE) ); // -1% registered by 4% of the difference of how far we can see and how far is the target
if ( gGameOptions.fNewTraitSystem )
{
// Martial Arts trait reduces the points registered when moving
if ( HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) && (ubInterruptType == SP_MOVEMENT_INTERRUPT || ubInterruptType == MOVEMENT_INTERRUPT ))
{
ubPointsRegistered -= gSkillTraitValues.ubMAReducedAPsRegisteredWhenMoving * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT );
}
// Stealhty trait reduced the points registered on all actions
if ( HAS_SKILL_TRAIT( pSoldier, STEALTHY_NT ) )
{
ubPointsRegistered -= gSkillTraitValues.ubSTReducedAPsRegistered;
}
}
// ALRIGHT! Get final value
ubPointsRegistered = max( 5, min( 100, ubPointsRegistered ) ); // 5% is minimum, 100% maximum
ubPointsRegistered = (UINT8)((sAPCost * ubPointsRegistered / 100) + 0.5); // now calc how many APs we will award and store it in ubPointsRegistered
// increase the counter
if ( ubPointsRegistered )
{
pOpponent->aiData.ubInterruptCounter[pSoldier->ubID] += ubPointsRegistered;
fFoundInterrupter = TRUE;
}
}
}
// if interrupted, freeze our guy and trigger interrupt situation
if (fFoundInterrupter)
{
// if we've got the special movement flag type here, pass it to after-action type
// it's only meant for martial arts bonuses
if ( ubInterruptType == SP_MOVEMENT_INTERRUPT )
{
ubInterruptType = AFTERACTION_INTERRUPT;
}
// OK, something happened, set the interrupt pending flag
gTacticalStatus.ubInterruptPending = ubInterruptType;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
@@ -1107,6 +1251,9 @@ INT16 GetBreathPerAP( SOLDIERTYPE *pSoldier, UINT16 usAnimState )
break;
case WALKING:
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
sBreathPerAP = APBPConstants[BP_PER_AP_LT_EFFORT];
break;
@@ -2111,6 +2258,9 @@ INT8 MinAPsToStartMovement( SOLDIERTYPE * pSoldier, UINT16 usMovementMode )
{
case RUNNING:
case WALKING:
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
if (gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)
{
bAPs += GetAPsCrouch(pSoldier, TRUE) + GetAPsProne(pSoldier, TRUE);
+1 -1
View File
@@ -287,7 +287,7 @@ INT16 EstimateActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir,
BOOLEAN SelectedMercCanAffordMove( );
BOOLEAN EnoughPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost, BOOLEAN fDisplayMsg );
void DeductPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost, BOOLEAN fProactive = TRUE );
void DeductPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost, UINT8 ubInterruptType = 2 ); // SANDRO - change for improved interrupt system (ubInterruptType = 2 = UNDEFINED_INTERRUPT)
INT32 AdjustBreathPts(SOLDIERTYPE *pSold, INT32 iBPCost);
void UnusedAPsToBreath(SOLDIERTYPE *pSold);
INT16 TerrainBreathPoints(SOLDIERTYPE * pSoldier, INT32 sGridNo,INT8 bDir, UINT16 usMovementMode);
+3 -1
View File
@@ -45,6 +45,8 @@
#include "Interface.h"
#endif
#include "Animation Control.h"
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
@@ -1332,7 +1334,7 @@ void MercLooksForCorpses( SOLDIERTYPE *pSoldier )
if ( Random( 400 ) <= 2 )
{
INT32 cnt;
INT16 sGridNo;
INT32 sGridNo;
ROTTING_CORPSE *pCorpse;
// Loop through all corpses....
+435 -8
View File
@@ -57,6 +57,17 @@
#include "Interface Enhanced.h"
#endif
#ifdef JA2UB
#include "Explosion Control.h"
#include "Ja25_Tactical.h"
#include "Ja25 Strategic Ai.h"
#include "MapScreen Quotes.h"
#include "email.h"
#include "interface Dialogue.h"
#include "Ja25_Tactical.h"
#include "ub_config.h"
#endif
#include "BuildDefines.h"
#include <algorithm>
@@ -281,13 +292,28 @@ SKIRGBCOLOR SkiGlowColorsA[]={
#define FLO_DISCOUNT_PERCENTAGE 10
#ifdef JA2UB
#define SKI_BETTY_MINIMUM_AMOUNT_TO_SET_FACT 10
#define SKI_RAUL_MINIMUM_AMOUNT_TO_SET_FACT 100
#endif
////////////////////////////////////////////
//
// Global Variables
//
///////////////////////////////////////////
#ifdef JA2UB
//ja25 UB
enum
{
TRNSMTR_MSG_BOX__NONE,
TRNSMTR_MSG_BOX__1_FRAME_WAIT,
TRNSMTR_MSG_BOX__DISPLAY_BOX,
};
void AskUserToAttachTransmitterToLaptop();
void AttachLaptopTransmitterToLaptop( UINT8 ubExitValue );
#endif
UINT32 guiMainTradeScreenImage;
UINT32 guiCornerWhereTacticalIsStillSeenImage; //This image is for where the corner of tactical is still seen through the shop keeper interface
@@ -354,6 +380,9 @@ INT32 giPopUpBoxId=-1;
BOOLEAN gfIsTheShopKeeperTalking;
#ifdef JA2UB
UINT8 gubDisplayMsgBoxAskingUserToAttachTransmitter=0; // Ja25 UB
#endif
// the glow for unwanted items
BOOLEAN fDeltaColorForShopkeepUnwanted = TRUE;
@@ -382,6 +411,10 @@ BOOLEAN gfExitSKIDueToMessageBox=FALSE;
OBJECTTYPE *pShopKeeperItemDescObject=NULL;
#ifdef JA2UB
BOOLEAN gfCanSayMakeTransactionQuote; //ja25 UB
#endif
UINT32 guiNextFreeInvSlot;
BOOLEAN gfStartWithRepairsDelayedQuote = FALSE;
@@ -674,7 +707,6 @@ void HatchOutInvSlot( UINT16 usPosX, UINT16 usPosY );
extern BOOLEAN ItemIsARocketRifle( INT16 sItemIndex );
#ifdef JA2TESTVERSION
BOOLEAN gfTestDisplayDealerCash = FALSE;
void DisplayAllDealersCash();
@@ -1232,7 +1264,15 @@ ATM:
// by default re-enable calls to PerformTransaction()
gfPerformTransactionInProgress = FALSE;
#ifdef JA2UB
//JA25 UB
//if the dealer is RAUL
if( gbSelectedArmsDealerID == ARMS_DEALER_RAUL )
{
//set the fact the raul refreshed his inventory
SetFactFalse( FACT_RAULS_INVENTORY_CHANGED_SINCE_LAST_VISIT );
}
#endif
return( TRUE );
}
@@ -1357,7 +1397,28 @@ BOOLEAN ExitShopKeeperInterface()
MSYS_EnableRegion(&gRadarRegion);
gfSMDisableForItems = FALSE;
#ifdef JA2UB
//JA25 UB
//Check to see if a merc should say something
//CheckForValidQuotesWhenLeavingDealer( gTalkPanel.ubCharNum );
//if the laptop was just fixed
if( gubQuest[ QUEST_FIX_LAPTOP ] == QUESTDONE && !( gJa25SaveStruct.uiJa25GeneralFlags & JA_GF__PLAYER_SAID_LAPTOP_FIXED_QUOTE ) )
{
INT8 bSoldierID=-1;
//Have a new merc say a quote
bSoldierID = RandomSoldierIdFromNewMercsOnPlayerTeam();
if( bSoldierID != -1 )
{
TacticalCharacterDialogue( &Menptr[ bSoldierID ], QUOTE_SPARE2 );
}
gJa25SaveStruct.uiJa25GeneralFlags |= JA_GF__PLAYER_SAID_LAPTOP_FIXED_QUOTE;
}
#endif
return( TRUE );
}
@@ -1483,6 +1544,24 @@ void HandleShopKeeperInterface()
{
DisplayTheSkiDropItemToGroundString();
}
#ifdef JA2UB
//ja25 UB
else if( gubDisplayMsgBoxAskingUserToAttachTransmitter != TRNSMTR_MSG_BOX__NONE )
{
if( gubDisplayMsgBoxAskingUserToAttachTransmitter == TRNSMTR_MSG_BOX__1_FRAME_WAIT )
{
gubDisplayMsgBoxAskingUserToAttachTransmitter = TRNSMTR_MSG_BOX__DISPLAY_BOX;
}
else if( gubDisplayMsgBoxAskingUserToAttachTransmitter == TRNSMTR_MSG_BOX__DISPLAY_BOX )
{
//Tell user that they are attaching the transmitter
AskUserToAttachTransmitterToLaptop();
//clear the flag
gubDisplayMsgBoxAskingUserToAttachTransmitter = TRNSMTR_MSG_BOX__NONE;
}
}
#endif
}
@@ -3086,13 +3165,16 @@ BOOLEAN RepairIsDone(DEALER_SPECIAL_ITEM* pSpecial)
}
}
#ifdef JA2UB
//no UB
#else
// if the item is imprinted (by anyone, even player's mercs), and it's Fredo repairing it
if ( ( gbSelectedArmsDealerID == ARMS_DEALER_FREDO ) )
{
// then reset the imprinting!
RepairItem.ItemObject[0]->data.ubImprintID = NO_PROFILE;
}
#endif
//try to add the item to the players offer area
INT8 bSlotNum;
bSlotNum = AddItemToPlayersOfferArea( RepairItem.ubIdOfMercWhoOwnsTheItem, &RepairItem, -1 );
@@ -3149,6 +3231,9 @@ UINT32 CalcShopKeeperItemPrice( BOOLEAN fDealerSelling, BOOLEAN fUnitPriceOnly,
UINT32 uiTotalPrice = 0;
UINT32 uiDiscountValue;
// UINT32 uiDifFrom10 = 0;
#ifdef JA2UB
UINT8 ubItemsNotCounted = 0; //ja25 UB
#endif
std::vector<UINT32> uiItemPrice;
uiItemPrice.resize(pItemObject->ubNumberOfObjects);
@@ -3267,6 +3352,78 @@ UINT32 CalcShopKeeperItemPrice( BOOLEAN fDealerSelling, BOOLEAN fUnitPriceOnly,
// we're always count the first one
uiTotalPrice = uiUnitPrice;
#ifdef JA2UB
//---------------------------JA25 UB---------------
// if NOT pricing just one
if ( !fUnitPriceOnly )
{
// add value of all that weren't already counted
uiTotalPrice += ( ubItemsNotCounted * uiUnitPrice );
}
//if the dealer is Raul
if( gbSelectedArmsDealerID == ARMS_DEALER_RAUL )
{
//if the item is the antique musket
if( usItemID == HAND_CANNON ) //4498
{
//if the "Find anitque musket" quest is active
if( gubQuest[ QUEST_FIND_ANTIQUE_MUSKET_FOR_RAUL ] == QUESTINPROGRESS )
{
//the price should be.... nothin ( reward for the quest )
uiTotalPrice = 1;
//if the player hasnt said the quote before
if( !( gArmsDealerStatus[ gbSelectedArmsDealerID ].ubSpecificDealerFlags & ARMS_DEALER_FLAG__RAUL_SAID_QUOTE_48 ) )
{
StartShopKeeperTalking( SK_QUOTES_NPC_SPECIFIC_48 );
gArmsDealerStatus[ gbSelectedArmsDealerID ].ubSpecificDealerFlags |= ARMS_DEALER_FLAG__RAUL_SAID_QUOTE_48;
gfCanSayMakeTransactionQuote = FALSE;
}
//else if
if( gArmsDealerStatus[ gbSelectedArmsDealerID ].ubSpecificDealerFlags & ARMS_DEALER_FLAG__RAUL_SAID_QUOTE_49 )
{
//if the player hasnt said it before
if( !( gArmsDealerStatus[ gbSelectedArmsDealerID ].ubSpecificDealerFlags & ARMS_DEALER_FLAG__RAUL_SAID_QUOTE_50 ) )
{
StartShopKeeperTalking( SK_QUOTES_NPC_SPECIFIC_50 );
gArmsDealerStatus[ gbSelectedArmsDealerID ].ubSpecificDealerFlags |= ARMS_DEALER_FLAG__RAUL_SAID_QUOTE_50;
}
//the price should be
uiTotalPrice = 100;
}
}
}
//if the item is the barrat
if( usItemID == BARRETT_UB )
{
//and if the player found the antique musket for Raul
if( IsJa25GeneralFlagSet( JA_GF__BARRETT_IS_HALF_PRICE ) )
{
//the barrett is half off
uiTotalPrice /= 2;
}
}
}
//JA25UB
//if the dealer is Raul
if( gbSelectedArmsDealerID == ARMS_DEALER_BETTY )
{
//if the item is the antique musket
if( usItemID == TEX_MOVIE_ATTACK_CLYDESDALES || usItemID == TEX_MOVIE_WILD_EAST || usItemID == TEX_MOVIE_HAVE_HONDA )
// if( usItemID == 1356 || usItemID == 1357 || usItemID == 1358 )
{
//Make the item price top be what is listed in the item table ( 20 )
uiTotalPrice = Item[ usItemID ].usPrice;
}
}
#endif
return( uiTotalPrice );
}
@@ -3922,7 +4079,29 @@ void PerformTransaction( UINT32 uiMoneyFromPlayersAccount )
//Move all dealers offered items to the player
MoveAllArmsDealersItemsInOfferAreaToPlayersOfferArea( );
#ifdef JA2UB
//JA25 UB
//if the arms dealer is Raul
if( gbSelectedArmsDealerID == ARMS_DEALER_RAUL )
{
//if this is the first time that the player purchased somehting form raul
if( gArmsDealerStatus[ gbSelectedArmsDealerID ].fHasSoldSomethingToPlayer == FALSE )
{
//if RAUL doesnt have the BARRETT anymore ie the player already bought it
//if( gArmsDealersInventory[ ARMS_DEALER_PERKO ][ BARRETT ].ubTotalItems != 0 )
//{
if( gubQuest[ QUEST_FIND_ANTIQUE_MUSKET_FOR_RAUL ] == QUESTNOTSTARTED )
{
//Raul Start the quest and have Raul say somehitng
StartShopKeeperTalking( SK_QUOTES_NPC_SPECIFIC_46 );
StartShopKeeperTalking( SK_QUOTES_NPC_SPECIFIC_47 );
StartQuest( QUEST_FIND_ANTIQUE_MUSKET_FOR_RAUL, -1, -1 );
}
//}
}
}
#endif
//if the arms dealer is the type of person to give change
if( armsDealerInfo[ gbSelectedArmsDealerID ].uiFlags & ARMS_DEALER_GIVES_CHANGE )
@@ -3951,7 +4130,34 @@ void PerformTransaction( UINT32 uiMoneyFromPlayersAccount )
else if( iChangeToGiveToPlayer == 0 )
StartShopKeeperTalking( SK_QUOTES_PLAYER_HAS_EXACTLY_ENOUGH_MONEY_FOR_TRANSACTION );
}
#ifdef JA2UB
//Bought from dealer specific stuff
//if the arms dealer is Betty, set fact 403
if( gbSelectedArmsDealerID == ARMS_DEALER_BETTY )
{
//if the player spent more the X
if( uiMoneyFromPlayersAccount >= SKI_BETTY_MINIMUM_AMOUNT_TO_SET_FACT )
{
//set the fact
SetFactTrue( FACT_PLAYER_PAID_BETTY_MORE_THEN_X_FOR_ITEM );
}
}
//if the arms dealer is Raul, set fact 407
if( gbSelectedArmsDealerID == ARMS_DEALER_RAUL )
{
//if the player spent more the X
if( uiMoneyFromPlayersAccount >= SKI_RAUL_MINIMUM_AMOUNT_TO_SET_FACT )
{
//set the fact
SetFactTrue( FACT_PLAYER_BOUGHT_SOMETHING_FROM_RAUL );
}
}
//Remeber the fact that the player has sold somehting to the player
gArmsDealerStatus[ gbSelectedArmsDealerID ].fHasSoldSomethingToPlayer = TRUE;
#endif
//if the arms dealer is tony
if( gbSelectedArmsDealerID == ARMS_DEALER_TONY )
@@ -3990,19 +4196,67 @@ void MoveAllArmsDealersItemsInOfferAreaToPlayersOfferArea( )
//for all items in the dealers items offer area
UINT32 uiCnt;
INT16 bSlotID=0;
#ifdef JA2UB
BOOLEAN fAddItemToPlayer=TRUE;
#endif
//loop through all the slots in the shopkeeper's offer area
for( uiCnt=0; uiCnt<SKI_NUM_TRADING_INV_SLOTS; uiCnt++)
{
//if there is an item here
if( ArmsDealerOfferArea[ uiCnt ].fActive )
{
#ifdef JA2UB
//JA25 UB
fAddItemToPlayer = TRUE;
//if the dealer is betty
if( gbSelectedArmsDealerID == ARMS_DEALER_BETTY )
{
//if the item is the laptop transmitter
if( ArmsDealerOfferArea[ uiCnt ].sItemIndex == LAPTOP_TRANSMITTER ) //4500
{
//Dont transfer the item
fAddItemToPlayer = FALSE;
//Tell the user we are going to attach the transmitter to the laptop
//( need to wait 1 frame caus ewe are currently in a msg box )
gubDisplayMsgBoxAskingUserToAttachTransmitter = TRNSMTR_MSG_BOX__1_FRAME_WAIT;
}
//if the item is the porno mag
if( ArmsDealerOfferArea[ uiCnt ].sItemIndex == PORNOS )
{
StartShopKeeperTalking( SK_QUOTES_WHEN_PLAYER_BUYS_PORNO );
}
//if the item is Tex's videos
if( ArmsDealerOfferArea[ uiCnt ].sItemIndex == TEX_MOVIE_ATTACK_CLYDESDALES ||//1356 ||
ArmsDealerOfferArea[ uiCnt ].sItemIndex == TEX_MOVIE_WILD_EAST ||//1357 ||
ArmsDealerOfferArea[ uiCnt ].sItemIndex == TEX_MOVIE_HAVE_HONDA )//1358 )
{
SetFactTrue( FACT_PLAYER_BOUGHT_A_TEX_VIDEO_FROM_BETTY );
}
}
if( fAddItemToPlayer ) //JA25 UB
{
#endif
bSlotID = AddItemToPlayersOfferArea( NO_PROFILE, &ArmsDealerOfferArea[ uiCnt ], -1 );
if( bSlotID != -1 )
{
PlayersOfferArea[ bSlotID ].uiFlags |= ARMS_INV_JUST_PURCHASED;
#ifdef JA2UB
//if the player has just purchased the BArrett form Raul
if( ( gbSelectedArmsDealerID == ARMS_DEALER_RAUL ) && ( ArmsDealerOfferArea[ uiCnt ].sItemIndex == BARRETT_UB ) )
{
// set a special flag
gArmsDealerStatus[ gbSelectedArmsDealerID ].ubSpecificDealerFlags |= ARMS_DEALER_FLAG__RAUL_HAS_SOLD_BARRETT_TO_PLAYER;
}
#endif
//if the player has just purchased a VIDEO_CAMERA from Franz Hinkle
if( ( gbSelectedArmsDealerID == ARMS_DEALER_FRANZ ) && ( ArmsDealerOfferArea[ uiCnt ].sItemIndex == VIDEO_CAMERA ) )
{
@@ -4010,7 +4264,9 @@ void MoveAllArmsDealersItemsInOfferAreaToPlayersOfferArea( )
gArmsDealerStatus[ gbSelectedArmsDealerID ].ubSpecificDealerFlags |= ARMS_DEALER_FLAG__FRANZ_HAS_SOLD_VIDEO_CAMERA_TO_PLAYER;
}
}
#ifdef JA2UB
}
#endif
//Remove the items out of the dealers inventory
RemoveItemFromDealersInventory( &ArmsDealerOfferArea[ uiCnt ], (UINT16)ArmsDealerOfferArea[ uiCnt ].bSlotIdInOtherLocation );
@@ -4051,7 +4307,9 @@ BOOLEAN RemoveItemFromDealersInventory( INVENTORY_IN_SLOT* pInvSlot, UINT16 ubSl
void MovePlayerOfferedItemsOfValueToArmsDealersInventory()
{
UINT32 uiCnt;
#ifdef JA2UB
BOOLEAN fAddItemToDealer=TRUE;
#endif
//loop through all the slots in the players offer area
for( uiCnt=0; uiCnt<SKI_NUM_TRADING_INV_SLOTS; uiCnt++)
{
@@ -4070,6 +4328,57 @@ void MovePlayerOfferedItemsOfValueToArmsDealersInventory()
//add the money to the dealers 'cash'
gArmsDealerStatus[ gbSelectedArmsDealerID ].uiArmsDealersCash += PlayersOfferArea[ uiCnt ].ItemObject[0]->data.money.uiMoneyAmount;
}
#ifdef JA2UB
else
{
fAddItemToDealer = TRUE;
//if the dealer is raul
if( gbSelectedArmsDealerID == ARMS_DEALER_RAUL )
{
//if the item is the cannon balls
if( PlayersOfferArea[ uiCnt ].sItemIndex == CLIP_CANNON_BALL )// 4499 )
{
fAddItemToDealer = FALSE;
}
//if the item is the antique musket
if( PlayersOfferArea[ uiCnt ].sItemIndex == HAND_CANNON )// 4498 )
{
//Only do this if the player knew about the cannon offer
if( gubQuest[ QUEST_FIND_ANTIQUE_MUSKET_FOR_RAUL ] == QUESTINPROGRESS )
{
//Have raul say a quote
StartShopKeeperTalking( SK_QUOTES_NPC_SPECIFIC_51 );
//Trigger Rauls action #52
TriggerNPCRecord( PERKO, 52 );
//Remeber to discount the barrett
SetJa25GeneralFlag( JA_GF__BARRETT_IS_HALF_PRICE );
}
//Mark the quest done
EndQuest( QUEST_FIND_ANTIQUE_MUSKET_FOR_RAUL, -1, -1 );
fAddItemToDealer = FALSE;
}
}
//if we ARE to transfer the item
if( fAddItemToDealer )
{
//if the dealer doesn't strictly buy items from the player, give the item to the dealer
if( armsDealerInfo[ gbSelectedArmsDealerID ].ubTypeOfArmsDealer != ARMS_DEALER_BUYS_ONLY )
{
// item cease to be merc-owned during this operation
AddObjectToArmsDealerInventory( gbSelectedArmsDealerID, &( PlayersOfferArea[ uiCnt ].ItemObject ) );
PlayersOfferArea[ uiCnt ].ItemObject.initialize();
}
}
}
#else
else
{
//if the dealer doesn't strictly buy items from the player, give the item to the dealer
@@ -4081,6 +4390,7 @@ void MovePlayerOfferedItemsOfValueToArmsDealersInventory()
}
}
#endif
//erase the item from the player's offer area
ClearPlayersOfferSlot( uiCnt );
}
@@ -4191,7 +4501,26 @@ void BeginSkiItemPointer( UINT8 ubSource, INT16 bSlotNum, BOOLEAN fOfferToDealer
}
else
gpItemPointerSoldier = gpSMCurrentMerc;
#ifdef JA2UB
//ja25 ub
//if the dealer is Raul
if( gbSelectedArmsDealerID == ARMS_DEALER_RAUL )
{
//if the item is the antique musket
if( gMoveingItem.ItemObject.usItem == HAND_CANNON ) //4498 )
{
if( gubQuest[ QUEST_FIND_ANTIQUE_MUSKET_FOR_RAUL ] == QUESTINPROGRESS )
{
//if the player hasnt said the quote before
if( !( gArmsDealerStatus[ gbSelectedArmsDealerID ].ubSpecificDealerFlags & ARMS_DEALER_FLAG__RAUL_SAID_QUOTE_49 ) )
{
StartShopKeeperTalking( SK_QUOTES_NPC_SPECIFIC_49 );
gArmsDealerStatus[ gbSelectedArmsDealerID ].ubSpecificDealerFlags |= ARMS_DEALER_FLAG__RAUL_SAID_QUOTE_49;
}
}
}
}
#endif
break;
@@ -4648,7 +4977,50 @@ void HandleShopKeeperDialog( UINT8 ubInit )
}
}
}
#ifdef JA2UB
//ja25 UB
// if neither of the more precise quotes fit, or 33 percent of the time anyways
if ( ( sRandomQuoteToUse == -1 ) || Chance( 33 ) )
{
//If the dealer is Betty,
if( gbSelectedArmsDealerID == ARMS_DEALER_BETTY )
{
//she has 4 random quotes
UINT8 ubRandom = Random( 100 );
if( ubRandom > 75 )
sRandomQuoteToUse = SK_QUOTES_RANDOM_QUOTE_WHILE_PLAYER_DECIDING_1;
else if( ubRandom > 50 )
sRandomQuoteToUse = SK_QUOTES_RANDOM_QUOTE_WHILE_PLAYER_DECIDING_2;
else if( ubRandom > 25 )
sRandomQuoteToUse = SK_QUOTES_RANDOM_QUOTE_WHILE_PLAYER_DECIDING_3;
else
sRandomQuoteToUse = SK_QUOTES_RANDOM_QUOTE_WHILE_PLAYER_DECIDING_4;
}
else
{
if( Chance ( 50 ) )
sRandomQuoteToUse = SK_QUOTES_RANDOM_QUOTE_WHILE_PLAYER_DECIDING_1;
else
sRandomQuoteToUse = SK_QUOTES_RANDOM_QUOTE_WHILE_PLAYER_DECIDING_2;
}
}
Assert( sRandomQuoteToUse != -1 );
Assert( sRandomQuoteToUse < NUM_COMMON_SK_QUOTES );
if ( !gfCommonQuoteUsedThisSession[ sRandomQuoteToUse ] )
{
StartShopKeeperTalking( (UINT16) sRandomQuoteToUse );
gfCommonQuoteUsedThisSession[ sRandomQuoteToUse ] = TRUE;
//increase the random quote delay
guiRandomQuoteDelayTime += SKI_DEALERS_RANDOM_QUOTE_DELAY_INCREASE_RATE;
}
#else
// if neither of the more precise quotes fit, or 33 percent of the time anyways
if ( ( sRandomQuoteToUse == -1 ) || Chance( 33 ) )
{
@@ -4670,6 +5042,7 @@ void HandleShopKeeperDialog( UINT8 ubInit )
//increase the random quote delay
guiRandomQuoteDelayTime += SKI_DEALERS_RANDOM_QUOTE_DELAY_INCREASE_RATE;
}
#endif
}
uiLastTime = GetJA2Clock();
@@ -5981,12 +6354,16 @@ void EvaluateItemAddedToPlayersOfferArea( INT8 bSlotID, BOOLEAN fFirstOne )
// say "Hmm... Let's see" once per trading session to start evaluation
// SPECIAL: Devin doesn't have this quote (he's the only one)
#ifdef JA2UB
//no UB
#else
if( !gfDealerHasSaidTheEvaluateQuoteOnceThisSession && ( gbSelectedArmsDealerID != ARMS_DEALER_DEVIN ) )
{
gfDealerHasSaidTheEvaluateQuoteOnceThisSession = TRUE;
StartShopKeeperTalking( SK_QUOTES_PLAYER_REQUESTED_EVALUATION );
}
#endif
//Can this particular kind of item be sold/repaired here
if( WillShopKeeperRejectObjectsFromPlayer( gbSelectedArmsDealerID, bSlotID ) == FALSE )
@@ -6118,6 +6495,33 @@ void EvaluateItemAddedToPlayersOfferArea( INT8 bSlotID, BOOLEAN fFirstOne )
switch ( uiEvalResult )
{
case EVAL_RESULT_DONT_HANDLE:
#ifdef JA2UB
//JA25 UB
if( armsDealerInfo[ gbSelectedArmsDealerID ].ubTypeOfArmsDealer == ARMS_DEALER_SELLS_ONLY )
{
// then he doesn't have quotes 17, 19, or 20, always use 4. Devin doesn't have 18 either,
// while the text of 18 seems wrong for Sam & Howard if offered something they should consider valuable.
sQuoteNum = SK_QUOTES_NOT_INTERESTED_IN_THIS_ITEM;
}
else
{
//if the dealer is BETTY
if( gbSelectedArmsDealerID == ARMS_DEALER_BETTY &&
( Item[ PlayersOfferArea[ bSlotID ].sItemIndex ].usItemClass == IC_AMMO ||
Item[ PlayersOfferArea[ bSlotID ].sItemIndex ].usItemClass == IC_GUN
)
)
{
// she accepts items, but not this one
sQuoteNum = SK_QUOTES_NPC_SPECIFIC_40;
}
else
{
// he accepts items, but not this one
sQuoteNum = SK_QUOTES_DURING_EVALUATION_STUFF_REJECTED;
}
}
#endif
if( armsDealerInfo[ gbSelectedArmsDealerID ].ubTypeOfArmsDealer == ARMS_DEALER_SELLS_ONLY )
{
// then he doesn't have quotes 17, 19, or 20, always use 4. Devin doesn't have 18 either,
@@ -7358,7 +7762,12 @@ void HandlePossibleRepairDelays()
gfStartWithRepairsDelayedQuote = FALSE;
// if it's Fredo or Perko
#ifdef JA2UB
if ( ( gbSelectedArmsDealerID == ARMS_DEALER_FREDO ) || ( gbSelectedArmsDealerID == ARMS_DEALER_RAUL ) )
#else
if ( ( gbSelectedArmsDealerID == ARMS_DEALER_FREDO ) || ( gbSelectedArmsDealerID == ARMS_DEALER_PERKO ) )
#endif
{
// because the quotes are so specific, we'll only use them once per game per repairman
if( !gArmsDealerStatus[ gbSelectedArmsDealerID ].fRepairDelayBeenUsed )
@@ -7841,3 +8250,21 @@ void HatchOutInvSlot( UINT16 usPosX, UINT16 usPosY )
DrawHatchOnInventory( guiRENDERBUFFER, usSlotX, usSlotY, usSlotWidth, usSlotHeight );
InvalidateRegion( usSlotX, usSlotY, usSlotX + usSlotWidth, usSlotY + usSlotHeight );
}
#ifdef JA2UB
//ja25 UB
void AskUserToAttachTransmitterToLaptop()
{
DoSkiMessageBox( MSG_BOX_BASIC_STYLE, zNewTacticalMessages[ TCTL_MSG__ATTACH_TRANSMITTER_TO_LAPTOP ], SHOPKEEPER_SCREEN, MSG_BOX_FLAG_OK, AttachLaptopTransmitterToLaptop );
}
void AttachLaptopTransmitterToLaptop( UINT8 ubExitValue )
{
//
// Get the laptop working again
//
//Mark the quest done
if ( gGameUBOptions.LaptopQuestEnabled == TRUE )
EndQuest( QUEST_FIX_LAPTOP, -1, -1 );
}
#endif
+37
View File
@@ -28,7 +28,44 @@ enum
SK_QUOTES_PRESSED_DONE_HASNT_MADE_TRANSACTION,
SK_QUOTES_PRESSED_DONE_STILL_HAS_STUFF_IN_OFFER_AREA,
SK_QUOTES_CANT_AFFORD_TO_BUY_OR_TOO_MUCH_TO_REPAIR,
#ifdef JA2UB
SK_QUOTES_BETTY_IS_ENEMY,
SK_QUOTES_NPC_HEALED_BY_PC,
//30 JA25 UB
SK_QUOTES_DEFAULT_WHEN_FIGHTING_NEARBY,
SK_QUOTES_FOLLOWS_QUOTE_1_POSITIVE,
SK_QUOTES_FOLLOWS_QUOTE_1_NEGATIVE,
SK_QUOTES_NPC_WANTS_TO_CLOSE_UP_SHOP,
SK_QUOTES_WHEN_PLAYER_BUYS_PORNO,
//35
SK_QUOTES_INTRO_TO_TEX,
SK_QUOTES_INTRO_TO_TEX_FOLLOW_UP_1,
SK_QUOTES_INTRO_TO_TEX_FOLLOW_UP_2,
SK_QUOTES_RANDOM_QUOTE_WHILE_PLAYER_DECIDING_3,
SK_QUOTES_RANDOM_QUOTE_WHILE_PLAYER_DECIDING_4,
//40
SK_QUOTES_NPC_SPECIFIC_40,
SK_QUOTES_NPC_SPECIFIC_41,
SK_QUOTES_NPC_SPECIFIC_42,
SK_QUOTES_NPC_SPECIFIC_43,
SK_QUOTES_NPC_SPECIFIC_44,
SK_QUOTES_NPC_SPECIFIC_45,
SK_QUOTES_NPC_SPECIFIC_46,
SK_QUOTES_NPC_SPECIFIC_47,
SK_QUOTES_NPC_SPECIFIC_48,
SK_QUOTES_NPC_SPECIFIC_49,
SK_QUOTES_NPC_SPECIFIC_50,
SK_QUOTES_NPC_SPECIFIC_51,
SK_QUOTES_NPC_SPECIFIC_52,
SK_QUOTES_NPC_SPECIFIC_53,
SK_QUOTES_NPC_SPECIFIC_54,
#endif
NUM_COMMON_SK_QUOTES,
// Quotes 28+ are NPC Specific, and are not under direct control of the SKI system. The get used by .COD files
+32 -1
View File
@@ -23,6 +23,11 @@
#include "Exit Grids.h"
#endif
#ifdef JA2UB
#include "Ja25 Strategic Ai.h"
#include "Ja25_Tactical.h"
#include "ub_config.h"
#endif
#include "GameSettings.h" // ary-05/05/2009 : add forced turn mode
#include "text.h" // : add forced turn mode
@@ -1095,6 +1100,9 @@ BOOLEAN InternalAddSoldierToSector( UINT8 ubID, BOOLEAN fCalculateDirection, BOO
if ( pSoldier->bActive )
{
#ifdef JA2UB
//Ja25 No meanwhiles in exp
#else
// ATE: Make sure life of elliot is OK if from a meanwhile
if ( AreInMeanwhile() && pSoldier->ubProfile == ELLIOT )
{
@@ -1103,7 +1111,7 @@ BOOLEAN InternalAddSoldierToSector( UINT8 ubID, BOOLEAN fCalculateDirection, BOO
pSoldier->stats.bLife = 25;
}
}
#endif
// ADD SOLDIER TO SLOT!
if (pSoldier->flags.uiStatusFlags & SOLDIER_OFF_MAP)
{
@@ -1571,6 +1579,28 @@ void AddSoldierToSectorGridNo( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDir
// default to standing on arrival
if ( pSoldier->usAnimState != HELIDROP )
{
#ifdef JA2UB
// DAVE!!!!
if ( gfFirstTimeInGameHeliCrash && gGameUBOptions.InGameHeli == FALSE )
{
//should we be on our back or tummy
if( Random( 100 ) < 50 )
pSoldier->EVENT_InitNewSoldierAnim( STAND_FALLFORWARD_STOP, 1, TRUE );
else
pSoldier->EVENT_InitNewSoldierAnim( FALLBACKHIT_STOP, 1, TRUE );
pSoldier->bCollapsed = TRUE;
}
else if ( fUseAnimation )
{
pSoldier->EVENT_InitNewSoldierAnim( usAnimState, usAnimCode, TRUE );
}
else if ( pSoldier->ubBodyType != CROW )
{
pSoldier->EVENT_InitNewSoldierAnim( STANDING, 1, TRUE );
}
#else
if ( fUseAnimation )
{
pSoldier->EVENT_InitNewSoldierAnim( usAnimState, usAnimCode, TRUE );
@@ -1579,6 +1609,7 @@ void AddSoldierToSectorGridNo( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDir
{
pSoldier->EVENT_InitNewSoldierAnim( STANDING, 1, TRUE );
}
#endif
}
// ATE: if we are below OK life, make them lie down!
+66 -3
View File
@@ -597,6 +597,25 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
{
UnSetUIBusy( pSoldier->ubID );
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - if pending interrupt flag was set for after-attack type of interupt, try to resolve it now
else if ( gGameExternalOptions.fImprovedInterruptSystem )
{
if ( ResolvePendingInterrupt( pSoldier, AFTERACTION_INTERRUPT ) )
{
pSoldier->usPendingAnimation = NO_PENDING_ANIMATION;
pSoldier->ubPendingDirection = NO_PENDING_DIRECTION;
// "artificially" set lock ui flag in this case
if (pSoldier->bTeam == gbPlayerNum)
{
AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, Message[STR_INTERRUPT] );
guiPendingOverrideEvent = LU_BEGINUILOCK;
HandleTacticalUI( );
}
return( TRUE );
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
break;
case 443:
@@ -1013,12 +1032,12 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
{
//AXP 25.03.2007: MinAPsToThrow now actually returns the real cost, not 0
// ATE: Deduct points!
DeductPoints( pSoldier, MinAPsToThrow( pSoldier, pSoldier->sTargetGridNo, FALSE ), 0 );
DeductPoints( pSoldier, MinAPsToThrow( pSoldier, pSoldier->sTargetGridNo, FALSE ), 0, AFTERACTION_INTERRUPT );
}
else
{
// ATE: Deduct points!
DeductPoints( pSoldier, APBPConstants[AP_TOSS_ITEM], 0 );
DeductPoints( pSoldier, APBPConstants[AP_TOSS_ITEM], 0, AFTERACTION_INTERRUPT );
}
INT32 iRealObjectID = CreatePhysicalObject( pSoldier->pTempObject, pSoldier->pThrowParams->dLifeSpan, pSoldier->pThrowParams->dX, pSoldier->pThrowParams->dY, pSoldier->pThrowParams->dZ, pSoldier->pThrowParams->dForceX, pSoldier->pThrowParams->dForceY, pSoldier->pThrowParams->dForceZ, pSoldier->ubID, pSoldier->pThrowParams->ubActionCode, pSoldier->pThrowParams->uiActionData, FALSE );
@@ -1221,7 +1240,13 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
}
else
{
#ifdef JA2UB
//Ja25 No meanwhiles
if ( fMartialArtist )
#else
if ( fMartialArtist && !AreInMeanwhile( ) )
#endif
{
pSoldier->ChangeSoldierState( NINJA_BREATH, 0, FALSE );
return( TRUE );
@@ -2025,6 +2050,29 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
case 498:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - if pending interrupt flag was set for before-attack type of interupt, try to resolve it now
if ( gGameExternalOptions.fImprovedInterruptSystem )
{
if ( ResolvePendingInterrupt( pSoldier, BEFORESHOT_INTERRUPT ) )
{
if ( pSoldier->flags.fTurningToShoot )
pSoldier->flags.fTurningToShoot = FALSE;
pSoldier->usPendingAnimation = NO_PENDING_ANIMATION;
pSoldier->ubPendingDirection = NO_PENDING_DIRECTION;
// "artificially" set lock ui flag in this case
if (pSoldier->bTeam == gbPlayerNum)
{
AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, Message[STR_INTERRUPT] );
guiPendingOverrideEvent = LU_BEGINUILOCK;
HandleTacticalUI( );
}
return( TRUE );
break;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CONDITONAL JUMP
// If we have a pending animation, play it, else continue
if ( pSoldier->usPendingAnimation != NO_PENDING_ANIMATION )
@@ -2616,6 +2664,14 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
DebugAttackBusy( "@@@@@@@ Reducing attacker busy count for end of queen swipe" );
// ReduceAttackBusyCount( pSoldier->ubID, FALSE );
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - if pending interrupt flag was set for after-attack type of interupt, try to resolve it now
if ( gGameExternalOptions.fImprovedInterruptSystem )
{
ResolvePendingInterrupt( pSoldier, AFTERACTION_INTERRUPT );
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
break;
case 754:
@@ -3628,6 +3684,9 @@ void CheckForAndHandleSoldierIncompacitated( SOLDIERTYPE *pSoldier )
}
// OK, if we are in a meanwhile and this is elliot...
#ifdef JA2UB
//ja25: No queen
#else
if ( AreInMeanwhile( ) )
{
SOLDIERTYPE *pQueen;
@@ -3639,7 +3698,7 @@ void CheckForAndHandleSoldierIncompacitated( SOLDIERTYPE *pSoldier )
TriggerNPCWithGivenApproach( QUEEN, APPROACH_DONE_SLAPPED, FALSE );
}
}
#endif
// We are unconscious now, play randomly, this animation continued, or a new death
if ( pSoldier->CheckSoldierHitRoof( ) )
{
@@ -3649,7 +3708,11 @@ void CheckForAndHandleSoldierIncompacitated( SOLDIERTYPE *pSoldier )
// If guy is now dead, play sound!
if ( pSoldier->stats.bLife == 0 )
{
#ifdef JA2UB
//Ja25 No meanwhiles
#else
if ( !AreInMeanwhile() )
#endif
{
pSoldier->DoMercBattleSound( BATTLE_SOUND_DIE1 );
pSoldier->flags.fDeadSoundPlayed = TRUE;
+454 -45
View File
@@ -99,6 +99,13 @@
#include "LOS.h" // added by SANDRO
#endif
#include "ub_config.h"
#ifdef JA2UB
#include "Ja25_Tactical.h"
#include "Ja25 Strategic Ai.h"
#endif
#include "fresh_header.h"
#include "Dialogue Control.h"
@@ -2884,6 +2891,8 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
// If we are NOT loading a game, continue normally
if( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
{
usItem = this->inv[ HANDPOS ].usItem;
// CHECK IF WE ARE TRYING TO INTURRUPT A SCRIPT WHICH WE DO NOT WANT INTERRUPTED!
if ( this->flags.fInNonintAnim )
{
@@ -3039,7 +3048,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
// We are told that we need to rasie weapon
// Do so only if
// 1) We have a rifle in hand...
usItem = this->inv[ HANDPOS ].usItem;
//usItem = this->inv[ HANDPOS ].usItem;
if ( this->inv[ HANDPOS ].exists() == true && (Item[ usItem ].twohanded ) && !Item[usItem].rocketlauncher )
{
@@ -3062,7 +3071,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
// We are told that we need to rasie weapon
// Do so only if
// 1) We have a rifle in hand...
usItem = this->inv[ HANDPOS ].usItem;
//usItem = this->inv[ HANDPOS ].usItem;
if ( this->inv[ HANDPOS ].exists() == true && (Item[ usItem ].twohanded ) && !Item[usItem].rocketlauncher )
{
@@ -3125,7 +3134,8 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
}
// OK.......
if ( this->ubBodyType > REGFEMALE )
// SANDRO - removing unused code
/*if ( this->ubBodyType > REGFEMALE )
{
if ( this->stats.bLife < INJURED_CHANGE_THREASHOLD )
{
@@ -3135,7 +3145,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
// usNewState = FROM_INJURED_TRANSITION;
}
}
}
}*/
// Alrighty, check if we should free buddy up!
if ( usNewState == GIVING_AID )
@@ -3161,10 +3171,10 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
{
if ( usNewState == KNEEL_DOWN && this->usAnimState != BIGMERC_CROUCH_TRANS_INTO )
{
UINT16 usItem;
//UINT16 usItem;
// Do we have a rifle?
usItem = this->inv[ HANDPOS ].usItem;
//usItem = this->inv[ HANDPOS ].usItem;
if ( this->inv[ HANDPOS ].exists() == true )
{
@@ -3181,10 +3191,10 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
if ( usNewState == KNEEL_UP && this->usAnimState != BIGMERC_CROUCH_TRANS_OUTOF )
{
UINT16 usItem;
//UINT16 usItem;
// Do we have a rifle?
usItem = this->inv[ HANDPOS ].usItem;
//usItem = this->inv[ HANDPOS ].usItem;
if ( this->inv[ HANDPOS ].exists() == true )
{
@@ -3211,15 +3221,39 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
if ( this->ubDirection == gPurpendicularDirection[ this->ubDirection ][ this->pathing.usPathingData[ this->pathing.usPathIndex ] ] )
{
// We are perpendicular!
usNewState = SIDE_STEP;
// SANDRO - wait wait wait!!! We need to determine if gonna sidestep with weapon raised
if (( (gAnimControl[ this->usAnimState ].uiFlags & ANIM_FIREREADY ) ||
(gAnimControl[ this->usAnimState ].uiFlags & ANIM_FIRE ) ) && gGameExternalOptions.fAllowWalkingWithWeaponRaised )
//if ( WeaponReady( this ) )
{
if ( this->inv[ HANDPOS ].exists() == true && Item[ usItem ].usItemClass == IC_GUN && !Item[usItem].rocketlauncher)
{
if ( !(Item[ usItem ].twohanded ) )
{
if ( this->IsValidSecondHandShot() )
{
usNewState = SIDE_STEP_DUAL_RDY;
}
else
{
usNewState = SIDE_STEP_PISTOL_RDY;
}
}
else
{
usNewState = SIDE_STEP_RIFLE_RDY;
}
}
}
else
{
usNewState = SIDE_STEP;
}
}
else
{
if ( gAnimControl[ this->usAnimState ].ubEndHeight == ANIM_CROUCH )
{
//*** ddd
UINT16 usItem = this->inv[ HANDPOS ].usItem;
{
if( this->inv[ HANDPOS ].exists() == true && Item[ usItem ].usItemClass == IC_GUN && Item[ usItem ].twohanded && !Item[usItem].rocketlauncher)
usNewState = SWAT_BACKWARDS;
else
@@ -3288,6 +3322,29 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
usNewState = WALKING;
}
}
// SANDRO - check if we are gonna move with weapon raised
else if (( (gAnimControl[ this->usAnimState ].uiFlags & ANIM_FIREREADY ) ||
(gAnimControl[ this->usAnimState ].uiFlags & ANIM_FIRE ) ) && ( usNewState == WALKING ) && gGameExternalOptions.fAllowWalkingWithWeaponRaised )
{
if ( this->inv[ HANDPOS ].exists() == true && Item[ usItem ].usItemClass == IC_GUN && !Item[usItem].rocketlauncher)
{
if ( !(Item[ usItem ].twohanded ) )
{
if ( this->IsValidSecondHandShot() )
{
usNewState = WALKING_DUAL_RDY;
}
else
{
usNewState = WALKING_PISTOL_RDY;
}
}
else
{
usNewState = WALKING_RIFLE_RDY;
}
}
}
// Turn off anipause flag for any anim!
this->flags.uiStatusFlags &= (~SOLDIER_PAUSEANIMOVE);
@@ -3540,7 +3597,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
if ( !this->flags.fDontChargeReadyAPs )
{
sAPCost = GetAPsToReadyWeapon( this, usNewState );
DeductPoints( this, sAPCost, sBPCost );
DeductPoints( this, sAPCost, sBPCost, BEFORESHOT_INTERRUPT );
}
else
{
@@ -3549,6 +3606,9 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
break;
case WALKING:
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
this->usPendingAnimation = NO_PENDING_ANIMATION;
this->aiData.ubPendingActionAnimCount = 0;
@@ -3581,7 +3641,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
}
else
sAPCost = GetAPsStartRun( this ); // changed by SANDRO
DeductPoints( this, sAPCost, sBPCost );
DeductPoints( this, sAPCost, sBPCost, MOVEMENT_INTERRUPT );
}
// Set pending action count to 0
this->aiData.ubPendingActionAnimCount = 0;
@@ -3679,7 +3739,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
break;
case CUTTING_FENCE:
DeductPoints( this, APBPConstants[AP_USEWIRECUTTERS], APBPConstants[BP_USEWIRECUTTERS] );
DeductPoints( this, APBPConstants[AP_USEWIRECUTTERS], APBPConstants[BP_USEWIRECUTTERS], AFTERACTION_INTERRUPT );
break;
case PLANT_BOMB:
@@ -3721,7 +3781,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
case USE_REMOTE:
DeductPoints( this, APBPConstants[AP_USE_REMOTE], 0 );
DeductPoints( this, APBPConstants[AP_USE_REMOTE], 0, AFTERACTION_INTERRUPT );
break;
//case PUNCH:
@@ -3736,28 +3796,28 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
// CHRISL
// SANDRO - changed this a bit
if((UsingNewInventorySystem() == true) && FindBackpackOnSoldier( this ) != ITEM_NOT_FOUND )
DeductPoints( this, GetAPsToJumpFence( this, TRUE ), GetBPsToJumpFence( this, TRUE ) );
DeductPoints( this, GetAPsToJumpFence( this, TRUE ), GetBPsToJumpFence( this, TRUE ), SP_MOVEMENT_INTERRUPT );
else
DeductPoints( this, GetAPsToJumpFence( this, FALSE ), GetBPsToJumpFence( this, FALSE ) );
DeductPoints( this, GetAPsToJumpFence( this, FALSE ), GetBPsToJumpFence( this, FALSE ), SP_MOVEMENT_INTERRUPT );
break;
case JUMPWINDOWS:
if((UsingNewInventorySystem() == true) && FindBackpackOnSoldier( this ) != ITEM_NOT_FOUND )
DeductPoints( this, GetAPsToJumpThroughWindows( this, TRUE ), GetBPsToJumpThroughWindows( this, TRUE ) );
DeductPoints( this, GetAPsToJumpThroughWindows( this, TRUE ), GetBPsToJumpThroughWindows( this, TRUE ), SP_MOVEMENT_INTERRUPT );
else
DeductPoints( this, GetAPsToJumpThroughWindows( this, FALSE ), GetBPsToJumpThroughWindows( this, FALSE ) );
DeductPoints( this, GetAPsToJumpThroughWindows( this, FALSE ), GetBPsToJumpThroughWindows( this, FALSE ), SP_MOVEMENT_INTERRUPT );
break;
// Deduct aps for falling down....
case FALLBACK_HIT_STAND:
case FALLFORWARD_FROMHIT_STAND:
DeductPoints( this, APBPConstants[AP_FALL_DOWN], APBPConstants[BP_FALL_DOWN] );
DeductPoints( this, APBPConstants[AP_FALL_DOWN], APBPConstants[BP_FALL_DOWN], DISABLED_INTERRUPT );
break;
case FALLFORWARD_FROMHIT_CROUCH:
DeductPoints( this, (APBPConstants[AP_FALL_DOWN]/2), (APBPConstants[BP_FALL_DOWN]/2) );
DeductPoints( this, (APBPConstants[AP_FALL_DOWN]/2), (APBPConstants[BP_FALL_DOWN]/2), DISABLED_INTERRUPT );
break;
case QUEEN_SWIPE:
@@ -3771,7 +3831,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
// disable sight
gTacticalStatus.uiFlags |= DISALLOW_SIGHT;
DeductPoints( this, GetAPsToClimbRoof( this, TRUE), GetBPsToClimbRoof( this, TRUE) ); // changed by SANDRO
DeductPoints( this, GetAPsToClimbRoof( this, TRUE), GetBPsToClimbRoof( this, TRUE), SP_MOVEMENT_INTERRUPT ); // changed by SANDRO
break;
case CLIMBUPROOF:
@@ -3779,7 +3839,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
// disable sight
gTacticalStatus.uiFlags |= DISALLOW_SIGHT;
DeductPoints( this, GetAPsToClimbRoof( this, FALSE), GetBPsToClimbRoof( this, FALSE) ); // changed by SANDRO
DeductPoints( this, GetAPsToClimbRoof( this, FALSE), GetBPsToClimbRoof( this, FALSE), SP_MOVEMENT_INTERRUPT ); // changed by SANDRO
break;
case JUMPDOWNWALL:
@@ -3787,7 +3847,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
// disable sight
gTacticalStatus.uiFlags |= DISALLOW_SIGHT;
DeductPoints( this, GetAPsToJumpWall( this, TRUE), GetBPsToJumpWall( this, TRUE) );
DeductPoints( this, GetAPsToJumpWall( this, TRUE), GetBPsToJumpWall( this, TRUE), SP_MOVEMENT_INTERRUPT );
break;
case JUMPUPWALL:
@@ -3795,7 +3855,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
// disable sight
gTacticalStatus.uiFlags |= DISALLOW_SIGHT;
DeductPoints( this, GetAPsToJumpWall( this, FALSE), GetBPsToJumpWall( this, FALSE) );
DeductPoints( this, GetAPsToJumpWall( this, FALSE), GetBPsToJumpWall( this, FALSE), SP_MOVEMENT_INTERRUPT );
break;
case JUMP_OVER_BLOCKING_PERSON:
@@ -3804,7 +3864,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
{
INT32 usNewGridNo;
DeductPoints( this, GetAPsToJumpOver( this ), APBPConstants[BP_JUMP_OVER] ); // changed by SANDRO
DeductPoints( this, GetAPsToJumpOver( this ), APBPConstants[BP_JUMP_OVER], SP_MOVEMENT_INTERRUPT ); // changed by SANDRO
usNewGridNo = NewGridNo( this->sGridNo, DirectionInc( this->ubDirection ) );
usNewGridNo = NewGridNo( usNewGridNo, DirectionInc( this->ubDirection ) );
@@ -4451,6 +4511,9 @@ void SOLDIERTYPE::SetSoldierGridNo( INT32 sNewGridNo, BOOLEAN fForceRemove )
switch( this->usAnimState )
{
case WALKING:
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
case RUNNING:
// IN deep water, swim!
@@ -4637,6 +4700,27 @@ void SOLDIERTYPE::EVENT_FireSoldierWeapon( INT32 sTargetGridNo )
// Ready weapon
this->SoldierReadyWeapon( sTargetXPos, sTargetYPos, FALSE );
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - hack! - an interrupt pending before shot
if ( gGameExternalOptions.fImprovedInterruptSystem )
{
if ( ResolvePendingInterrupt( this, BEFORESHOT_INTERRUPT ) )
{
this->usPendingAnimation = NO_PENDING_ANIMATION;
this->ubPendingDirection = NO_PENDING_DIRECTION;
// "artificially" set lock ui flag
if (this->bTeam == gbPlayerNum)
{
AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, Message[STR_INTERRUPT] );
guiPendingOverrideEvent = LU_BEGINUILOCK;
HandleTacticalUI( );
}
// return as we are not gonna shoot if interrupted
return;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IF WE ARE AN NPC, SLIDE VIEW TO SHOW WHO IS SHOOTING
{
//if ( this->flags.fDoSpread )
@@ -5408,11 +5492,15 @@ void SOLDIERTYPE::EVENT_SoldierGotHit( UINT16 usWeaponIndex, INT16 sDamage, INT1
}
////////////////////////////////////////////////////////////////////////////
sDamage = sDamage / PUNCH_REAL_DAMAGE_PORTION;
#ifdef JA2UB
//Ja25: No meanwhiles
#else
if ( AreInMeanwhile() && gCurrentMeanwhileDef.ubMeanwhileID == INTERROGATION )
{
sBreathLoss = 0;
sDamage /= 2;
}
#endif
ubReason = TAKE_DAMAGE_HANDTOHAND;
}
// marke added one 'or' for explosive ammo. variation of: AmmoTypes[this->inv[this->ubAttackingHand ][0]->data.gun.ubGunAmmoType].explosionSize > 1
@@ -6013,7 +6101,7 @@ void SoldierGotHitGunFire( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sD
// HEADROCK HAM 3.2: Critical legshots cost an extra number of APs, based on shot damage.
if (gGameExternalOptions.fCriticalLegshotCausesAPLoss)
{
DeductPoints( pSoldier, APBPConstants[AP_LOSS_PER_LEGSHOT_DAMAGE]*sDamage, 0);
DeductPoints( pSoldier, APBPConstants[AP_LOSS_PER_LEGSHOT_DAMAGE]*sDamage, 0, DISABLED_INTERRUPT);
}
SoldierCollapse( pSoldier );
return;
@@ -6457,7 +6545,16 @@ BOOLEAN SOLDIERTYPE::EVENT_InternalGetNewSoldierPath( INT32 sDestGridNo, UINT16
}
// If we were aiming, end aim!
usAnimState = PickSoldierReadyAnimation( this, TRUE );
// SANDRO - we may try to move with raised weapon, so don't end aim after
if ( (gAnimControl[ this->usAnimState ].uiFlags & ( ANIM_FIREREADY | ANIM_FIRE )) &&
(usMoveAnimState == WALKING || usMoveAnimState == SIDE_STEP ) && !( this->MercInWater( )) )
{
usAnimState = INVALID_ANIMATION;
}
else
{
usAnimState = PickSoldierReadyAnimation( this, TRUE );
}
// Add a pending animation first!
// Only if we were standing!
@@ -6649,7 +6746,8 @@ void SOLDIERTYPE::EVENT_InternalSetSoldierDestination( UINT16 usNewDirection, BO
// OK, ATE: If we are side_stepping, calculate a NEW desired direction....
if ( this->bReverse && (usAnimState == SIDE_STEP || usAnimState == ROLL_PRONE_R || usAnimState == ROLL_PRONE_L) )
if ( this->bReverse && (usAnimState == SIDE_STEP || usAnimState == ROLL_PRONE_R || usAnimState == ROLL_PRONE_L
|| usAnimState == SIDE_STEP_PISTOL_RDY || usAnimState == SIDE_STEP_RIFLE_RDY || usAnimState == SIDE_STEP_DUAL_RDY ) )
{
UINT8 ubPerpDirection;
@@ -6757,7 +6855,8 @@ INT8 MultiTiledTurnDirection( SOLDIERTYPE * pSoldier, INT8 bStartDirection, INT8
void EVENT_InternalSetSoldierDesiredDirection( SOLDIERTYPE *pSoldier, UINT8 ubNewDirection, BOOLEAN fInitalMove, UINT16 usAnimState )
{
//if ( usAnimState == WALK_BACKWARDS )
if ( pSoldier->bReverse && (usAnimState != SIDE_STEP && usAnimState != ROLL_PRONE_R && usAnimState != ROLL_PRONE_L) )
if ( pSoldier->bReverse && (usAnimState != SIDE_STEP && usAnimState != ROLL_PRONE_R && usAnimState != ROLL_PRONE_L
&& usAnimState != SIDE_STEP_PISTOL_RDY && usAnimState != SIDE_STEP_RIFLE_RDY && usAnimState != SIDE_STEP_DUAL_RDY ) )
{
// OK, check if we are going to go in the exact opposite than our facing....
ubNewDirection = gOppositeDirection[ ubNewDirection ];
@@ -7055,6 +7154,9 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou
}
this->CalcNewActionPoints( );
// SANDRO - Improved Interrupt System - reset interrupt counter
memset(this->aiData.ubInterruptCounter,0,sizeof(this->aiData.ubInterruptCounter));
// HEADROCK HAM 3.6: If this soldier is in a "moving" animation, but has not moved any tiles
// in the previous turn, then the player has apparently forgotten that he was moving.
@@ -7978,6 +8080,9 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier
return;
case WALKING:
case WALKING_PISTOL_RDY:
case WALKING_RIFLE_RDY:
case WALKING_DUAL_RDY:
// Adjust based on body type
bAdditional = (UINT8)( gubAnimWalkSpeeds[ pStatsSoldier->ubBodyType ].sSpeed );
@@ -8700,13 +8805,15 @@ void SOLDIERTYPE::BeginSoldierGetup( void )
{
return;
}
#ifdef JA2UB
//Ja25: No meanwhiles
#else
// ATE: Don't getup if we are in a meanwhile
if ( AreInMeanwhile( ) )
{
return;
}
#endif
if ( this->bCollapsed )
{
if ( this->stats.bLife >= OKLIFE && this->bBreath >= OKBREATH && (this->bSleepDrugCounter == 0) )
@@ -8945,13 +9052,15 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
// Turn off
this->flags.uiStatusFlags &= ( ~SOLDIER_NPC_SHOOTING );
}
#ifdef JA2UB
//Ja25: No meanwhiles
#else
// CJC: make sure Elliot doesn't bleed to death!
if ( ubReason == TAKE_DAMAGE_BLOODLOSS && AreInMeanwhile() )
{
return( 0 );
}
#endif
// Calculate bandage
bBandage = this->stats.bLifeMax - this->stats.bLife - this->bBleeding;
@@ -9136,7 +9245,7 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
// ATE: if the robot, do not deduct
if ( !AM_A_ROBOT( this ) )
{
DeductPoints( this, sAPCost, sBreathLoss , FALSE);
DeductPoints( this, sAPCost, sBreathLoss, DISABLED_INTERRUPT );
}
ubCombinedLoss = (UINT8) sLifeDeduct / 10 + sBreathLoss / 2000;
@@ -9352,7 +9461,39 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
{
DecayIndividualOpplist( this );
}
#ifdef JA2UB
//if the attacker is MORRIS, AND he didnt kill the person
if( Menptr[ ubAttacker ].ubProfile == 75 ) //MORRIS
{
//if the soldier is hurt, but not dead
if( this->stats.bLife < bOldLife && this->stats.bLife > 0 )
{
//if he hasnt said his quote #1 before
if( !( Menptr[ ubAttacker ].usQuoteSaidExtFlags & SOLDIER_QUOTE_SAID_THOUGHT_KILLED_YOU ) )
{
//said a flag so morris can say this quote next turn
gJa25SaveStruct.fMorrisToSayHurtPlayerQuoteNextTurn = TRUE;
//Remeber who Morris is saying the quote too
gJa25SaveStruct.ubPlayerMorrisHurt = this->ubProfile;
}
}
// else if morris is to say the quote, he hasnt said it yet and he just killed the person he WAS going to say it to
else if( gJa25SaveStruct.fMorrisToSayHurtPlayerQuoteNextTurn &&
gJa25SaveStruct.ubPlayerMorrisHurt == this->ubProfile &&
this->stats.bLife <= 0 &&
!( Menptr[ ubAttacker ].usQuoteSaidExtFlags & SOLDIER_QUOTE_SAID_THOUGHT_KILLED_YOU ) )
{
//said a flag so morris can say this quote next turn
gJa25SaveStruct.fMorrisToSayHurtPlayerQuoteNextTurn = FALSE;
//Remeber who Morris is saying the quote too
gJa25SaveStruct.ubPlayerMorrisHurt = NO_PROFILE;
}
}
#endif
return( ubCombinedLoss );
}
@@ -11173,7 +11314,12 @@ void SOLDIERTYPE::EVENT_SoldierBeginPunchAttack( INT32 sGridNo, UINT8 ubDirectio
fMartialArtist = TRUE;
}
//Ja25 No meanwhiles
#ifdef JA2UB
if ( fMartialArtist && !Item[usItem].crowbar && this->ubBodyType == REGMALE)
#else
if ( fMartialArtist && !AreInMeanwhile( ) && !Item[usItem].crowbar && this->ubBodyType == REGMALE ) // SANDRO - added check for body type
#endif
{
// Are we in attack mode yet?
if ( this->usAnimState != NINJA_BREATH && gAnimControl[ this->usAnimState ].ubHeight == ANIM_STAND && gAnimControl[ pTSoldier->usAnimState ].ubHeight != ANIM_PRONE )
@@ -11269,6 +11415,7 @@ void SOLDIERTYPE::EVENT_SoldierBeginKnifeThrowAttack( INT32 sGridNo, UINT8 ubDir
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting knifethrow attack, bullets left %d", this->bBulletsLeft) );
DebugAttackBusy( String( "Begin knife throwing attack: ATB %d\n", gTacticalStatus.ubAttackBusyCount) );
// SANDRO - new animation for throwing for big mercs by PasHancock
if ( this->ubBodyType == BIGMALE && ((this->ubProfile != NO_PROFILE && gMercProfiles[ this->ubProfile ].bCharacterTrait == CHAR_TRAIT_SHOWOFF) || (HAS_SKILL_TRAIT( this, THROWING_NT ) && gGameOptions.fNewTraitSystem) || (HAS_SKILL_TRAIT( this, THROWING_OT ) && !gGameOptions.fNewTraitSystem) ) )
{
this->EVENT_InitNewSoldierAnim( THROW_KNIFE_SP_BM, 0 , FALSE );
@@ -11963,7 +12110,7 @@ void SOLDIERTYPE::HaultSoldierFromSighting( BOOLEAN fFromSightingEnemy )
SStopMerc.sXPos=this->sX;
SStopMerc.sYPos=this->sY;
//AddGameEvent( S_STOP_MERC, 0, &SStopMerc ); //hayden.
if(this->ubID>=120 || (!is_server && this->ubID >=20)) return;//hayden
if((is_networked) && (this->ubID>=120 || (!is_server && this->ubID >=20))) return;//hayden
if(is_client)send_stop(&SStopMerc);
// If we are a 'specialmove... ignore...
@@ -13734,7 +13881,7 @@ BOOLEAN SOLDIERTYPE::PlayerSoldierStartTalking( UINT8 ubTargetID, BOOLEAN fValid
else
{
// Deduct points from our guy....
DeductPoints( this, sAPCost, 0 );
DeductPoints( this, sAPCost, 0, UNTRIGGERED_INTERRUPT );
apsDeducted = TRUE;
StartCivQuote( pTSoldier );
@@ -13745,7 +13892,7 @@ BOOLEAN SOLDIERTYPE::PlayerSoldierStartTalking( UINT8 ubTargetID, BOOLEAN fValid
// WANNE: This fixes the bug, that APs for talking are not always deducted.
if (!apsDeducted)
{
DeductPoints( this, sAPCost, 0 );
DeductPoints( this, sAPCost, 0, UNTRIGGERED_INTERRUPT );
apsDeducted = TRUE;
}
@@ -14440,11 +14587,19 @@ BOOLEAN HAS_SKILL_TRAIT( SOLDIERTYPE * pSoldier, UINT8 uiSkillTraitNumber )
return( FALSE );
INT8 bNumMajorTraitsCounted = 0;
INT8 bMaxTraits = gSkillTraitValues.ubMaxNumberOfTraits;
INT8 bMaxMajorTraits = gSkillTraitValues.ubNumberOfMajorTraitsAllowed;
// special case for Dr.Q - he's allowed to have 3 major traits and one minor for total by default
if ( pSoldier->ubProfile == 33 && gSkillTraitValues.fAllowDrQTraitsException )
{
bMaxTraits++;
bMaxMajorTraits++;
}
// check old/new traits
if (gGameOptions.fNewTraitSystem)
{
for ( INT8 bCnt = 0; bCnt < gSkillTraitValues.ubMaxNumberOfTraits; bCnt++ )
for ( INT8 bCnt = 0; bCnt < min(30,bMaxTraits); bCnt++ )
{
if ( uiSkillTraitNumber > 0 && uiSkillTraitNumber <= NUM_MAJOR_TRAITS )
{
@@ -14457,7 +14612,7 @@ BOOLEAN HAS_SKILL_TRAIT( SOLDIERTYPE * pSoldier, UINT8 uiSkillTraitNumber )
bNumMajorTraitsCounted++;
}
// if we exceeded the allowed number of major traits, ignore the rest of them
if ( bNumMajorTraitsCounted >= gSkillTraitValues.ubNumberOfMajorTraitsAllowed )
if ( bNumMajorTraitsCounted >= min(20,bMaxMajorTraits) )
{
break;
}
@@ -14488,11 +14643,19 @@ INT8 NUM_SKILL_TRAITS( SOLDIERTYPE * pSoldier, UINT8 uiSkillTraitNumber )
INT8 bNumberOfTraits = 0;
INT8 bNumMajorTraitsCounted = 0;
INT8 bMaxTraits = gSkillTraitValues.ubMaxNumberOfTraits;
INT8 bMaxMajorTraits = gSkillTraitValues.ubNumberOfMajorTraitsAllowed;
// special case for Dr.Q - he's allowed to have 3 major traits and one minor for total by default
if ( pSoldier->ubProfile == 33 && gSkillTraitValues.fAllowDrQTraitsException )
{
bMaxTraits++;
bMaxMajorTraits++;
}
// check old/new traits
if (gGameOptions.fNewTraitSystem)
{
for ( INT8 bCnt = 0; bCnt < gSkillTraitValues.ubMaxNumberOfTraits; bCnt++ )
for ( INT8 bCnt = 0; bCnt < min(30,bMaxTraits); bCnt++ )
{
if ( uiSkillTraitNumber > 0 && uiSkillTraitNumber <= NUM_MAJOR_TRAITS )
{
@@ -14506,7 +14669,7 @@ INT8 NUM_SKILL_TRAITS( SOLDIERTYPE * pSoldier, UINT8 uiSkillTraitNumber )
bNumMajorTraitsCounted++;
}
// if we exceeded the allowed number of major traits, ignore the rest of them
if ( bNumMajorTraitsCounted >= gSkillTraitValues.ubNumberOfMajorTraitsAllowed )
if ( bNumMajorTraitsCounted >= min(20,bMaxMajorTraits) )
{
break;
}
@@ -14761,4 +14924,250 @@ UINT8 RegainDamagedStats( SOLDIERTYPE * pSoldier, UINT16 usAmountRegainedHundred
// Done, return what we healed
return( bStatsReturned );
}
////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - Improved Interrupt System
/////////////////////////////////////////
BOOLEAN ResolvePendingInterrupt( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType )
{
// real time or not in combat? disable and clear
if (!(gTacticalStatus.uiFlags & TURNBASED) ||
!(gTacticalStatus.uiFlags & INCOMBAT) )
{
gTacticalStatus.ubInterruptPending = DISABLED_INTERRUPT;
ClearIntList();
return( FALSE );
}
// invalid guy
if ( pSoldier == NULL )
{
//ClearIntList();
return( FALSE );
}
// can't be interrupted if it's not our turn at all
if ( gTacticalStatus.ubCurrentTeam != pSoldier->bTeam )
{
return( FALSE );
}
// no interrupt called or not gonna trigger it now
if ( gTacticalStatus.ubInterruptPending == DISABLED_INTERRUPT ||
gTacticalStatus.ubInterruptPending == UNTRIGGERED_INTERRUPT )
{
return( FALSE );
}
// if the interrupt called match the type we are trying to resolve..
if ( gTacticalStatus.ubInterruptPending == ubInterruptType || ubInterruptType == INSTANT_INTERRUPT )
{
/////////////////////////////
// Gather all interrupters //
/////////////////////////////
SOLDIERTYPE *pInterrupter;
UINT8 ubInterruptersFound = 0;
UINT8 ubaInterruptersList[64];
UINT16 uCnt = 0, uiReactionTime;
INT16 iInjuryPenalty;
for ( uCnt = 0; uCnt <= MAX_NUM_SOLDIERS; uCnt++ )
{
// first find all guys who can see us
pInterrupter = MercPtrs[ uCnt ];
if ( pInterrupter == NULL )
continue; // not valid
if ( pInterrupter->stats.bLife < OKLIFE || pInterrupter->bCollapsed || !pInterrupter->bActive || !pInterrupter->bInSector || pInterrupter->bActionPoints < 4 )
continue; // not active
if ( pSoldier->bTeam == pInterrupter->bTeam )
continue; // same team
if ( pSoldier->bSide == pInterrupter->bSide )
continue; // not enemy
if ( CONSIDERED_NEUTRAL( pSoldier, pInterrupter ) )
continue; // neutral
/////////////////////////////////////////////////////////////
// Calculate Reaction Time (i.e. interrupt counter length) //
/////////////////////////////////////////////////////////////
// set base value ( interrupt per every X APs an enemy uses )
if ( pInterrupter->aiData.bOppList[pSoldier->ubID] == SEEN_CURRENTLY ) // if we see him
{
uiReactionTime = gGameExternalOptions.ubBasicReactionTimeLengthIIS;
}
else // if not seen the length is higher (we don't want to interrupt in most cases here)
{
uiReactionTime = (gGameExternalOptions.ubBasicReactionTimeLengthIIS * 2);
}
uiReactionTime = uiReactionTime * 10; // x10 ... we will divide by 10 after all adjustments done
// adjust based on Agility
if ( pInterrupter->stats.bAgility >= 80 )
{
uiReactionTime = (uiReactionTime * (100 - (2 * (pInterrupter->stats.bAgility - 80)))/100);
}
else if ( pInterrupter->stats.bAgility < 80 && pInterrupter->stats.bAgility > 50 )
{
uiReactionTime = (uiReactionTime * (100 + (2 * (80 - pInterrupter->stats.bAgility)))/100);
}
else
{
uiReactionTime = (uiReactionTime * 8/5);
}
// adjust based on APs left
// at full possible APs no adjustement (100% applies), +1% length per every 2% of APs down from full
uiReactionTime = (uiReactionTime * (100 + (50 - (50 * pInterrupter->bActionPoints / pInterrupter->CalcActionPoints())) ) /100);
// adjust based on injuries
if (pInterrupter->stats.bLife < pInterrupter->stats.bLifeMax)
{
// OK, this looks a bit complicated..
// our HP lost minus half of the bandaged part gives us 2% longer reaction time per 1% of our health down from full health
// this penalty is however slightly reduced by our experience level
iInjuryPenalty = ( 200 * (pInterrupter->stats.bLifeMax - pInterrupter->stats.bLife + ((pInterrupter->stats.bLifeMax - pInterrupter->stats.bLife - pInterrupter->bBleeding) / 2))) / (pInterrupter->stats.bLifeMax);
uiReactionTime = (uiReactionTime * (100 + iInjuryPenalty * (100 - (3 * EffectiveExpLevel( pInterrupter ))) / 100) / 100);
}
// adjust by breath down
if (pSoldier->bBreath < 100)
{
// +1% per 2 points of breath down
uiReactionTime = (uiReactionTime * (100 + ((100 - pSoldier->bBreath)/2)) /100);
}
// adjust for getting aid, being in gas or being in shock
if ( pInterrupter->flags.uiStatusFlags & SOLDIER_GASSED )
uiReactionTime = (uiReactionTime * (100 + AIM_PENALTY_GASSED) /100);
if (pInterrupter->ubServiceCount > 0)
uiReactionTime = (uiReactionTime * (100 + AIM_PENALTY_GETTINGAID) /100);
if (pInterrupter->aiData.bShock)
uiReactionTime = (uiReactionTime * (100 + (pInterrupter->aiData.bShock * 20)) /100); // this is severe, 20% per point
// Phlegmatic characters has slightly longer reaction time
if ( pSoldier->ubProfile != NO_PROFILE )
{
if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_PHLEGMATIC )
{
uiReactionTime = ((uiReactionTime * 110) / 100);
}
}
// finally divide back by 10 to get the needed result (round properly)
uiReactionTime = ((uiReactionTime + 5) / 10);
/////////////////////////////////////////////
// Check if we reached reaction time value //
/////////////////////////////////////////////
// if we have hit the needed amount, the actual interrupt occurs for the observer
if ( pInterrupter->aiData.ubInterruptCounter[pSoldier->ubID] >= uiReactionTime )
{
///////////////////////////
// Success! Add to list! //
///////////////////////////
// the soldier to be interrupted is added to the list (once only)
if ( ubInterruptersFound == 0)
{
AddToIntList( pSoldier->ubID, FALSE, TRUE);
}
ubaInterruptersList[ubInterruptersFound] = pInterrupter->ubID;
ubInterruptersFound++;
// add the observer who got the interrupt
AddToIntList( pInterrupter->ubID, TRUE, TRUE);
// reset the counter
pInterrupter->aiData.ubInterruptCounter[pSoldier->ubID] = 0;
}
}
if ( ubInterruptersFound > 0 )
{
////////////////////////////////////////////////
// Check for possible "Collective Interrupts" //
////////////////////////////////////////////////
if ( gGameExternalOptions.fAllowCollectiveInterrupts )
{
SOLDIERTYPE *pTeammate;
UINT16 uCnt2 = 0, usColIntChance = 0;
UINT8 ubOriginalInterruptersCount = ubInterruptersFound, uCnt3 = 0;
BOOLEAN fAlreadyIn;
for ( uCnt = 0; uCnt < ubOriginalInterruptersCount; uCnt++ )
{
pInterrupter = MercPtrs[ ubaInterruptersList[uCnt] ];
uCnt2 = gTacticalStatus.Team[ pInterrupter->bTeam ].bFirstID;
for ( pTeammate = MercPtrs[ uCnt2 ]; uCnt2 <= gTacticalStatus.Team[ pInterrupter->bTeam ].bLastID; uCnt2++,pTeammate++)
{
if ( pTeammate == NULL )
continue; // not valid
if ( pTeammate->bTeam != pInterrupter->bTeam )
continue; // little paranoya check here
if ( pTeammate->stats.bLife < OKLIFE || pTeammate->bCollapsed || !pTeammate->bActive || !pTeammate->bInSector || pTeammate->bActionPoints < 4 )
continue; // not active
// check if we haven't been added to the list already
fAlreadyIn = FALSE;
for ( uCnt3 = 0; uCnt3 < ubInterruptersFound; uCnt3++ )
{
if ( pTeammate->ubID == ubaInterruptersList[uCnt3] )
{
fAlreadyIn = TRUE;
break;
}
}
// if we are close enough
if ( !fAlreadyIn && PythSpacesAway( pInterrupter->sGridNo, pTeammate->sGridNo ) <= 5 )
{
// calculate the chance
// we would have base chance 100% (if both have maxed stats)
// 0-30% is determined by Leadership of the original interrupted - i.e. how well and if he can "inform" us
// 0-20% is determined by his Experience Level
// 0-20% is determined by our Experience Level - i.e how well can we realize that we must act
// 0-20% is determined by our Agility - can our body react so swiftly at all
// 0-10% is determined by our Wisdom - do we have enough mental agility as well?
usColIntChance = 10*( ( (pInterrupter->stats.bLeadership * 3) +
(EffectiveExpLevel( pInterrupter ) * 20) +
(EffectiveExpLevel( pTeammate ) * 20) +
(pTeammate->stats.bAgility * 2) +
(pTeammate->stats.bWisdom) ) / 100 );
// add bonus per Squadleader trait of the original interrupter
if ( HAS_SKILL_TRAIT( pInterrupter, SQUADLEADER_NT ) && gGameOptions.fNewTraitSystem )
{
usColIntChance += gSkillTraitValues.ubSLCollectiveInterruptsBonus * NUM_SKILL_TRAITS( pInterrupter, SQUADLEADER_NT );
}
if ( PreChance(usColIntChance))
{
ubaInterruptersList[ubInterruptersFound] = pTeammate->ubID;
ubInterruptersFound++;
// if he can react on collective interrupt, give it to him
AddToIntList( pTeammate->ubID, TRUE, TRUE);
// reset the counter for him
pTeammate->aiData.ubInterruptCounter[pSoldier->ubID] = 0;
}
}
}
}
}
/////////////////////////////////////////////
// OK, done, all interrupters added, SEND! //
/////////////////////////////////////////////
// remove AI control from the interrupted guy just in case may not be neccessary, but it's harmless anyway
if ( (gTacticalStatus.ubCurrentTeam != pSoldier->bTeam) && !(gTacticalStatus.Team[ gTacticalStatus.ubCurrentTeam ].bHuman) )
{
if ( pSoldier->flags.uiStatusFlags & SOLDIER_UNDERAICONTROL )
{
pSoldier->flags.uiStatusFlags &= (~SOLDIER_UNDERAICONTROL);
}
}
// reset
gTacticalStatus.ubInterruptPending = DISABLED_INTERRUPT;
// start interrupt
DoneAddingToIntList( pSoldier, TRUE, 1 );
return( TRUE );
}
else // no interrupters found, reset until next occasion
{
// reset
gTacticalStatus.ubInterruptPending = DISABLED_INTERRUPT;
}
}
return( FALSE );
}
+34 -1
View File
@@ -24,7 +24,11 @@
// TEMP VALUES FOR NAMES
#define MAXCIVLASTNAMES 30
extern UINT16 CivLastNames[MAXCIVLASTNAMES][10];
#ifdef JA2UB
//ja25ub
#define NUM_ASSIST_SLOTS 156 //used for when the player asssists in killing the enemty
#endif
// ANDREW: these are defines for OKDestanation usage - please move to approprite file
#define IGNOREPEOPLE 0
@@ -133,12 +137,23 @@ INT8 NUM_SKILL_TRAITS( SOLDIERTYPE * pSoldier, UINT8 uiSkillTraitNumber );
#define SOLDIER_QUOTE_SAID_EXT_SEEN_CREATURE_ATTACK 0x0002
#define SOLDIER_QUOTE_SAID_EXT_USED_BATTLESOUND_HIT 0x0004
#define SOLDIER_QUOTE_SAID_EXT_CLOSE_CALL 0x0008
//Ja25: no mike
#ifdef JA2UB
#define SOLDIER_QUOTE_SAID_EXT_MORRIS 0x0010 //Ja25 UB
#else
#define SOLDIER_QUOTE_SAID_EXT_MIKE 0x0010
#endif
#define SOLDIER_QUOTE_SAID_DONE_ASSIGNMENT 0x0020
#define SOLDIER_QUOTE_SAID_BUDDY_1_WITNESSED 0x0040
#define SOLDIER_QUOTE_SAID_BUDDY_2_WITNESSED 0x0080
#define SOLDIER_QUOTE_SAID_BUDDY_3_WITNESSED 0x0100
#ifdef JA2UB
#define SOLDIER_QUOTE_SAID_THOUGHT_KILLED_YOU 0x0200
#endif
#define SOLDIER_CONTRACT_RENEW_QUOTE_NOT_USED 0
#define SOLDIER_CONTRACT_RENEW_QUOTE_89_USED 1
@@ -475,6 +490,7 @@ public:
INT8 fAIFlags;
INT16 bAimTime; //100AP
INT8 bShownAimTime;
UINT8 ubInterruptCounter[MAX_NUM_SOLDIERS]; // SANDRO - interrupt counter added
};
class STRUCT_Flags//last edited at version 102
@@ -1126,6 +1142,15 @@ public:
// I don't know if this is a good idea at all...
//INT16 filler;
#ifdef JA2UB
//ja25
BOOLEAN fIgnoreGetupFromCollapseCheck;
TIMECOUNTER GetupFromJA25StartCounter;
BOOLEAN fWaitingToGetupFromJA25Start;
UINT8 ubPercentDamageInflictedByTeam[NUM_ASSIST_SLOTS]; //The percent of damage inflicted by the player team. Each element corresponds to the Soldier ID. Each element contains the percent damage inflicted by that merc
#endif
char endOfPOD; // marker for end of POD (plain old data)
// Note: Place all non-POD items at the end (after endOfPOD)
@@ -1415,6 +1440,7 @@ void HandlePlayerTogglingLightEffects( BOOLEAN fToggleValue );
UINT8 GetSquadleadersCountInVicinity( SOLDIERTYPE * pSoldier, BOOLEAN fWithHigherLevel, BOOLEAN fDontCheckDistance );
UINT16 NumberOfDamagedStats( SOLDIERTYPE * pSoldier );
UINT8 RegainDamagedStats( SOLDIERTYPE * pSoldier, UINT16 usAmountRegainedHundredths );
BOOLEAN ResolvePendingInterrupt( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType );
//typedef struct
class OLDSOLDIERTYPE_101
@@ -2094,7 +2120,14 @@ public:
INT8 snowCamo;
INT8 wornSnowCamo;
#ifdef JA2UB
BOOLEAN fIgnoreGetupFromCollapseCheck;
TIMECOUNTER GetupFromJA25StartCounter;
BOOLEAN fWaitingToGetupFromJA25Start;
UINT8 ubPercentDamageInflictedByTeam[NUM_ASSIST_SLOTS]; //The percent of damage inflicted by the player team. Each element corresponds to the Soldier ID. Each element contains the percent damage inflicted by that merc
#endif
UINT8 bFiller[ 36 ];
//
+171 -12
View File
@@ -52,6 +52,11 @@
#include "message.h"
#include "fresh_header.h"
#ifdef JA2UB
#include "Ja25_Tactical.h"
#include "Ja25 Strategic Ai.h"
#endif
// THESE 3 DIFFICULTY FACTORS MUST ALWAYS ADD UP TO 100% EXACTLY!!!
#define DIFF_FACTOR_PLAYER_PROGRESS 50
#define DIFF_FACTOR_PALACE_DISTANCE 30
@@ -566,7 +571,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
BOOLEAN fGuyAvail = FALSE;
UINT8 bLastTeamID;
UINT8 ubVehicleID = 0;
*pubID = NOBODY;
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("TacticalCreateSoldier"));
@@ -1004,36 +1009,48 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
case ELDORADO:
case ICECREAMTRUCK:
case JEEP:
case TANK_NW:
case TANK_NE:
case TANK_NW:
case TANK_NE:
Soldier.flags.uiStatusFlags |= SOLDIER_VEHICLE;
switch( Soldier.ubBodyType )
{
case HUMVEE:
case ELDORADO:
case ICECREAMTRUCK:
case JEEP:
if ( Soldier.ubProfile != HELICOPTER || Soldier.ubProfile != 0 || Soldier.ubProfile != NO_PROFILE || Soldier.ubProfile != TANK_CAR )
{
ubVehicleID = Soldier.ubProfile;
Soldier.aiData.bNeutral = gNewVehicle[Soldier.ubProfile].bNewNeutral;
}
break;
/* case HUMVEE:
ubVehicleID = HUMMER;
Soldier.aiData.bNeutral = TRUE;
Soldier.aiData.bNeutral = TRUE;
break;
case ELDORADO:
ubVehicleID = ELDORADO_CAR;
Soldier.aiData.bNeutral = TRUE;
Soldier.aiData.bNeutral = TRUE;
break;
case ICECREAMTRUCK:
ubVehicleID = ICE_CREAM_TRUCK;
Soldier.aiData.bNeutral = TRUE;
Soldier.aiData.bNeutral = TRUE;
break;
case JEEP:
ubVehicleID = JEEP_CAR;
break;
*/
case TANK_NW:
case TANK_NE:
@@ -2867,7 +2884,7 @@ SOLDIERTYPE* TacticalCreateCreature( INT8 bCreatureBodyType )
void RandomizeRelativeLevel( INT8 *pbRelLevel, UINT8 ubSoldierClass )
{
UINT8 ubLocationModifier;
UINT8 ubLocationModifier = 0;
INT8 bRollModifier;
INT8 bRoll, bAdjustedRoll;
@@ -3105,6 +3122,20 @@ void CopyProfileItems( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCreateStruc
// to provide one which doesn't work and would confuse everything.
switch( pCreateStruct->ubProfile )
{
#ifdef JA2UB
case 75: //MORRIS:
if ( pProfile->inv[ cnt ] >= KEY_1 && pProfile->inv[ cnt ] <= KEY_32)
{
fRet = CreateKeyObject( &gTempObject , pProfile->bInvNumber[ cnt ], 32 );
//CreateKeyObject( &(pSoldier->inv[ cnt ] ), pProfile->bInvNumber[ cnt ], 32 );
}
//else
//{
// memset( &(pSoldier->inv[cnt]), 0, sizeof( OBJECTTYPE ) );
//}
break;
#endif
// WANNE: Changed KEY_32 to KEY_8 because we only have 8 keys defined in Items.xml
case BREWSTER:
if ( pProfile->inv[ cnt ] >= KEY_1 && pProfile->inv[ cnt ] <= KEY_8){
@@ -3202,17 +3233,145 @@ void TrashAllSoldiers( )
UINT8 GetLocationModifier( UINT8 ubSoldierClass )
{
UINT8 ubLocationModifier;
UINT8 ubPalaceDistance;
UINT8 ubLocationModifier = 0;
INT16 sSectorX, sSectorY, sSectorZ;
#ifdef JA2UB
#else
INT8 bTownId;
UINT8 ubPalaceDistance;
#endif
BOOLEAN fSuccess;
// where is all this taking place?
fSuccess = GetCurrentBattleSectorXYZ( &sSectorX, &sSectorY, &sSectorZ );
Assert( fSuccess );
#ifdef JA2UB
//Ja25 UB
//switch on the sector, to determine modifer
//the modifier is based between 0 and 40. 40 being the "hardest"
switch( SECTOR( sSectorX, sSectorY ) )
{
//Starting sector
case SEC_H7:
ubLocationModifier = 4;
break;
//First sector that has enemies in it
case SEC_H8:
ubLocationModifier = 8;
break;
//Guard Post
case SEC_H9:
ubLocationModifier = 14;
break;
// The 2 "empty" sectors before the town ( north and west of town )
case SEC_H10:
case SEC_I9:
ubLocationModifier = 12;
break;
//the town of varrez
case SEC_I10:
ubLocationModifier = 16;
break;
case SEC_I11:
ubLocationModifier = 19;
break;
// The 2 "empty" sectors after the town ( east and south of town )
case SEC_I12:
case SEC_J11:
ubLocationModifier = 22;
break;
//The abandoned mine
case SEC_I13:
ubLocationModifier = 22;
break;
//"empty field" that player can take to avoid going through the mine
case SEC_J12:
ubLocationModifier = 22;
break;
//The power Generator facility
case SEC_J13:
{
//the top floor
switch( sSectorZ )
{
//Main floor
case 0:
ubLocationModifier = 26;
break;
//Basement level
case 1:
ubLocationModifier = 15;
break;
default:
Assert( 0 );
break;
}
}
break;
//tunnel levels, no enemies
case SEC_J14:
case SEC_K14:
ubLocationModifier = 35;
break;
case SEC_K15:
{
//the top floor
switch( sSectorZ )
{
//Main floor
case 0:
ubLocationModifier = 30;
break;
//Basement level
case 1:
ubLocationModifier = 28;
break;
case 2:
ubLocationModifier = 35;
break;
default:
ubLocationModifier = 0;
// Assert( 0 );
break;
}
}
break;
case SEC_L15:
{
//the top floor
switch( sSectorZ )
{
//Basement level
case 2:
ubLocationModifier = 40;
break;
case 3:
ubLocationModifier = 40;
break;
default:
Assert( 0 );
break;
}
}
break;
}
#else
// ignore sSectorZ - treat any underground enemies as if they were on the surface!
bTownId = GetTownIdForSector( sSectorX, sSectorY );
@@ -3242,7 +3401,7 @@ UINT8 GetLocationModifier( UINT8 ubSoldierClass )
// adjust for distance from Queen's palace (P3) (0 to +30)
ubLocationModifier = ( ( MAX_PALACE_DISTANCE - ubPalaceDistance ) * DIFF_FACTOR_PALACE_DISTANCE ) / MAX_PALACE_DISTANCE;
#endif
return( ubLocationModifier );
}
+18
View File
@@ -707,6 +707,9 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL )
}
}
}
#ifdef JA2UB
//Ja25: no queen
#else
else if ( !gfInMeanwhile && gWorldSectorX == 3 && gWorldSectorY == 16 && !gbWorldSectorZ )
{ //Special civilian setup for queen's palace.
if( gubFact[ FACT_QUEEN_DEAD ] )
@@ -728,6 +731,7 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL )
}
}
}
#endif
else if ( gWorldSectorX == TIXA_SECTOR_X && gWorldSectorY == TIXA_SECTOR_Y && gbWorldSectorZ == 0 )
{
// Tixa prison, once liberated, should not have any civs without profiles unless
@@ -788,6 +792,20 @@ BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *curr, GROUP *pGroup = NULL )
}
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("AddPlacementToWorld: return true"));
/*
#ifdef JA2UB
INT32 iCnt;
for( iCnt=0; iCnt< NUM_ORIGINAL_INV_SLOTS; iCnt++)
{
if ( gGameOptions.ubInventorySystem == INVENTORY_OLD && gGameOptions.ubAttachmentSystem == ATTACHMENT_OLD )
{
if( pSoldier->inv[ iCnt ].usItem == 97 || pSoldier->inv[ iCnt ].usItem == 1346 || pSoldier->inv[ iCnt ].usItem == 99
|| pSoldier->inv[ iCnt ].usItem == 1347 || pSoldier->inv[ iCnt ].usItem == 584 || pSoldier->inv[ iCnt ].usItem == 551 ) //43
pSoldier->inv[ iCnt ].usItem = 129; //335
}
}
#endif
*/
return TRUE;
}
else
+79 -5
View File
@@ -61,6 +61,13 @@
#include "AimFacialIndex.h"
#include "mercs.h"
#ifdef JA2UB
#include "Ja25_Tactical.h"
#endif
#include "ub_config.h"
#include "XML.h"
#include "connect.h"
#ifdef JA2EDITOR
extern BOOLEAN gfProfileDataLoaded;
@@ -499,7 +506,9 @@ BOOLEAN LoadMercProfiles(void)
// FILE *fptr;
HWFILE fptr;
STR8 pFileName = "BINARYDATA\\Prof.dat";
#ifdef JA2UB
STR8 pFileName_UB = "BINARYDATA\\JA25PROF.DAT";
#endif
STR8 pFileName1_Normal = "BINARYDATA\\Prof_Novice_NormalGuns.dat";
STR8 pFileName2_Normal = "BINARYDATA\\Prof_Experienced_NormalGuns.dat";
STR8 pFileName3_Normal = "BINARYDATA\\Prof_Expert_NormalGuns.dat";
@@ -517,6 +526,7 @@ BOOLEAN LoadMercProfiles(void)
//InitNewProfiles();
// ----- WANNE.PROFILE: New Profile Loading - END
if (gGameExternalOptions.fUseDifficultyBasedProfDat == TRUE)
{
switch ( gGameOptions.ubDifficultyLevel)
@@ -552,7 +562,17 @@ BOOLEAN LoadMercProfiles(void)
}
else
{
#ifdef JA2UB
fptr = FileOpen(pFileName_UB, FILE_ACCESS_READ, FALSE ); //ub
if( !fptr )
{
fptr = FileOpen(pFileName, FILE_ACCESS_READ, FALSE ); //ja
}
#else
fptr = FileOpen(pFileName, FILE_ACCESS_READ, FALSE );
#endif
}
@@ -867,6 +887,27 @@ BOOLEAN LoadMercProfiles(void)
}
FileClose( fptr );
//WriteMercStartingGearStats();
//--------------
/*
CHAR8 fileName[255];
//JA25 UB
for( int i = 0; i < NUM_PROFILES; i++ )
{
strcpy(fileName, "TABLEDATA\\Profile\\prof03.xml");
//sprintf( fileName, "TABLEDATA\\Profile\\prof%03d.xml", i );
if ( FileExists(fileName) )
{
ReadInMercProfiles(fileName,FALSE,i,TRUE);
}
}
*/
//--------------
// ---------------
@@ -1061,6 +1102,9 @@ void MakeRemainingTerroristsTougher( void )
{
if ( gMercProfiles[ gubTerrorists[ ubLoop ] ].bMercStatus != MERC_IS_DEAD && gMercProfiles[ gubTerrorists[ ubLoop ] ].sSectorX != 0 && gMercProfiles[ gubTerrorists[ ubLoop ] ].sSectorY != 0 )
{
#ifdef JA2UB
//no Ub
#else
if ( gubTerrorists[ ubLoop ] == SLAY )
{
if ( FindSoldierByProfileID( SLAY, TRUE ) != NULL )
@@ -1069,6 +1113,7 @@ void MakeRemainingTerroristsTougher( void )
continue;
}
}
#endif
ubRemainingTerrorists++;
}
}
@@ -1132,6 +1177,10 @@ void MakeRemainingTerroristsTougher( void )
{
if ( gMercProfiles[ gubTerrorists[ ubLoop ] ].bMercStatus != MERC_IS_DEAD && gMercProfiles[ gubTerrorists[ ubLoop ] ].sSectorX != 0 && gMercProfiles[ gubTerrorists[ ubLoop ] ].sSectorY != 0 )
{
#ifdef JA2UB
// no UB
#else
if ( gubTerrorists[ ubLoop ] == SLAY )
{
if ( FindSoldierByProfileID( SLAY, TRUE ) != NULL )
@@ -1140,7 +1189,7 @@ void MakeRemainingTerroristsTougher( void )
continue;
}
}
#endif
if ( usOldItem != NOTHING )
{
RemoveObjectFromSoldierProfile( gubTerrorists[ ubLoop ], usOldItem );
@@ -1289,9 +1338,29 @@ void StartSomeMercsOnAssignment(void)
}
pProfile = &(gMercProfiles[ uiCnt ]);
#ifdef JA2UB
//Make sure stigie and Gaston are available at the start of the game
/* if( uiCnt == 59 || uiCnt == 58 )
{
pProfile->bMercStatus = MERC_OK;
pProfile->uiDayBecomesAvailable = 0;
pProfile->uiPrecedentQuoteSaid = 0;
pProfile->ubDaysOfMoraleHangover = 0;
continue;
}
*/
//if the merc is dead, dont modify anything
if( pProfile->bMercStatus == MERC_IS_DEAD )
{
continue;
}
// calc chance to start on assignment
uiChance = 3 * pProfile->bExpLevel; //5 Ja25 UB
#else
uiChance = 5 * pProfile->bExpLevel;
#endif
// tais: disable mercs being on assignment (this check is just for at the start of the campaign)
if (Random(100) < uiChance && gGameExternalOptions.fMercsOnAssignment < 1)
@@ -1671,13 +1740,15 @@ BOOLEAN RecruitRPC( UINT8 ubCharNum )
SwapObjs( pNewSoldier, bSlot, HANDPOS, TRUE );
}
}
#ifdef JA2UB
// no Ja25 UB
#else
if ( ubCharNum == IRA )
{
// trigger 0th PCscript line
TriggerNPCRecord( IRA, 0 );
}
#endif
// Set whatkind of merc am i
pNewSoldier->ubWhatKindOfMercAmI = MERC_TYPE__NPC;
@@ -1695,7 +1766,10 @@ BOOLEAN RecruitRPC( UINT8 ubCharNum )
//remove the merc from the Personnel screens departed list ( if they have never been hired before, its ok to call it )
RemoveNewlyHiredMercFromPersonnelDepartedList( pSoldier->ubProfile );
#ifdef JA2UB
//If this is a special NPC, play a quote from the team mates
HandlePlayingQuoteWhenHiringNpc( pNewSoldier->ubProfile );
#endif
return( TRUE );
}
+17 -1
View File
@@ -34,6 +34,7 @@ extern INT16 gsTerroristSector[][5][2];
extern BOOLEAN gfPotentialTeamChangeDuringDeath;
extern MERCPROFILESTRUCT gMercProfiles[ NUM_PROFILES ];
extern MERCPROFILEGEAR gMercProfileGear[ NUM_PROFILES ][ NUM_MERCSTARTINGGEAR_KITS ];
@@ -98,8 +99,11 @@ enum NPCIDs
COUGAR,
NUMB,
BUBBA,
#ifdef JA2UB
MIGUEL = 58, //Ja25: Was 57
#else
MIGUEL = 57,
#endif
CARLOS,
IRA,
DIMITRI,
@@ -108,7 +112,11 @@ enum NPCIDs
ROBOT,
HAMOUS,
SLAY,
#ifdef JA2UB
// RPC65,
#else
RPC65,
#endif
DYNAMO,
SHANK,
IGGY,
@@ -219,11 +227,19 @@ enum NPCIDs
PROF_ICECREAM,
PROF_HELICOPTER,
NPC164,
#ifdef JA2UB
NPC165,
NPC166,
NPC167,
NPC168,
NPC169,
#else
GASTON,
STOGIE,
TEX,
BIGGENS,
NPC169,
#endif
NPC170 = NPC169 + 84,
} ;
+60
View File
@@ -92,6 +92,15 @@ void InitSquads( void )
BOOLEAN IsThisSquadFull( INT8 bSquadValue )
{
//SQUAD10 FIX: Number of taken slots should not exceed 6/8/10 depending on resolution
if ( NumberOfPeopleInSquad( bSquadValue ) >= gGameOptions.ubSquadSize )
{
return( true );
}
return ( false );
/*
INT32 iCounter = 0;
// run through entries in the squad list, make sure there is a free entry
@@ -107,6 +116,7 @@ BOOLEAN IsThisSquadFull( INT8 bSquadValue )
// no free slots - it's full
return( TRUE );
*/
}
INT8 GetFirstEmptySquad( void )
@@ -127,6 +137,47 @@ INT8 GetFirstEmptySquad( void )
return( -1 );
}
void FixOversizedSquadsInSector( void )
{
// SQUAD10: Fix any squads in current tactical map with more people than allowed at current resolution
INT32 iCountSquad = 0;
INT8 iCountSoldier = 0;
INT8 iPeopleInSquad = 0;
// loop through all squads
for( iCountSquad = 0; iCountSquad < NUMBER_OF_SQUADS; iCountSquad++ )
{
// but deal only with squads in current sector
if( IsSquadOnCurrentTacticalMap( iCountSquad ) == TRUE )
{
// found a squad in current sector...check size
iPeopleInSquad = NumberOfPeopleInSquad( iCountSquad );
while ( iPeopleInSquad > gGameOptions.ubSquadSize )
{
// oversized squad found -- move some people to another squad
//
// loop backwards through the squad in order to remove the last person
for( iCountSoldier = NUMBER_OF_SOLDIERS_PER_SQUAD - 1; iCountSoldier >= 0 ; iCountSoldier-- )
{
// if squad is still oversized, and we have found a squad member
if( (Squad[ iCountSquad ][ iCountSoldier ] != NULL) && (iPeopleInSquad > gGameOptions.ubSquadSize) )
{
// ... attempt to move him to another squad
if ( AddCharacterToAnySquad( Squad[ iCountSquad ][ iCountSoldier ] ) == TRUE )
{
// success: we got rid of one person in this squad
iPeopleInSquad--;
}
}
}
// we've looped through all members off the squad
// reset iPeopleInSquad as there is nothing more we can do
iPeopleInSquad = 0;
}
}
}
}
BOOLEAN AddCharacterToSquad( SOLDIERTYPE *pCharacter, INT8 bSquadValue )
{
INT8 bCounter =0;
@@ -178,7 +229,16 @@ BOOLEAN AddCharacterToSquad( SOLDIERTYPE *pCharacter, INT8 bSquadValue )
// 'successful of sorts, if there, then he's 'added'
return ( TRUE );
}
}
if ( NumberOfPeopleInSquad( bSquadValue ) >= gGameOptions.ubSquadSize )
{
// SQUAD10: too many people in this squad
return( FALSE );
}
for( bCounter =0; bCounter < NUMBER_OF_SOLDIERS_PER_SQUAD; bCounter++ )
{
// free slot, add here
if( Squad[ bSquadValue ][ bCounter ] == NULL )
{
+4 -1
View File
@@ -6,7 +6,7 @@
#include "Overhead Types.h"
// header for squad management system
#define NUMBER_OF_SOLDIERS_PER_SQUAD 6
#define NUMBER_OF_SOLDIERS_PER_SQUAD 10
// enums for squads
enum{
@@ -172,4 +172,7 @@ BOOLEAN DoesVehicleExistInSquad( INT8 bSquadValue );
// re-create any trashed squad movement groups
void CheckSquadMovementGroups( void );
//SQUAD10: Check for squads that are oversized at current resolution and move them to another squad
void FixOversizedSquadsInSector( void );
#endif
+15
View File
@@ -37,6 +37,12 @@
#include "Creature Spreading.h"
#endif
#ifdef JA2UB
#include "Explosion Control.h"
#include "Ja25 Strategic Ai.h"
#include "Ja25_Tactical.h"
#endif
BOOLEAN gfInSectorExitMenu = FALSE;
void CheckLoadMapCallback( GUI_BUTTON *btn, INT32 reason );
@@ -760,6 +766,15 @@ void RemoveSectorExitMenu( BOOLEAN fOk )
if ( fOk )
{
#ifdef JA2UB
//ja25 ub
//If this is the sector with the power fan
if( gWorldSectorX == 13 && gWorldSectorY == 10 && gbWorldSectorZ == 0 )
{
//Remeber how the player got through
HandleHowPlayerGotThroughFan();
}
#endif
// Handle the effects here!
if ( gExitDialog.fAllMove && gExitDialog.fGotoSector && gExitDialog.fGotoSectorText )
{
+13 -5
View File
@@ -47,7 +47,7 @@
#include "Queen Command.h"
#include "Map Screen Interface Map Inventory.h"
#endif
#include "Animation Control.h"
#include <vfs/Core/vfs.h>
BOOLEAN gfWasInMeanwhile = FALSE;
@@ -931,12 +931,15 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( )
gfWasInMeanwhile = FALSE;
return TRUE;
}
#ifdef JA2UB
//Ja25v No meanwhiles
#else
else if( AreInMeanwhile() )
{
gfInMeanwhile = FALSE;
fShouldBeInMeanwhile = TRUE;
}
#endif
//If we havent been to tactical yet
if( ( gWorldSectorX == 0 ) && ( gWorldSectorY == 0 ) )
{
@@ -1037,11 +1040,14 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( )
EnableModifiedFileSetCache(cacheResetValue);
#ifdef JA2UB
//Ja25 no meanwhile
#else
if( fShouldBeInMeanwhile )
{
gfInMeanwhile = TRUE;
}
#endif
return( TRUE );
}
@@ -1196,7 +1202,9 @@ BOOLEAN LoadCurrentSectorsInformationFromTempItemsFile()
//
// Load in the sectors ITems
//
#ifdef JA2UB
//Ja25v no meanwhiles
#else
if( AreInMeanwhile() )
{ //There will never be a temp file for the meanwhile scene, so return TRUE. However,
//set a flag to not save it either!
@@ -1217,7 +1225,7 @@ BOOLEAN LoadCurrentSectorsInformationFromTempItemsFile()
}
return TRUE;
}
#endif
//if we are in an above ground sector
//If there is a file, load in the Items array
+8 -2
View File
@@ -40,7 +40,10 @@ extern void DecayPublicOpplist( INT8 bTeam );
//not in overhead.h!
extern UINT8 NumEnemyInSector();
#ifdef JA2UB
//no uB
#else
void HandleRPCDescription( )
{
@@ -136,7 +139,7 @@ void HandleRPCDescription( )
}
}
}
#endif
void HandleTacticalEndTurn( )
{
@@ -260,8 +263,11 @@ void HandleTacticalEndTurn( )
}
}
}
#ifdef JA2UB
// HandleRPCDescription( );
#else
HandleRPCDescription( );
#endif
}
+12
View File
@@ -490,6 +490,10 @@
RelativePath=".\Items.h"
>
</File>
<File
RelativePath=".\Ja25_Tactical.h"
>
</File>
<File
RelativePath=".\Keys.h"
>
@@ -820,6 +824,10 @@
RelativePath=".\Items.cpp"
>
</File>
<File
RelativePath=".\Ja25_Tactical.cpp"
>
</File>
<File
RelativePath=".\Keys.cpp"
>
@@ -1132,6 +1140,10 @@
RelativePath=".\XML_TonyInventory.cpp"
>
</File>
<File
RelativePath=".\XML_Vehicles.cpp"
>
</File>
</Filter>
</Files>
<Globals>
+13 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Version="9,00"
Name="Tactical"
ProjectGUID="{8E3BD72D-8791-497B-A38E-D71B255F0A66}"
RootNamespace="Tactical"
@@ -495,6 +495,10 @@
RelativePath="Items.h"
>
</File>
<File
RelativePath=".\Ja25_Tactical.h"
>
</File>
<File
RelativePath="Keys.h"
>
@@ -823,6 +827,10 @@
RelativePath="Items.cpp"
>
</File>
<File
RelativePath=".\Ja25_Tactical.cpp"
>
</File>
<File
RelativePath="Keys.cpp"
>
@@ -1135,6 +1143,10 @@
RelativePath="XML_TonyInventory.cpp"
>
</File>
<File
RelativePath=".\XML_Vehicles.cpp"
>
</File>
</Filter>
</Files>
<Globals>
+3
View File
@@ -61,6 +61,7 @@
<ClInclude Include="Inventory Choosing.h" />
<ClInclude Include="Item Types.h" />
<ClInclude Include="Items.h" />
<ClInclude Include="Ja25_Tactical.h" />
<ClInclude Include="Keys.h" />
<ClInclude Include="LOS.h" />
<ClInclude Include="Map Information.h" />
@@ -144,6 +145,7 @@
<ClCompile Include="Inventory Choosing.cpp" />
<ClCompile Include="Item Types.cpp" />
<ClCompile Include="Items.cpp" />
<ClCompile Include="Ja25_Tactical.cpp" />
<ClCompile Include="Keys.cpp" />
<ClCompile Include="LOS.cpp" />
<ClCompile Include="Map Information.cpp" />
@@ -222,6 +224,7 @@
<ClCompile Include="XML_Sounds.cpp" />
<ClCompile Include="XML_SpreadPatterns.cpp" />
<ClCompile Include="XML_TonyInventory.cpp" />
<ClCompile Include="XML_Vehicles.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{433FBCC4-F612-489C-AA28-CCD6CF27D80C}</ProjectGuid>
+9
View File
@@ -258,6 +258,9 @@
<ClInclude Include="XML_Profiles.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Ja25_Tactical.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Air Raid.cpp">
@@ -602,5 +605,11 @@
<ClCompile Include="XML_NewFaceGear.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XML_Vehicles.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Ja25_Tactical.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
+50 -14
View File
@@ -48,6 +48,11 @@
#include "NPC.h"
#endif
#ifdef JA2UB
#include "Ja25_Tactical.h"
#include "Ja25 Strategic Ai.h"
#endif
// HEADROCK HAM 3.2: Gamesettings.h for external modifications to team turns.
#include "GameSettings.h"
#include "Reinforcement.h"
@@ -257,6 +262,8 @@ void StartPlayerTeamTurn( BOOLEAN fDoBattleSnd, BOOLEAN fEnteringCombatMode )
// ATE: Reset killed on attack variable.. this is because sometimes timing is such
/// that a baddie can die and still maintain it's attacker ID
gTacticalStatus.fKilledEnemyOnAttack = FALSE;
gTacticalStatus.ubInterruptPending = DISABLED_INTERRUPT;
HandleTacticalUI( );
}
@@ -342,6 +349,8 @@ void EndTurn( UINT8 ubNextTeam )
}
gTacticalStatus.ubCurrentTeam = ubNextTeam;
gTacticalStatus.ubInterruptPending = DISABLED_INTERRUPT;
if(is_server || !is_client) BeginTeamTurn( gTacticalStatus.ubCurrentTeam );
@@ -429,6 +438,8 @@ void EndAllAITurns( void )
gTacticalStatus.ubCurrentTeam = gbPlayerNum;
//BeginTeamTurn( gTacticalStatus.ubCurrentTeam );
gTacticalStatus.ubInterruptPending = DISABLED_INTERRUPT;
}
}
@@ -448,6 +459,16 @@ void EndTurnEvents( void )
// decay AI warning values from corpses
DecayRottingCorpseAIWarnings();
#ifdef JA2UB
//Ja25 UB
//increment the number of tactical turns that have gone by in turn based mode
gJa25SaveStruct.uiTacticalTurnCounter++;
//if the fan should start up
HandleStartingFanBackUp();
#endif
}
//rain
@@ -676,12 +697,14 @@ void DisplayHiddenTurnbased( SOLDIERTYPE * pActingSoldier )
// This code should put the game in turn-based and give control to the AI-controlled soldier
// whose pointer has been passed in as an argument (we were in non-combat and the AI is doing
// something visible, i.e. making an attack)
#ifdef JA2UB
//Ja25 No meanwhiles
#else
if ( AreInMeanwhile( ) )
{
return;
}
#endif
if (gTacticalStatus.uiFlags & REALTIME || gTacticalStatus.uiFlags & INCOMBAT)
{
// pointless call here; do nothing
@@ -790,7 +813,8 @@ void StartInterrupt( void )
INT32 iSquad, iCounter;
// build string for display of who gets interrupt
while( 1 )
//while( 1 )
for( iCounter = 0; iCounter <= MAX_NUM_SOLDIERS; iCounter++ )
{
MercPtrs[ubInterrupter]->aiData.bMoved = FALSE;
DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("INTERRUPT: popping %d off of the interrupt queue", ubInterrupter ) );
@@ -908,9 +932,10 @@ void StartInterrupt( void )
}
*/
while( 1 )
//while( 1 )
UINT16 usCounter;
for( usCounter = 0; usCounter <= MAX_NUM_SOLDIERS; usCounter++ )
{
MercPtrs[ubInterrupter]->aiData.bMoved = FALSE;
DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("INTERRUPT: popping %d off of the interrupt queue", ubInterrupter ) );
@@ -931,7 +956,6 @@ void StartInterrupt( void )
ubFirstInterrupter = ubInterrupter;
}
}
{
// here we have to rebuilt the AI list!
BuildAIListForTeam( bTeam );
@@ -939,11 +963,15 @@ void StartInterrupt( void )
// set to the new first interrupter
cnt = RemoveFirstAIListEntry();
pSoldier = MercPtrs[ cnt ];
pTempSoldier = MercPtrs[ cnt ];
// pSoldier = MercPtrs[ubFirstInterrupter];
//if ( gTacticalStatus.ubCurrentTeam == OUR_TEAM )//hayden
if (!is_networked && gTacticalStatus.ubCurrentTeam == OUR_TEAM ) // if ( pSoldier->bTeam > OUR_TEAM && pSoldier->bTeam < 6) // cheap disable
// if ( pSoldier->bTeam > OUR_TEAM && pSoldier->bTeam < 6) // cheap disable
// SANDRO - if we just saw the guy, don't flag it as hidden interrupt
if (!is_networked && gTacticalStatus.ubCurrentTeam == OUR_TEAM
&& MercPtrs[ LATEST_INTERRUPT_GUY ]->aiData.bOppList[pTempSoldier->ubID] != SEEN_CURRENTLY
&& MercPtrs[ LATEST_INTERRUPT_GUY ]->aiData.bOppList[pTempSoldier->ubID] != SEEN_THIS_TURN )
{
// we're being interrupted by the computer!
// we delay displaying any interrupt message until the computer
@@ -953,8 +981,8 @@ void StartInterrupt( void )
}
// otherwise it's the AI interrupting another AI team
if (pSoldier != NULL)
gTacticalStatus.ubCurrentTeam = pSoldier->bTeam;
if (pTempSoldier != NULL)
gTacticalStatus.ubCurrentTeam = pTempSoldier->bTeam;
if (is_networked)
{
@@ -963,10 +991,8 @@ void StartInterrupt( void )
#endif
}
if (pSoldier != NULL)
StartNPCAI( pSoldier );
}
if (pTempSoldier != NULL)
StartNPCAI( pTempSoldier );
}
if ( !gfHiddenInterrupt )
@@ -1106,6 +1132,7 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
// change team
gTacticalStatus.ubCurrentTeam = pSoldier->bTeam;
// switch appropriate messages & flags
if ( pSoldier->bTeam == OUR_TEAM)
{
@@ -1198,6 +1225,9 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
// normal player's turn without readjusting time left in turn (for
// timed turns)
InitPlayerUIBar( 2 );
// SANDRO - shouldn't we unset ui here too?
UnSetUIBusy( pSoldier->ubID );
}
}
@@ -2334,6 +2364,12 @@ void ResolveInterruptsVs( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType)
{
// add this guy to everyone's interrupt queue
AddToIntList(ubIntList[ubSmallestSlot],TRUE,TRUE);
// SANDRO - for IIS, reset counter if we got here
if ( gGameExternalOptions.fImprovedInterruptSystem )
{
// reset the counter
MercPtrs[ ubIntList[ubSmallestSlot] ]->aiData.ubInterruptCounter[pSoldier->ubID] = 0;
}
if (INTERRUPTS_OVER)
{
// a loop was created which removed all the people in the interrupt queue!
+62 -14
View File
@@ -1437,6 +1437,8 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
static BOOLEAN fAltDown = FALSE;
INT32 usMapPos;
BOOLEAN fGoodCheatLevelKey = FALSE;
CHAR16 zString[128];
GetCursorPos(&MousePos);
ScreenToClient(ghWindow, &MousePos); // In window coords!
@@ -1536,7 +1538,9 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
HandleShortCutExitState( );
//*puiNewEvent = I_EXIT;
}
#ifdef JA2UB
//Ja25 No meanwhiles
#else
if ((InputEvent.usEvent == KEY_UP )&& ( InputEvent.usParam == ESC) )
{
if ( AreInMeanwhile() && gCurrentMeanwhileDef.ubMeanwhileID != INTERROGATION )
@@ -1545,11 +1549,29 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
EndMeanwhile();
}
}
// ROMAN.MP
#endif
// It is not allowed in a network game to go to the load screen, because if you cancel the load screen it is always your turn!
if (!is_networked)
{
// WANNE: Just disabled for now
/*
// WANNE: If the game hangs on enemy turn, just press ALT + CTRL + E and the game will continue with enemy turn!!
if ( (InputEvent.usEvent == KEY_DOWN )&& (InputEvent.usKeyState & CTRL_DOWN) && ( InputEvent.usParam == 'e') )
{
if( InputEvent.usKeyState & ALT_DOWN )
{
if (gTacticalStatus.ubCurrentTeam != 0)
{
if( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) )
{
EndTurn( 1 );
}
}
}
}
*/
/// Allow to load everywhere
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == 'l') )
{
@@ -2120,43 +2142,64 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
HandleSelectMercSlot( 5, LOCATEANDSELECT_MERC );
break;
#ifdef JA2TESTVERSION
case F7:
if( fAlt )
if( fShift )
HandleSelectMercSlot( 6, LOCATE_MERC_ONCE );
#ifdef JA2TESTVERSION
else if( fAlt )
{
TestMeanWhile( 16 );
}
#endif
else
HandleSelectMercSlot( 6, LOCATEANDSELECT_MERC );
break;
case F8:
if( fAlt )
case F8:
if( fShift )
HandleSelectMercSlot( 7, LOCATE_MERC_ONCE );
#ifdef JA2TESTVERSION
else if( fAlt )
{
TestMeanWhile( 7 );
}
#endif
else
HandleSelectMercSlot( 7, LOCATEANDSELECT_MERC );
break;
case F9:
if( fCtrl )
if( fShift )
HandleSelectMercSlot( 8, LOCATE_MERC_ONCE );
#ifdef JA2TESTVERSION
else if( fCtrl )
{
TestMeanWhile( 8 );
}
#endif
else
{
#ifdef JA2EDITOR
*puiNewEvent = I_ENTER_EDIT_MODE;
gfMercResetUponEditorEntry = !fAlt;
break;
#endif
HandleSelectMercSlot( 8, LOCATEANDSELECT_MERC );
}
break;
case F10:
if( fAlt )
case F10:
if( fShift )
HandleSelectMercSlot( 9, LOCATE_MERC_ONCE );
#ifdef JA2TESTVERSION
else if( fAlt )
{
TestMeanWhile( 9 );
}
break;
#endif
else
HandleSelectMercSlot( 9, LOCATEANDSELECT_MERC );
break;
case F11:
@@ -3797,7 +3840,10 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
if ( !MercPtrs[ gusSelectedSoldier ]->MercInWater( ) && !(MercPtrs[ gusSelectedSoldier ]->flags.uiStatusFlags & SOLDIER_ROBOT ) )
{
//change selected merc to run
if ( MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != WALKING && MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != RUNNING )
if ( MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != WALKING && MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != RUNNING
&& MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != WALKING_PISTOL_RDY
&& MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != WALKING_RIFLE_RDY
&& MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != WALKING_DUAL_RDY )
{
UIHandleSoldierStanceChange( (UINT8)gusSelectedSoldier, ANIM_STAND );
MercPtrs[ gusSelectedSoldier ]->flags.fUIMovementFast = 1;
@@ -3905,7 +3951,9 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
}
else if ( fCtrl && fShift )
{
SaveGame( SAVE__TIMED_AUTOSAVE, L"Auto Save" );
//SaveGame( SAVE__TIMED_AUTOSAVE_SLOT1, L"Auto Save 1" );
swprintf( zString, L"%s %d",pMessageStrings[ 90 ],SAVE__TIMED_AUTOSAVE_SLOT1);
DoAutoSave(SAVE__TIMED_AUTOSAVE_SLOT1,zString);
}
else
{
+85 -28
View File
@@ -55,10 +55,15 @@ UINT8 ubNumberOfVehicles = 0;
extern INT8 SquadMovementGroups[ ];
NEW_CAR gNewVehicle[NUM_PROFILES];
BOOLEAN SaveNewVehiclesToSaveGameFile( HWFILE hFile );
BOOLEAN LoadNewVehiclesToSaveGameFile( HWFILE hFile );
//ATE: These arrays below should all be in a large LUT which contains
// static info for each vehicle....
// the mvt groups associated with vehcile types
/*
INT32 iMvtTypes[]={
CAR, // eldorado
CAR, // hummer
@@ -111,6 +116,7 @@ UINT8 ubVehicleTypeProfileID[ ] = {
PROF_HELICOPTER
};
*/
/*
// location of crits based on facing
@@ -133,7 +139,7 @@ INT8 bInternalCritHitsByLocation[ NUMBER_OF_EXTERNAL_HIT_LOCATIONS_ON_VEHICLE ][
TANK_CAR,
HELICOPTER,
*/
/*
INT16 sVehicleArmourType[ NUMBER_OF_TYPES_OF_VEHICLES ] =
{
KEVLAR_VEST, // El Dorado
@@ -143,7 +149,7 @@ INT16 sVehicleArmourType[ NUMBER_OF_TYPES_OF_VEHICLES ] =
SPECTRA_VEST, // Tank - do we want this?
KEVLAR_VEST, // Helicopter
};
*/
/*
INT16 sVehicleExternalOrigArmorValues[ NUMBER_OF_TYPES_OF_VEHICLES ][ NUMBER_OF_INTERNAL_HIT_LOCATIONS_IN_VEHICLE ]={
@@ -177,6 +183,32 @@ void SetDriver( INT32 iID, UINT8 ubID );
void TeleportVehicleToItsClosestSector( INT32 iVehicleId, UINT8 ubGroupID );
BOOLEAN SaveNewVehiclesToSaveGameFile( HWFILE hFile )
{
UINT32 uiNumBytesWritten;
FileWrite( hFile, &gNewVehicle, sizeof( gNewVehicle), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( gNewVehicle ) )
{
return( FALSE );
}
return( TRUE );
}
BOOLEAN LoadNewVehiclesToSaveGameFile( HWFILE hFile )
{
UINT32 uiNumBytesRead;
FileRead( hFile, &gNewVehicle, sizeof( gNewVehicle), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( gNewVehicle ) )
{
return( FALSE );
}
return( TRUE );
}
void InitAVehicle(int index, int x, int y) {
gubVehicleMovementGroups[ index ] = CreateNewVehicleGroupDepartingFromSector( x, y, index );
@@ -196,8 +228,9 @@ void InitAllVehicles( ) {
void SetVehicleValuesIntoSoldierType( SOLDIERTYPE *pVehicle )
{
wcscpy( pVehicle->name, zVehicleName[ pVehicleList[ pVehicle->bVehicleID ].ubVehicleType ] );
// wcscpy( pVehicle->name, zVehicleName[ pVehicleList[ pVehicle->bVehicleID ].ubVehicleType ] );
wcscpy( pVehicle->name, gNewVehicle[ pVehicleList[ pVehicle->bVehicleID ].ubVehicleType ].NewVehicleName );
pVehicle->ubProfile = pVehicleList[ pVehicle->bVehicleID ].ubProfileID;
// Init fuel!
@@ -292,9 +325,9 @@ INT32 AddVehicleToList( INT16 sMapX, INT16 sMapY, INT32 sGridNo, UINT8 ubType )
pVehicleList[ iCount ].pMercPath = NULL;
pVehicleList[ iCount ].fFunctional = TRUE;
pVehicleList[ iCount ].fDestroyed = FALSE;
pVehicleList[ iCount ].iMoveSound = iMoveVehicleSndID[ ubType ];
pVehicleList[ iCount ].iOutOfSound = iEnterVehicleSndID[ ubType ];
pVehicleList[ iCount ].ubProfileID = ubVehicleTypeProfileID[ ubType ];
pVehicleList[ iCount ].iMoveSound = gNewVehicle[ ubType ].iNewMoveVehicleSndID;
pVehicleList[ iCount ].iOutOfSound = gNewVehicle[ ubType ].iNewEnterVehicleSndID;
pVehicleList[ iCount ].ubProfileID = ubType; //gNewVehicle[ ubType ].ubNewVehicleTypeProfileID;//gNewVehicle[ ubType ].uiIndex; //gNewVehicle[ ubType ].ubNewVehicleTypeProfileID; //
pVehicleList[ iCount ].ubMovementGroup = gubVehicleMovementGroups[ iCount ];
// ATE: Add movement mask to group...
@@ -319,8 +352,20 @@ INT32 AddVehicleToList( INT16 sMapX, INT16 sMapY, INT32 sGridNo, UINT8 ubType )
pGroup->ubTransportationMask = TRUCK;
}
else
{
pGroup->ubTransportationMask = (UINT8)iMvtTypes[ ubType ];
{
// WANNE: This FIXES the bug (== instead of =), that the heli could only fly on roads!!
if ( gNewVehicle[ ubType ].iNewMvtTypes == 0 )
pGroup->ubTransportationMask = FOOT;
else if ( gNewVehicle[ ubType ].iNewMvtTypes == 1 )
pGroup->ubTransportationMask = CAR;
else if ( gNewVehicle[ ubType ].iNewMvtTypes == 2 )
pGroup->ubTransportationMask = TRUCK;
else if ( gNewVehicle[ ubType ].iNewMvtTypes == 3 )
pGroup->ubTransportationMask = TRACKED;
else if ( gNewVehicle[ ubType ].iNewMvtTypes == 4 )
pGroup->ubTransportationMask = AIR;
else
pGroup->ubTransportationMask = CAR;
}
// ARM: setup group movement defaults
@@ -511,7 +556,7 @@ BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
}
// check if the grunt is already here
for( iCounter = 0; iCounter < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
{
if( pVehicleList[ iId ].pPassengers[ iCounter ] == pSoldier )
{
@@ -531,7 +576,7 @@ BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
PlayJA2Sample( pVehicleList[ pVehicleSoldier->bVehicleID ].iOutOfSound, RATE_11025, SoundVolume( HIGHVOLUME, pVehicleSoldier->sGridNo ), 1, SoundDir( pVehicleSoldier->sGridNo ) );
}
for( iCounter = 0; iCounter < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
{
// check if slot free
if( pVehicleList[ iId ].pPassengers[ iCounter ] == NULL )
@@ -689,7 +734,7 @@ BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
}
// now look for the grunt
for( iCounter = 0; iCounter < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
{
if( pVehicleList[ iId ].pPassengers[ iCounter ] == pSoldier )
{
@@ -707,7 +752,7 @@ BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
// check if anyone left in vehicle
fSoldierLeft = FALSE;
for( iCounter = 0; iCounter < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
{
if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL )
{
@@ -1051,7 +1096,13 @@ BOOLEAN CopyVehiclePathToSoldier( SOLDIERTYPE *pSoldier )
BOOLEAN IsVehicle(SOLDIERTYPE *pSoldier)
{
switch(pSoldier->ubProfile)
if ( gProfilesVehicle[ pSoldier->ubProfile ].ProfilId == pSoldier->ubProfile )
return(TRUE);
else
return(FALSE);
/*switch(pSoldier->ubProfile)
{
case PROF_HUMMER:
case PROF_ELDERODO:
@@ -1061,6 +1112,7 @@ BOOLEAN IsVehicle(SOLDIERTYPE *pSoldier)
return(FALSE);
}
return(FALSE);
*/
}
@@ -1105,7 +1157,7 @@ BOOLEAN SetUpMvtGroupForVehicle( SOLDIERTYPE *pSoldier )
// add everyone in vehicle to this mvt group
//for( iCounter = 0; iCounter < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
//for( iCounter = 0; iCounter < gNewVehicle.iNewSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
//{
// if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL )
// {
@@ -1181,7 +1233,7 @@ void UpdatePositionOfMercsInVehicle( INT32 iId )
}
// go through list of mercs in vehicle and set all thier states as arrived
for( iCounter = 0; iCounter < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
{
if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL )
{
@@ -1235,7 +1287,7 @@ BOOLEAN AddVehicleMembersToMvtGroup( INT32 iId )
// RemoveAllPlayersFromGroup( pVehicleList[ iId ].ubMovementGroup );
// go through list of mercs in vehicle and set all thier states as arrived
for( iCounter = 0; iCounter < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
{
if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL )
{
@@ -1323,7 +1375,7 @@ BOOLEAN KillAllInVehicle( INT32 iId )
}
// go through list of occupants and kill them
for( iCounter = 0; iCounter < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
{
if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL )
{
@@ -1349,7 +1401,7 @@ INT32 GetNumberInVehicle( INT32 iId )
return ( 0 );
}
for( iCounter = 0; iCounter < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
{
if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL )
{
@@ -1372,7 +1424,7 @@ INT32 GetNumberOfNonEPCsInVehicle( INT32 iId )
return ( 0 );
}
for( iCounter = 0; iCounter < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
{
if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL && !AM_AN_EPC( pVehicleList[ iId ].pPassengers[ iCounter ] ) )
{
@@ -1395,7 +1447,7 @@ BOOLEAN IsRobotControllerInVehicle( INT32 iId )
return ( 0 );
}
for( iCounter = 0; iCounter < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
{
pSoldier = pVehicleList[ iId ].pPassengers[ iCounter ];
if ( pSoldier != NULL && pSoldier->ControllingRobot( ) )
@@ -1442,7 +1494,7 @@ void SetDriver( INT32 iID, UINT8 ubID )
#ifdef JA2TESTVERSION
void VehicleTest( void )
{
SetUpHelicopterForPlayer( 9,1, SKYRIDER );
SetUpHelicopterForPlayer( 9,1, gNewVehicle[ HELICOPTER ].NewPilot, HELICOPTER );
}
#endif
@@ -1455,7 +1507,7 @@ BOOLEAN IsEnoughSpaceInVehicle( INT32 iID )
return ( FALSE );
}
if ( GetNumberInVehicle( iID ) == iSeatingCapacities[ pVehicleList[ iID ].ubVehicleType ] )
if ( GetNumberInVehicle( iID ) == gNewVehicle[ pVehicleList[ iID ].ubVehicleType ].iNewSeatingCapacities )
{
return( FALSE );
}
@@ -1629,7 +1681,7 @@ void AddPassangersToTeamPanel( INT32 iId )
{
INT32 cnt;
for( cnt = 0; cnt < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; cnt++ )
for( cnt = 0; cnt < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; cnt++ )
{
if( pVehicleList[ iId ].pPassengers[ cnt ] != NULL )
{
@@ -1679,7 +1731,7 @@ void HandleCriticalHitForVehicleInLocation( UINT8 ubID, INT16 sDmg, INT32 sGridN
#if 0
{
// injure someone inside
iRand = Random( iSeatingCapacities[ pVehicleList[ ubID ].ubVehicleType ] );
iRand = Random( gNewVehicle[ pVehicleList[ ubID ].ubVehicleType ].iNewSeatingCapacities );
if( pVehicleList[ ubID ].pPassengers[ iRand ] )
{
// hurt this person
@@ -1887,7 +1939,7 @@ void SetUpArmorForVehicle( UINT8 ubID )
*/
// for armour type, store the index into the armour table itself
pVehicleList[ ubID ].sArmourType = Item[ sVehicleArmourType[ pVehicleList[ ubID ].ubVehicleType ] ].ubClassIndex;
pVehicleList[ ubID ].sArmourType = Item[ gNewVehicle[ pVehicleList[ ubID ].ubVehicleType ].sNewVehicleArmourType ].ubClassIndex;
return;
}
@@ -2156,6 +2208,11 @@ BOOLEAN LoadVehicleInformationFromSavedGameFile( HWFILE hFile, UINT32 uiSavedGam
pVehicleList[cnt].pMercPath = NULL;
}
}
// WANNE: This should make savegames before the externalized vehicles compatible.
if (pVehicleList[cnt].ubVehicleType != pVehicleList[cnt].ubProfileID)
pVehicleList[cnt].ubVehicleType = pVehicleList[cnt].ubProfileID;
}
}
return( TRUE );
@@ -2186,7 +2243,7 @@ void UpdateAllVehiclePassengersGridNo( SOLDIERTYPE *pSoldier )
iId = pSoldier->bVehicleID;
// Loop through passengers and update each guy's position
for( iCounter = 0; iCounter < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
{
if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL )
{
@@ -2561,7 +2618,7 @@ SOLDIERTYPE* PickRandomPassengerFromVehicle( SOLDIERTYPE *pSoldier )
iId = pSoldier->bVehicleID;
// Loop through passengers and update each guy's position
for( iCounter = 0; iCounter < iSeatingCapacities[ pVehicleList[ iId ].ubVehicleType ]; iCounter++ )
for( iCounter = 0; iCounter < gNewVehicle[ pVehicleList[ iId ].ubVehicleType ].iNewSeatingCapacities; iCounter++ )
{
if( pVehicleList[ iId ].pPassengers[ iCounter ] != NULL )
{
+208 -2
View File
@@ -5,22 +5,228 @@
#include "Soldier Control.h"
#include "Strategic Movement.h"
#include "soldier profile type.h"
#define MAX_VEHICLES 10
extern std::vector<INT8> gubVehicleMovementGroups;
#define MAX_MAIN_VEHICLE_CHARS 500
typedef struct
{
UINT8 uiIndex;
INT32 iNewMvtTypes;
INT32 iNewSeatingCapacities;
INT32 iNewEnterVehicleSndID;
INT32 iNewMoveVehicleSndID;
UINT8 ubNewVehicleTypeProfileID;
INT16 sNewVehicleArmourType;
INT8 NewVehicleBodyType;
BOOLEAN bNewNeutral;
BOOLEAN bNewVehicle;
INT8 NewPilot;
CHAR8 szIconFace[MAX_MAIN_VEHICLE_CHARS];
CHAR16 NewVehicleStrings[128];
CHAR16 NewVehicleName[128];
CHAR16 NewShortVehicleStrings[128];
INT32 NewCarPortraits;
BOOLEAN NewUsed;
} NEW_CAR;
extern NEW_CAR gNewVehicle[NUM_PROFILES];
extern BOOLEAN SaveNewVehiclesToSaveGameFile( HWFILE hFile );
extern BOOLEAN LoadNewVehiclesToSaveGameFile( HWFILE hFile );
// type of vehicles
enum{
/* NEW_VEHICLE1 = 0,
NEW_VEHICLE2,
NEW_VEHICLE3,
NEW_VEHICLE4,
NEW_VEHICLE5,
NEW_VEHICLE6,
NEW_VEHICLE7,
NEW_VEHICLE8,
NEW_VEHICLE9,
NEW_VEHICLE10,
NEW_VEHICLE11,
NEW_VEHICLE12,
NEW_VEHICLE13,
NEW_VEHICLE14,
NEW_VEHICLE15,
NEW_VEHICLE16,
NEW_VEHICLE17,
NEW_VEHICLE18,
NEW_VEHICLE19,
NEW_VEHICLE20,
NEW_VEHICLE21,
NEW_VEHICLE22,
NEW_VEHICLE23,
NEW_VEHICLE24,
NEW_VEHICLE25,
NEW_VEHICLE26,
NEW_VEHICLE27,
NEW_VEHICLE28,
NEW_VEHICLE29,
NEW_VEHICLE30,
NEW_VEHICLE31,
NEW_VEHICLE32,
NEW_VEHICLE33,
NEW_VEHICLE34,
NEW_VEHICLE35,
NEW_VEHICLE36,
NEW_VEHICLE37,
NEW_VEHICLE38,
NEW_VEHICLE39,
NEW_VEHICLE40,
NEW_VEHICLE41,
NEW_VEHICLE42,
NEW_VEHICLE43,
NEW_VEHICLE44,
NEW_VEHICLE45,
NEW_VEHICLE46,
NEW_VEHICLE47,
NEW_VEHICLE48,
NEW_VEHICLE49,
NEW_VEHICLE50,
NEW_VEHICLE51,
NEW_VEHICLE52,
NEW_VEHICLE53,
NEW_VEHICLE54,
NEW_VEHICLE55,
NEW_VEHICLE56,
NEW_VEHICLE57,
NEW_VEHICLE58,
NEW_VEHICLE59,
NEW_VEHICLE60,
NEW_VEHICLE61,
NEW_VEHICLE62,
NEW_VEHICLE63,
NEW_VEHICLE64,
NEW_VEHICLE65,
NEW_VEHICLE66,
NEW_VEHICLE67,
NEW_VEHICLE68,
NEW_VEHICLE69,
NEW_VEHICLE70,
NEW_VEHICLE71,
NEW_VEHICLE72,
NEW_VEHICLE73,
NEW_VEHICLE74,
NEW_VEHICLE75,
NEW_VEHICLE76,
NEW_VEHICLE77,
NEW_VEHICLE78,
NEW_VEHICLE79,
NEW_VEHICLE80,
NEW_VEHICLE81,
NEW_VEHICLE82,
NEW_VEHICLE83,
NEW_VEHICLE84,
NEW_VEHICLE85,
NEW_VEHICLE86,
NEW_VEHICLE87,
NEW_VEHICLE88,
NEW_VEHICLE89,
NEW_VEHICLE90,
NEW_VEHICLE91,
NEW_VEHICLE92,
NEW_VEHICLE93,
NEW_VEHICLE94,
NEW_VEHICLE95,
NEW_VEHICLE96,
NEW_VEHICLE97,
NEW_VEHICLE98,
NEW_VEHICLE99,
NEW_VEHICLE100,
NEW_VEHICLE101,
NEW_VEHICLE102,
NEW_VEHICLE103,
NEW_VEHICLE104,
NEW_VEHICLE105,
NEW_VEHICLE106,
NEW_VEHICLE107,
NEW_VEHICLE108,
NEW_VEHICLE109,
NEW_VEHICLE110,
NEW_VEHICLE111,
NEW_VEHICLE112,
NEW_VEHICLE113,
NEW_VEHICLE114,
NEW_VEHICLE115,
NEW_VEHICLE116,
NEW_VEHICLE117,
NEW_VEHICLE118,
NEW_VEHICLE119,
NEW_VEHICLE120,
NEW_VEHICLE121,
NEW_VEHICLE122,
NEW_VEHICLE123,
NEW_VEHICLE124,
NEW_VEHICLE125,
NEW_VEHICLE126,
NEW_VEHICLE127,
NEW_VEHICLE128,
NEW_VEHICLE129,
NEW_VEHICLE130,
NEW_VEHICLE131,
NEW_VEHICLE132,
NEW_VEHICLE133,
NEW_VEHICLE134,
NEW_VEHICLE135,
NEW_VEHICLE136,
NEW_VEHICLE137,
NEW_VEHICLE138,
NEW_VEHICLE139,
NEW_VEHICLE140,
NEW_VEHICLE141,
NEW_VEHICLE142,
NEW_VEHICLE143,
NEW_VEHICLE144,
NEW_VEHICLE145,
NEW_VEHICLE146,
NEW_VEHICLE147,
NEW_VEHICLE148,
NEW_VEHICLE149,
NEW_VEHICLE150,
NEW_VEHICLE151,
NEW_VEHICLE152,
NEW_VEHICLE153,
NEW_VEHICLE154,
NEW_VEHICLE155,
NEW_VEHICLE156,
NEW_VEHICLE157,
NEW_VEHICLE158,
NEW_VEHICLE159,
*/
NEW_VEHICLE1 = 0,
NEW_VEHICLE2 = NEW_VEHICLE1 + 159,
HUMMER = 160,
ELDORADO_CAR = 161,
ICE_CREAM_TRUCK = 162,
HELICOPTER = 163,
//JEEP_CAR = 164,
TANK_CAR = 164,
NEW_VEHICLE165 = 165,
NEW_VEHICLE166 = 166,
NEW_VEHICLE167 = 167,
NEW_VEHICLE168 = 168,
NEW_VEHICLE169 = 169,
NUMBER_OF_TYPES_OF_VEHICLES = NEW_VEHICLE169 + 84,
/*
ELDORADO_CAR = 0,
HUMMER,
ICE_CREAM_TRUCK,
JEEP_CAR,
TANK_CAR,
HELICOPTER,
NUMBER_OF_TYPES_OF_VEHICLES,
NUMBER_OF_TYPES_OF_VEHICLES,
*/
};
// external armor hit locations
enum{
FRONT_EXTERNAL_HIT_LOCATION,
+25 -21
View File
@@ -1212,7 +1212,7 @@ BOOLEAN CheckForGunJam( SOLDIERTYPE * pSoldier )
// try to unjam gun
if(EnoughPoints(pSoldier, APBPConstants[AP_UNJAM], APBPConstants[BP_UNJAM], FALSE))
{
DeductPoints(pSoldier, APBPConstants[AP_UNJAM], APBPConstants[BP_UNJAM]);
DeductPoints(pSoldier, APBPConstants[AP_UNJAM], APBPConstants[BP_UNJAM] );
INT8 bChanceMod;
if ( Weapon[pSoldier->inv[pSoldier->ubAttackingHand].usItem].EasyUnjam )
@@ -1643,7 +1643,7 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
*/
}
DeductPoints( pSoldier, sAPCost, 0 );
DeductPoints( pSoldier, sAPCost, 0, AFTERSHOT_INTERRUPT );
}
}
@@ -1655,12 +1655,12 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
// only deduct APs when the main gun fires
if ( pSoldier->ubAttackingHand == HANDPOS )
{
DeductPoints( pSoldier, sAPCost, 0 );
DeductPoints( pSoldier, sAPCost, 0, AFTERSHOT_INTERRUPT );
}
}
else
{
DeductPoints( pSoldier, sAPCost, 0 );
DeductPoints( pSoldier, sAPCost, 0, AFTERSHOT_INTERRUPT );
}
//PLAY SOUND
@@ -2177,7 +2177,7 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
*/
}
DeductPoints( pSoldier, sAPCost, 0 );
DeductPoints( pSoldier, sAPCost, 0, AFTERSHOT_INTERRUPT );
}
}
@@ -2189,12 +2189,12 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
// only deduct APs when the main gun fires
if ( pSoldier->ubAttackingHand == HANDPOS )
{
DeductPoints( pSoldier, sAPCost, 0 );
DeductPoints( pSoldier, sAPCost, 0, AFTERSHOT_INTERRUPT );
}
}
else
{
DeductPoints( pSoldier, sAPCost, 0 );
DeductPoints( pSoldier, sAPCost, 0, AFTERSHOT_INTERRUPT );
}
//PLAY SOUND
@@ -2674,7 +2674,7 @@ BOOLEAN UseBlade( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
// Deduct points!
sAPCost = CalcTotalAPsToAttack( pSoldier, sTargetGridNo, FALSE, pSoldier->aiData.bAimTime );
DeductPoints( pSoldier, sAPCost, 0 );
DeductPoints( pSoldier, sAPCost, 0, AFTERACTION_INTERRUPT );
// GET TARGET XY VALUES
ConvertGridNoToCenterCellXY( sTargetGridNo, &sXMapPos, &sYMapPos );
@@ -2873,7 +2873,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
if (!fStealing)
{
sAPCost = CalcTotalAPsToAttack( pSoldier, sTargetGridNo, FALSE, pSoldier->aiData.bAimTime );
DeductPoints( pSoldier, sAPCost, 0 );
DeductPoints( pSoldier, sAPCost, 0, AFTERACTION_INTERRUPT );
}
// Steal from the enemy
else
@@ -2949,7 +2949,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
// SANDRO - unable to steal from militia if they are not allowed to drop equipment
if (SOLDIER_CLASS_MILITIA(pTargetSoldier->ubSoldierClass) && (gGameExternalOptions.ubMilitiaDropEquipment != 2) )
{
DeductPoints( pSoldier, (APBPConstants[AP_STEAL_ITEM] / 5), 0 );
DeductPoints( pSoldier, (APBPConstants[AP_STEAL_ITEM] / 5), 0, AFTERACTION_INTERRUPT );
pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 );
return ( TRUE );
}
@@ -2963,7 +2963,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
{
// first, charge extra Aps, because it's difficlut to pickup from other soldier
if (gGameExternalOptions.fEnhancedCloseCombatSystem)
DeductPoints( pSoldier, (GetBasicAPsToPickupItem( pSoldier ) * 2), 0 );
DeductPoints( pSoldier, (GetBasicAPsToPickupItem( pSoldier ) * 2), 0, AFTERACTION_INTERRUPT );
// The item that the enemy holds in his hand before the stealing
usOldItem = pTargetSoldier->inv[HANDPOS].usItem;
@@ -2975,7 +2975,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
{
// charge Aps
if (gGameExternalOptions.fEnhancedCloseCombatSystem)
DeductPoints( pSoldier, GetBasicAPsToPickupItem( pSoldier ), 0 );
DeductPoints( pSoldier, GetBasicAPsToPickupItem( pSoldier ), 0, AFTERACTION_INTERRUPT );
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[ STR_STOLE_SOMETHING ], pSoldier->name, ShortItemNames[ pTargetSoldier->inv[ubIndexRet].usItem ] );
if (pTargetSoldier->inv[ubIndexRet].MoveThisObjectTo(gTempObject, 1) == 0) {
@@ -3136,28 +3136,28 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
{
if (HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) && ( gGameOptions.fNewTraitSystem ))
{
DeductPoints( pSoldier, max( 1, (INT16)((APBPConstants[AP_STEAL_ITEM] * (100 - gSkillTraitValues.ubMAReducedAPsToSteal * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ))/ 100) + 0.5)), 200);
DeductPoints( pSoldier, max( 1, (INT16)((APBPConstants[AP_STEAL_ITEM] * (100 - gSkillTraitValues.ubMAReducedAPsToSteal * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ))/ 100) + 0.5)), 200, AFTERACTION_INTERRUPT );
}
else
{
DeductPoints( pSoldier, APBPConstants[AP_STEAL_ITEM], 200 );
DeductPoints( pSoldier, APBPConstants[AP_STEAL_ITEM], 200, AFTERACTION_INTERRUPT );
}
}
// Only 1/7 of original AP cost, if the enemy has nothing to steal
else if ((fNoMoreItems == TRUE) || (fNoMoreItemInHand == TRUE))
{
DeductPoints( pSoldier, (APBPConstants[AP_STEAL_ITEM] / 7), 0 );
DeductPoints( pSoldier, (APBPConstants[AP_STEAL_ITEM] / 7), 0, AFTERACTION_INTERRUPT );
}
}
else
{
if (HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) && ( gGameOptions.fNewTraitSystem ))
{
DeductPoints( pSoldier, max( 1, (INT16)((APBPConstants[AP_STEAL_ITEM] * (100 - gSkillTraitValues.ubMAReducedAPsToSteal * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ))/ 100) + 0.5)), 0);
DeductPoints( pSoldier, max( 1, (INT16)((APBPConstants[AP_STEAL_ITEM] * (100 - gSkillTraitValues.ubMAReducedAPsToSteal * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ))/ 100) + 0.5)), 0, AFTERACTION_INTERRUPT );
}
else
{
DeductPoints( pSoldier, APBPConstants[AP_STEAL_ITEM], 0 );
DeductPoints( pSoldier, APBPConstants[AP_STEAL_ITEM], 0, AFTERACTION_INTERRUPT );
}
}
@@ -3424,8 +3424,12 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
}
}
// WDS 07/19/2008 - Random number use fix
#ifdef JA2UB
//Ja25 no meanwhiles
if ( iDiceRoll < iHitChance )
#else
if ( iDiceRoll < iHitChance || AreInMeanwhile( ) )
#endif
{
// CALCULATE DAMAGE!
iImpact = HTHImpact( pSoldier, pTargetSoldier, (iHitChance - iDiceRoll), FALSE );
@@ -3580,7 +3584,7 @@ BOOLEAN UseThrown( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
sAPCost += GetAPsToChangeStance( pSoldier, ANIM_STAND );
HandleSoldierThrowItem( pSoldier, pSoldier->sTargetGridNo );
DeductPoints( pSoldier, sAPCost, 0 );
DeductPoints( pSoldier, sAPCost, 0, AFTERSHOT_INTERRUPT );
pSoldier->inv[ HANDPOS ].RemoveObjectsFromStack(1);
/*
@@ -3710,12 +3714,12 @@ BOOLEAN UseLauncher( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
// ONly deduct points once
if ( pSoldier->bDoBurst == 1 )
{
DeductPoints( pSoldier, sAPCost, 0 );
DeductPoints( pSoldier, sAPCost, 0, AFTERSHOT_INTERRUPT );
}
}
else
{
DeductPoints( pSoldier, sAPCost, 0 );
DeductPoints( pSoldier, sAPCost, 0, AFTERSHOT_INTERRUPT );
}
/////////////////////////////////////////////////////////////////////////////////////
+63
View File
@@ -7,7 +7,14 @@
#include "faces.h"
#include "Interface.h"
#include "XML_SenderNameList.h"
#include "mainmenuscreen.h"
#include "ub_config.h"
#include "Strategic Town Loyalty.h"
#include "qarray.h"
#include "XML_Language.h"
#include "Encyclopedia_Data.h"
#include "Encyclopedia.h"
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
@@ -69,6 +76,10 @@ typedef PARSE_STAGE;
#define LBEPOCKETFILENAME "Pockets.xml"
#define MERCSTARTINGGEARFILENAME "MercStartingGear.xml"
#ifdef JA2UB
#define MERCSTARTINGGEAR25FILENAME "MercStartingGear25.xml" //ja25 ub
#endif
#define TONYINVENTORYFILENAME "NPCInventory\\TonyInventory.xml"
#define DEVININVENTORYFILENAME "NPCInventory\\DevinInventory.xml"
#define FRANZINVENTORYFILENAME "NPCInventory\\FranzInventory.xml"
@@ -89,6 +100,11 @@ typedef PARSE_STAGE;
#define PERKOINVENTORYFILENAME "NPCInventory\\PerkoInventory.xml"
#define FREDOINVENTORYFILENAME "NPCInventory\\FredoInventory.xml"
#ifdef JA2UB
#define BETTYINVENTORYFILENAME "NPCInventory\\BettyInventory.xml"
#define RAULINVENTORYFILENAME "NPCInventory\\RaulInventory.xml"
#endif
#define BOBBYRAYSTRINGSFILENAME "BobbyRayStrings.xml"
#define AMMOCALIBERSTRINGSFILENAME "AmmoCaliberStrings.xml"
@@ -172,9 +188,17 @@ typedef PARSE_STAGE;
//Sender Name List
#define SENDERNAMELISTFILENAME "SenderNameList.xml"
#define ACTIONITEMSFILENAME "MapAction\\Actionitems.xml"
#define IMPPORTRAITS "IMPPortraits.xml"
#ifdef JA2UB
// UB
#define MERCPROFILESFILENAME25 "MercProfiles25.xml"
// UB
#define MERCOPINIONSFILENAME25 "MercOpinions25.xml"
#endif
#define SOUNDPROFILE "SoundsProfiles.xml"
#define RANDOMSTATS "RandomStats.xml"
@@ -183,6 +207,8 @@ typedef PARSE_STAGE;
#define SECTORLEVEL2NAMESFILENAME "Map\\SectorNamesLevel_2.xml"
#define SECTORLEVEL3NAMESFILENAME "Map\\SectorNamesLevel_3.xml"
#define LAYOUTMAINMENU "Layout\\LayoutMainMenu.xml"
#define INTROFILESFILENAME "IntroFiles.xml"
#define MERCAVAILABILITY "MercAvailability.xml"
#define AIMAVAILABILITY "AimAvailability.xml"
@@ -191,6 +217,25 @@ typedef PARSE_STAGE;
#define FACEGEARFILENAME "FaceGear.xml"
//Sender Name List
#define EMAILSENDERNAMELIST "Email\\EmailSenderNameList.xml"
#define EMAILMERCAVAILABLE "Email\\EmailMercAvailable.xml"
#define EMAILMERCLEVELUP "Email\\EmailMercLevelUp.xml"
#define EMAILOTHER "Email\\EmailOther.xml"
#define EMAILINSURANCE "Email\\EmailInsurance.xml"
#define VEHICLESFILENAME "Vehicles.xml"
#define TEXTFILENAME "Text\\TacticalMessages.xml"
#define ENCYCLOPEDIALOCATIONFILENAME "Encyclopedia\\EncyclopediaLocations.xml"
#define ENCYCLOPEDIAPROFILEFILENAME "Encyclopedia\\EncyclopediaProfiles.xml"
#define ENCYCLOPEDIAINVENTORYFILENAME "Encyclopedia\\EncyclopediaInventory.xml"
#define ENCYCLOPEDIAOTHERFILENAME "Encyclopedia\\EncyclopediaOthers.xml"
#define ENCYCLOPEDIAQUESTSFILENAME "Encyclopedia\\EncyclopediaQuests.xml"
#define BRIEFINGROOMFILENAME "BriefingRoom\\BriefingRoom.xml"
extern BOOLEAN ReadInItemStats(STR fileName, BOOLEAN localizedVersion);
extern BOOLEAN WriteItemStats();
@@ -393,5 +438,23 @@ extern BOOLEAN ReadInQarray(QARRAY_VALUES *pQarray, STR fileName);
extern BOOLEAN WriteFaceGear();
extern BOOLEAN ReadInFaceGear( FACE_GEAR_VALUES *pFaceGear, STR fileName );
extern BOOLEAN ReadInIntroNames(STR fileName, BOOLEAN localizedVersion);
extern BOOLEAN ReadInMainMenu(MAIN_MENU_VALUES *pMainMenu, STR fileName);
extern BOOLEAN ReadInActionItems(STR fileName, BOOLEAN localizedVersion);
extern BOOLEAN WriteInActionItems( STR fileName);
extern BOOLEAN ReadInEmailMercAvailable(STR fileName, BOOLEAN localizedVersion);
extern BOOLEAN ReadInEmailMercLevelUp(STR fileName, BOOLEAN localizedVersion);
extern BOOLEAN ReadInEmailOther(STR fileName, BOOLEAN localizedVersion);
//extern BOOLEAN ReadInInsurance(STR fileName, BOOLEAN localizedVersion);
extern BOOLEAN ReadInEncyclopediaLocation(STR fileName, BOOLEAN localizedVersion, ENCYCLOPEDIA_LOCATION *Ency, UINT32 FileType2 );
extern BOOLEAN ReadInNewVehicles(STR fileName, BOOLEAN localizedVersion);
extern BOOLEAN WriteNewVehicles(STR fileName);
extern void InitNewVehicles ();
extern BOOLEAN ReadInLanguageLocation(STR fileName, BOOLEAN localizedVersion, LANGUAGE_LOCATION *Lang, UINT32 FileType2 );
#endif
+306
View File
@@ -0,0 +1,306 @@
#ifdef PRECOMPILEDHEADERS
#include "Tactical All.h"
#else
#include "sgp.h"
#include "Debug Control.h"
#include "expat.h"
#include "XML.h"
#include "Interface.h"
#include "Vehicles.h"
#endif
struct
{
PARSE_STAGE curElement;
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
NEW_CAR curNewCar;
NEW_CAR * curArray;
UINT32 maxArraySize;
UINT32 curIndex;
UINT32 currentDepth;
UINT32 maxReadDepth;
}
typedef newCarParseData;
BOOLEAN NewCar_TextOnly;
void InitNewVehicles ();
static void XMLCALL
newCarStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
{
newCarParseData * pData = (newCarParseData *)userData;
if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
{
if(strcmp(name, "VEHICLES") == 0 && pData->curElement == ELEMENT_NONE)
{
pData->curElement = ELEMENT_LIST;
pData->maxReadDepth++;
}
else if(strcmp(name, "VEHICLE") == 0 && pData->curElement == ELEMENT_LIST)
{
pData->curElement = ELEMENT;
pData->maxReadDepth++;
}
else if(pData->curElement == ELEMENT &&
( strcmp(name, "uiIndex") == 0 ||
strcmp(name, "MvtTypes") == 0 ||
strcmp(name, "SeatingCapacities") == 0 ||
strcmp(name, "EnterVehicleSndID") == 0 ||
strcmp(name, "MoveVehicleSndID") == 0 ||
strcmp(name, "VehicleTypeProfileID") == 0 ||
strcmp(name, "VehicleArmourType") == 0 ||
strcmp(name, "VehicleBodyType") == 0 ||
strcmp(name, "VehicleEnabled") == 0 ||
strcmp(name, "Pilot") == 0 ||
strcmp(name, "StiFaceIcon") == 0 ||
strcmp(name, "Name") == 0 ||
strcmp(name, "LongName") == 0 ||
strcmp(name, "ShortName") == 0 ||
strcmp(name, "Neutral") == 0 ))
{
pData->curElement = ELEMENT_PROPERTY;
pData->maxReadDepth++;
}
pData->szCharData[0] = '\0';
}
pData->currentDepth++;
}
static void XMLCALL
newCarCharacterDataHandle(void *userData, const XML_Char *str, int len)
{
newCarParseData * pData = (newCarParseData *)userData;
if( (pData->currentDepth <= pData->maxReadDepth) && (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH))
{
strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
}
}
static void XMLCALL
newCarEndElementHandle(void *userData, const XML_Char *name)
{
char temp;
newCarParseData * pData = (newCarParseData *)userData;
if(pData->currentDepth <= pData->maxReadDepth)
{
if(strcmp(name, "VEHICLES") == 0)
{
pData->curElement = ELEMENT_NONE;
}
else if(strcmp(name, "VEHICLE") == 0)
{
pData->curElement = ELEMENT_LIST;
if (!NewCar_TextOnly)
{
gNewVehicle[pData->curNewCar.uiIndex].uiIndex = pData->curNewCar.uiIndex;
gNewVehicle[pData->curNewCar.uiIndex].iNewMvtTypes = pData->curNewCar.iNewMvtTypes;
gNewVehicle[pData->curNewCar.uiIndex].iNewSeatingCapacities = pData->curNewCar.iNewSeatingCapacities;
gNewVehicle[pData->curNewCar.uiIndex].iNewEnterVehicleSndID = pData->curNewCar.iNewEnterVehicleSndID;
gNewVehicle[pData->curNewCar.uiIndex].iNewMoveVehicleSndID = pData->curNewCar.iNewMoveVehicleSndID;
gNewVehicle[pData->curNewCar.uiIndex].ubNewVehicleTypeProfileID = pData->curNewCar.ubNewVehicleTypeProfileID;
gNewVehicle[pData->curNewCar.uiIndex].sNewVehicleArmourType = pData->curNewCar.sNewVehicleArmourType;
gNewVehicle[pData->curNewCar.uiIndex].NewVehicleBodyType = pData->curNewCar.NewVehicleBodyType;
gNewVehicle[pData->curNewCar.uiIndex].bNewVehicle = pData->curNewCar.bNewVehicle;
gNewVehicle[pData->curNewCar.uiIndex].bNewNeutral = pData->curNewCar.bNewNeutral;
gNewVehicle[pData->curNewCar.uiIndex].NewPilot = pData->curNewCar.NewPilot;
strcpy(gNewVehicle[pData->curNewCar.uiIndex].szIconFace, pData->curNewCar.szIconFace);
gNewVehicle[ pData->curNewCar.uiIndex ].NewCarPortraits = -1;
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewVehicleStrings, pData->curNewCar.NewVehicleStrings);
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewVehicleName, pData->curNewCar.NewVehicleName);
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewShortVehicleStrings, pData->curNewCar.NewShortVehicleStrings);
gNewVehicle[ pData->curNewCar.uiIndex ].NewUsed = FALSE;
}
else
{
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewVehicleStrings, pData->curNewCar.NewVehicleStrings);
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewVehicleName, pData->curNewCar.NewVehicleName);
wcscpy(gNewVehicle[pData->curNewCar.uiIndex].NewShortVehicleStrings, pData->curNewCar.NewShortVehicleStrings);
}
}
else if(strcmp(name, "uiIndex") == 0)
{
pData->curElement = ELEMENT;
pData->curNewCar.uiIndex = (UINT8) atol(pData->szCharData);
}
else if(strcmp(name, "MvtTypes") == 0)
{
pData->curElement = ELEMENT;
pData->curNewCar.iNewMvtTypes = (INT32) atol(pData->szCharData);
}
else if(strcmp(name, "SeatingCapacities") == 0)
{
pData->curElement = ELEMENT;
pData->curNewCar.iNewSeatingCapacities = (INT32) atol(pData->szCharData);
}
else if(strcmp(name, "EnterVehicleSndID") == 0)
{
pData->curElement = ELEMENT;
pData->curNewCar.iNewEnterVehicleSndID = (INT32) atol(pData->szCharData);
}
else if(strcmp(name, "MoveVehicleSndID") == 0)
{
pData->curElement = ELEMENT;
pData->curNewCar.iNewMoveVehicleSndID = (INT32) atol(pData->szCharData);
}
else if(strcmp(name, "VehicleArmourType") == 0)
{
pData->curElement = ELEMENT;
pData->curNewCar.sNewVehicleArmourType = (INT16) atol(pData->szCharData);
}
else if(strcmp(name, "VehicleEnabled") == 0)
{
pData->curElement = ELEMENT;
pData->curNewCar.bNewVehicle = (BOOLEAN) atol(pData->szCharData);
}
else if(strcmp(name, "Neutral") == 0)
{
pData->curElement = ELEMENT;
pData->curNewCar.bNewNeutral = (BOOLEAN) atol(pData->szCharData);
}
else if(strcmp(name, "Pilot") == 0)
{
pData->curElement = ELEMENT;
pData->curNewCar.NewPilot = (INT8) atol(pData->szCharData);
}
else if(strcmp(name, "Name") == 0 )
{
pData->curElement = ELEMENT;
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curNewCar.NewVehicleName, sizeof(pData->curNewCar.NewVehicleName)/sizeof(pData->curNewCar.NewVehicleName[0]) );
pData->curNewCar.NewVehicleName[sizeof(pData->curNewCar.NewVehicleName)/sizeof(pData->curNewCar.NewVehicleName[0]) - 1] = '\0';
}
else if(strcmp(name, "LongName") == 0 )
{
pData->curElement = ELEMENT;
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curNewCar.NewVehicleStrings, sizeof(pData->curNewCar.NewVehicleStrings)/sizeof(pData->curNewCar.NewVehicleStrings[0]) );
pData->curNewCar.NewVehicleStrings[sizeof(pData->curNewCar.NewVehicleStrings)/sizeof(pData->curNewCar.NewVehicleStrings[0]) - 1] = '\0';
}
else if(strcmp(name, "ShortName") == 0 )
{
pData->curElement = ELEMENT;
MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curNewCar.NewShortVehicleStrings, sizeof(pData->curNewCar.NewShortVehicleStrings)/sizeof(pData->curNewCar.NewShortVehicleStrings[0]) );
pData->curNewCar.NewShortVehicleStrings[sizeof(pData->curNewCar.NewShortVehicleStrings)/sizeof(pData->curNewCar.NewShortVehicleStrings[0]) - 1] = '\0';
}
else if(strcmp(name, "StiFaceIcon") == 0)
{
pData->curElement = ELEMENT;
if(MAX_MAIN_VEHICLE_CHARS >= strlen(pData->szCharData))
strcpy(pData->curNewCar.szIconFace,pData->szCharData);
else
{
strncpy(pData->curNewCar.szIconFace,pData->szCharData,MAX_MAIN_VEHICLE_CHARS);
pData->curNewCar.szIconFace[MAX_MAIN_VEHICLE_CHARS] = '\0';
}
for(int i=0;i<min((int)strlen(pData->szCharData),MAX_MAIN_VEHICLE_CHARS);i++)
{
temp = pData->szCharData[i];
pData->curNewCar.szIconFace[i] = temp;
}
}
pData->maxReadDepth--;
}
pData->currentDepth--;
}
BOOLEAN ReadInNewVehicles(STR fileName, BOOLEAN localizedVersion)
{
HWFILE hFile;
UINT32 uiBytesRead;
UINT32 uiFSize;
CHAR8 * lpcBuffer;
XML_Parser parser = XML_ParserCreate(NULL);
newCarParseData pData;
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading Vehicles.xml" );
NewCar_TextOnly = localizedVersion;
// Open file
hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
if ( !hFile )
return( localizedVersion );
uiFSize = FileGetSize(hFile);
lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
//Read in block
if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
{
MemFree(lpcBuffer);
return( FALSE );
}
lpcBuffer[uiFSize] = 0; //add a null terminator
FileClose( hFile );
XML_SetElementHandler(parser, newCarStartElementHandle, newCarEndElementHandle);
XML_SetCharacterDataHandler(parser, newCarCharacterDataHandle);
memset(&pData,0,sizeof(pData));
XML_SetUserData(parser, &pData);
if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
{
CHAR8 errorBuf[511];
sprintf(errorBuf, "XML Parser Error in Vehicles.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
LiveMessage(errorBuf);
MemFree(lpcBuffer);
return FALSE;
}
MemFree(lpcBuffer);
XML_ParserFree(parser);
return( TRUE );
}
void InitNewVehicles ()
{
UINT32 iCount;
for( iCount=0; iCount<NUM_PROFILES; iCount++ )
{
gNewVehicle[ iCount ].uiIndex = iCount;
gNewVehicle[ iCount ].iNewMvtTypes = 1;
gNewVehicle[ iCount ].iNewSeatingCapacities = 6;
gNewVehicle[ iCount ].iNewEnterVehicleSndID = 85;
gNewVehicle[ iCount ].iNewMoveVehicleSndID = 82;
gNewVehicle[ iCount ].ubNewVehicleTypeProfileID = -1;
gNewVehicle[ iCount ].sNewVehicleArmourType = 164;
gNewVehicle[ iCount ].NewVehicleBodyType = 0;
gNewVehicle[ iCount ].bNewNeutral = TRUE;
gNewVehicle[ iCount ].bNewVehicle = FALSE;
gNewVehicle[ iCount ].NewPilot = -1;
gNewVehicle[ iCount ].NewCarPortraits = -1;
gNewVehicle[ iCount ].szIconFace[MAX_MAIN_VEHICLE_CHARS] = '\0';
gNewVehicle[ iCount ].NewVehicleStrings[128] = '\0';
gNewVehicle[ iCount ].NewVehicleName[128] = '\0';
gNewVehicle[ iCount ].NewShortVehicleStrings[128] = '\0';
gNewVehicle[ iCount ].NewUsed = FALSE;
}
}
+26 -1
View File
@@ -350,6 +350,21 @@ enum
NPC_ACTION_TRIGGER_MADLAB_31,
NPC_ACTION_TRIGGER_MADLAB_32,
NPC_ACTION_TRIGGER_BREWSTER_BY_WARDEN_PROXIMITY, // 298
#ifdef JA2UB
//JA25
NPC_ACTION_TRIGGER_JERRY_CONVERSATION_WITH_PGC_1 = 301,
NPC_ACTION_TRIGGER_JERRY_CONVERSATION_WITH_PGC_2,
NPC_ACTION_LEAVING_NPC_TALK_MENU = 304,
NPC_ACTION_BIGGENS_DETONATES_BOMBS = 305,
NPC_ACTION_RAUL_BLOWS_HIMSELF_UP=306,
NPC_ACTION_TEX_FLUSHES_TOILET=307,
NPC_ACTION_MARK_TEX_AS_ALREADY_INTRODUCED_HIMSELF=308,
NPC_ACTION_MAKE_TEX_CAMOED=309,
NPC_ACTION_HAVE_DEALER_OPEN_BUY_SELL_SCREEN=310,
#endif
// WDS - New AI
NPC_ACTION_SEND_WEIGHTED_ASSAULT_TO_LOCATION, // 1st optional parm is "direness: rating
NPC_ACTION_SEND_SPECIFIC_ASSAULT_TO_LOCATION, // 1st option parm is # of soldiers to send, 2nd is composition
@@ -370,7 +385,17 @@ extern UINT32 CalcPatientMedicalCost( SOLDIERTYPE * pSoldier );
extern UINT32 CalcMedicalCost( UINT8 ubId );
extern BOOLEAN gfInTalkPanel;
#ifdef JA2UB
//JA25 ub
void DelayedSayingOfMercQuote( UINT32 uiParam );
void DelayedMercQuote( UINT16 usProfileID, UINT32 uiQuoteNum, UINT32 uiTimeTillQuoteSaid );
void CheckForValidQuotesWhenLeavingDealer( UINT8 ubProfile );
void HaveBiggensDetonatingExplosivesByTheMine();
// This function checks if we should replace the mine entrance graphic
BOOLEAN IsMineEntranceInSectorI13AtThisGridNo( UINT32 sGridNo );
#endif
void ReplaceMineEntranceGraphicWithCollapsedEntrance();
#endif
#endif
+48 -3
View File
@@ -52,6 +52,10 @@
#include "Explosion Control.h"//dnl ch40 200909
#endif
#ifdef JA2UB
#include "Ja25_Tactical.h"
#endif
//rain
//#define VIS_DIST_DECREASE_PER_RAIN_INTENSITY 20
//end rain
@@ -102,6 +106,11 @@ BOOLEAN gfPlayerTeamSawCreatures = FALSE;
BOOLEAN gfPlayerTeamSawJoey = FALSE;
BOOLEAN gfMikeShouldSayHi = FALSE;
#ifdef JA2UB
//JA25 UB
BOOLEAN gfMorrisShouldSayHi = FALSE;
#endif
UINT8 gubBestToMakeSighting[BEST_SIGHTING_ARRAY_SIZE];
UINT8 gubBestToMakeSightingSize = 0;
//BOOLEAN gfHumanSawSomeoneInRealtime;
@@ -858,7 +867,8 @@ void HandleSight(SOLDIERTYPE *pSoldier, UINT8 ubSightFlags)
// if we've been told that interrupts are possible as a result of sighting
if ((gTacticalStatus.uiFlags & TURNBASED) &&
(gTacticalStatus.uiFlags & INCOMBAT) &&
(ubSightFlags & SIGHT_INTERRUPT))
(ubSightFlags & SIGHT_INTERRUPT) &&
(!gGameExternalOptions.fImprovedInterruptSystem || gGameExternalOptions.fAllowInstantInterruptsOnSight ) )
{
ResolveInterruptsVs( pSoldier, SIGHTINTERRUPT );
}
@@ -2194,6 +2204,9 @@ void ManSeesMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT32 sOppGridNo,
switch( pSoldier->ubProfile )
{
case CARMEN:
#ifdef JA2UB
// no UB
#else
if (pOpponent->ubProfile == SLAY ) // 64
{
// Carmen goes to war (against Slay)
@@ -2209,7 +2222,11 @@ void ManSeesMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT32 sOppGridNo,
EnterCombatMode( pSoldier->bTeam );
}
*/
}
#endif
break;
case ELDIN:
if ( pSoldier->aiData.bNeutral )
@@ -2264,6 +2281,10 @@ void ManSeesMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT32 sOppGridNo,
}
break;
//case QUEEN:
#ifdef JA2UB
//Ja25
//No Queen,Joe, or elliot
#else
case JOE:
case ELLIOT:
if ( ! ( gMercProfiles[ pSoldier->ubProfile ].ubMiscFlags2 & PROFILE_MISC_FLAG2_SAID_FIRSTSEEN_QUOTE ) )
@@ -2275,6 +2296,7 @@ void ManSeesMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT32 sOppGridNo,
}
}
break;
#endif
default:
break;
}
@@ -2370,6 +2392,15 @@ void ManSeesMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT32 sOppGridNo,
}
else if ( pSoldier->bTeam == gbPlayerNum )
{
#ifdef JA2UB
if( (pOpponent->ubProfile == 75 ) &&
( GetNumSoldierIdAndProfileIdOfTheNewMercsOnPlayerTeam( NULL, NULL ) != 0 ) &&
!( pSoldier->usQuoteSaidExtFlags & SOLDIER_QUOTE_SAID_EXT_MORRIS ) &&
!( gMercProfiles[ 75 ].ubMiscFlags2 & PROFILE_MISC_FLAG2_SAID_FIRSTSEEN_QUOTE ) )
{
gfMorrisShouldSayHi = TRUE;
}
#else
if ( (pOpponent->ubProfile == MIKE) && ( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC ) && !(pSoldier->usQuoteSaidExtFlags & SOLDIER_QUOTE_SAID_EXT_MIKE) )
{
if (gfMikeShouldSayHi == FALSE)
@@ -2379,6 +2410,7 @@ void ManSeesMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT32 sOppGridNo,
TacticalCharacterDialogue( pSoldier, QUOTE_AIM_SEEN_MIKE );
pSoldier->usQuoteSaidExtFlags |= SOLDIER_QUOTE_SAID_EXT_MIKE;
}
#endif
else if ( pOpponent->ubProfile == JOEY && gfPlayerTeamSawJoey == FALSE )
{
TacticalCharacterDialogue( pSoldier, QUOTE_SPOTTED_JOEY );
@@ -3274,12 +3306,14 @@ void SaySeenQuote( SOLDIERTYPE *pSoldier, BOOLEAN fSeenCreature, BOOLEAN fVirgin
UINT8 ubNumEnemies = 0;
UINT8 ubNumAllies = 0;
UINT32 cnt;
#ifdef JA2UB
//Ja25 No meanwhiles
#else
if ( AreInMeanwhile( ) )
{
return;
}
#endif
// Check out for our under large fire quote
if ( !(pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_IN_SHIT ) )
{
@@ -6513,7 +6547,11 @@ void TellPlayerAboutNoise( SOLDIERTYPE *pSoldier, UINT8 ubNoiseMaker, INT32 sGri
// if the quote was faint, say something
if (ubVolumeIndex == 0)
{
#ifdef JA2UB
//Ja25 No meanwhiles
#else
if ( !AreInMeanwhile( ) && !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV) && pSoldier->ubTurnsUntilCanSayHeardNoise == 0)
#endif
{
TacticalCharacterDialogue( pSoldier, QUOTE_HEARD_SOMETHING );
if ( gTacticalStatus.uiFlags & INCOMBAT )
@@ -7499,3 +7537,10 @@ BOOLEAN SoldierHasLimitedVision(SOLDIERTYPE * pSoldier)
else
return FALSE;
}
#ifdef JA2UB
INT32 MaxDistanceVisible( void )
{
return( STRAIGHT * 2 );
}
#endif
+22
View File
@@ -29,6 +29,20 @@
#define SIGHTINTERRUPT 1
#define NOISEINTERRUPT 2
// SANDRO - enum for improved interrupt system
enum
{
DISABLED_INTERRUPT = 0,
UNTRIGGERED_INTERRUPT,
UNDEFINED_INTERRUPT,
MOVEMENT_INTERRUPT,
SP_MOVEMENT_INTERRUPT,
BEFORESHOT_INTERRUPT,
AFTERSHOT_INTERRUPT,
AFTERACTION_INTERRUPT,
INSTANT_INTERRUPT,
MAX_INTERRUPT_TYPES
};
// noise type constants
enum
@@ -74,6 +88,9 @@ extern INT8 gfKnowAboutOpponents;
extern BOOLEAN gfPlayerTeamSawJoey;
extern BOOLEAN gfMikeShouldSayHi;
#ifdef JA2UB
extern BOOLEAN gfMorrisShouldSayHi; // JA25 UB
#endif
extern INT32 gsWatchedLoc[ TOTAL_SOLDIERS ][ NUM_WATCHED_LOCS ];
extern INT8 gbWatchedLocLevel[ TOTAL_SOLDIERS ][ NUM_WATCHED_LOCS ];
@@ -152,6 +169,11 @@ extern INT8 gbLightSighting[1][16];
BOOLEAN SoldierHasLimitedVision(SOLDIERTYPE * pSoldier);
#ifdef JA2UB
INT32 MaxDistanceVisible( void );
#endif
// HEADROCK HAM 3.6: Moved here from cpp
void MakeBloodcatsHostile( void );
#endif
+213
View File
@@ -8,7 +8,13 @@
#define NUM_PROFILES_v111 170
//tais: maximum amount of starting gear kits
#define NUM_MERCSTARTINGGEAR_KITS 5
#ifdef JA2UB
#define FIRST_RPC 60 //JA25 was 59
#else
#define FIRST_RPC 57
#endif
#define FIRST_NPC 75
#define NAME_LENGTH 30
@@ -1026,4 +1032,211 @@ public:
#define SUSPICIOUS_DEATH 1
#define VERY_SUSPICIOUS_DEATH 2
#ifdef WFconvertUB
typedef struct
{
UINT16 zName[ NAME_LENGTH ];
UINT16 zNickname[ NICKNAME_LENGTH ];
UINT32 uiAttnSound;
UINT32 uiCurseSound;
UINT32 uiDieSound;
UINT32 uiGoodSound;
UINT32 uiGruntSound;
UINT32 uiGrunt2Sound;
UINT32 uiOkSound;
UINT8 ubFaceIndex;
PaletteRepID PANTS;
PaletteRepID VEST;
PaletteRepID SKIN;
PaletteRepID HAIR;
INT8 bSex;
INT8 bArmourAttractiveness;
UINT8 ubMiscFlags2;
INT8 bEvolution;
UINT8 ubMiscFlags;
UINT8 bSexist;
INT8 bLearnToHate;
// skills
INT8 bStealRate;
INT8 bVocalVolume;
UINT8 ubQuoteRecord;
INT8 bDeathRate;
INT8 bScientific;
INT16 sExpLevelGain;
INT16 sLifeGain;
INT16 sAgilityGain;
INT16 sDexterityGain;
INT16 sWisdomGain;
INT16 sMarksmanshipGain;
INT16 sMedicalGain;
INT16 sMechanicGain;
INT16 sExplosivesGain;
UINT8 ubBodyType;
INT8 bMedical;
UINT16 usEyesX;
UINT16 usEyesY;
UINT16 usMouthX;
UINT16 usMouthY;
UINT32 uiEyeDelay;
UINT32 uiMouthDelay;
UINT32 uiBlinkFrequency;
UINT32 uiExpressionFrequency;
UINT16 sSectorX;
UINT16 sSectorY;
UINT32 uiDayBecomesAvailable; //day the merc will be available. used with the bMercStatus
INT8 bStrength;
INT8 bLifeMax;
INT8 bExpLevelDelta;
INT8 bLifeDelta;
INT8 bAgilityDelta;
INT8 bDexterityDelta;
INT8 bWisdomDelta;
INT8 bMarksmanshipDelta;
INT8 bMedicalDelta;
INT8 bMechanicDelta;
INT8 bExplosivesDelta;
INT8 bStrengthDelta;
INT8 bLeadershipDelta;
UINT16 usKills;
UINT16 usAssists;
UINT16 usShotsFired;
UINT16 usShotsHit;
UINT16 usBattlesFought;
UINT16 usTimesWounded;
UINT16 usTotalDaysServed;
INT16 sLeadershipGain;
INT16 sStrengthGain;
// BODY TYPE SUBSITUTIONS
UINT32 uiBodyTypeSubFlags;
INT16 sSalary;
INT8 bLife;
INT8 bDexterity; // dexterity (hand coord) value
INT8 bPersonalityTrait;
INT8 bSkillTrait;
INT8 bReputationTolerance;
INT8 bExplosive;
INT8 bSkillTrait2;
INT8 bLeadership;
INT8 bBuddy[5];
INT8 bHated[5];
INT8 bExpLevel; // general experience level
INT8 bMarksmanship;
UINT8 bMinService;
INT8 bWisdom;
UINT8 bResigned;
UINT8 bActive;
UINT8 bInvStatus[19];
UINT8 bInvNumber[19];
UINT16 usApproachFactor[4];
INT8 bMainGunAttractiveness;
INT8 bAgility; // agility (speed) value
BOOLEAN fUseProfileInsertionInfo; // Set to various flags, ( contained in TacticalSave.h )
INT16 sGridNo; // The Gridno the NPC was in before leaving the sector
UINT8 ubQuoteActionID;
INT8 bMechanical;
UINT8 ubInvUndroppable;
UINT8 ubRoomRangeStart[2];
UINT16 inv[19];
INT8 bMercTownReputation[ 20 ];
UINT16 usStatChangeChances[ 12 ]; // used strictly for balancing, never shown!
UINT16 usStatChangeSuccesses[ 12 ]; // used strictly for balancing, never shown!
UINT8 ubStrategicInsertionCode;
UINT8 ubRoomRangeEnd[2];
INT8 bPadding[ 4 ];
UINT8 ubLastQuoteSaid;
INT8 bRace;
INT8 bNationality;
INT8 bAppearance;
INT8 bAppearanceCareLevel;
INT8 bRefinement;
INT8 bRefinementCareLevel;
INT8 bHatedNationality;
INT8 bHatedNationalityCareLevel;
INT8 bRacist;
UINT32 uiWeeklySalary;
UINT32 uiBiWeeklySalary;
INT8 bMedicalDeposit;
INT8 bAttitude;
INT8 bBaseMorale;
UINT16 sMedicalDepositAmount;
INT8 bLearnToLike;
UINT8 ubApproachVal[4];
UINT8 ubApproachMod[3][4];
INT8 bTown;
INT8 bTownAttachment;
UINT16 usOptionalGearCost;
INT8 bMercOpinion[75];
INT8 bApproached;
INT8 bMercStatus; //The status of the merc. If negative, see flags at the top of this file. Positive: The number of days the merc is away for. 0: Not hired but ready to be.
INT8 bHatedTime[5];
INT8 bLearnToLikeTime;
INT8 bLearnToHateTime;
INT8 bHatedCount[5];
INT8 bLearnToLikeCount;
INT8 bLearnToHateCount;
UINT8 ubLastDateSpokenTo;
UINT8 bLastQuoteSaidWasSpecial;
INT8 bSectorZ;
UINT16 usStrategicInsertionData;
INT8 bFriendlyOrDirectDefaultResponseUsedRecently;
INT8 bRecruitDefaultResponseUsedRecently;
INT8 bThreatenDefaultResponseUsedRecently;
INT8 bNPCData; // NPC specific
INT32 iBalance;
INT16 sTrueSalary; // for use when the person is working for us for free but has a positive salary value
UINT8 ubCivilianGroup;
UINT8 ubNeedForSleep;
UINT32 uiMoney;
INT8 bNPCData2; // NPC specific
UINT8 ubMiscFlags3;
UINT8 ubDaysOfMoraleHangover; // used only when merc leaves team while having poor morale
UINT8 ubNumTimesDrugUseInLifetime; // The # times a drug has been used in the player's lifetime...
// Flags used for the precedent to repeating oneself in Contract negotiations. Used for quote 80 - ~107. Gets reset every day
UINT32 uiPrecedentQuoteSaid;
UINT32 uiProfileChecksum;
INT16 sPreCombatGridNo;
UINT8 ubTimeTillNextHatedComplaint;
UINT8 ubSuspiciousDeath;
INT32 iMercMercContractLength; //Used for MERC mercs, specifies how many days the merc has gone since last page
UINT32 uiTotalCostToDate; // The total amount of money that has been paid to the merc for their salary
UINT16 usTotalKills; // total kills the player has had ( only used if the player imported the mercs from ja2 )
UINT16 usTotalAssists; // total assists the player has had ( only used if the player imported the mercs from ja2 )
} MERCPROFILESTRUCT_OLD_WF;
#endif
#endif