From 7a27e7105d1b4f3c48fcbc66ff3a06bb7ee9f895 Mon Sep 17 00:00:00 2001 From: Overhaul Date: Sat, 9 Jun 2007 09:01:04 +0000 Subject: [PATCH] New attack busy system Added missing #includes Added LUA scripting and console Changed the way tracers are visualized, so they work more like real tracers instead of a light fountain Fixed signedness of many grid variables used in GetMouseMapPos calls Fixed enemy weapon choosing: Sometimes a mortar is chosen but later rejected, but the grenade class was not reset. Caused assertion failure Added checks so enemies don't try to chuck RPG grenades with their hands Now possible to shoot a someone in the head if he's in water Fixed InitSightArrays to also clear soldier interrupt duel points. This was causing an assertion failure elsewhere in the code because the interrupt list still had soldiers on it sometimes when this function was called. Soldiers are much less willing to forfeit their turn over an attempt to use more APs than they have Removed early setting of muzzle flash. This would allow enemies to get an interrupt before you even fired. Fixed item dropping by AI. If AI tried to drop something while standing it would cause deadlock Change to greatly speed up closing the sector inventory window in an unloaded sector Added conditional compile flag to always give robot weapon ready advantage, even for 360 degree sighting Check builddefines.h for the conditional flags. Of greatest interest might be LUA_CONSOLE. This will cause the game to bring up a command console when run. However this console is severely lacking in many areas. If anybody knows of an open-source terminal/console that could be used instead, it would be appreciated. The existing console does bad things when you try to close it, and since it counts as a separate app, it pauses the game while it has focus. LUA scripting is very limited, basically just proof of concept. There is one global variable, the Soldiers array. An array index gives you the soldier in that slot in the currently loaded sector. The soldier has a few things that can be accessed: name (short name); fullname (long name); grid (current grid #, can be changed); walkto(grid) (function to walk to another grid); runto(grid) (function to run to another grid) git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@924 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Credits.cpp | 19 + Editor/Editor Taskbar Creation.cpp | 1 + Editor/Editor Taskbar Utils.cpp | 6 +- Editor/EditorMercs.cpp | 1 + Editor/LoadScreen.cpp | 1 + Editor/Road Smoothing.cpp | 1 + Editor/Sector Summary.cpp | 1 + Editor/editscreen.cpp | 1 + Editor/selectwin.cpp | 5 +- GameInitOptionsScreen.cpp | 3 + GameSettings.cpp | 14 +- GameSettings.h | 2 +- HelpScreen.cpp | 8 + Init.cpp | 8 +- Intro.cpp | 8 + JA2 All.h | 2 + JA2 Splash.cpp | 6 +- Laptop/AimFacialIndex.cpp | 2 + Laptop/AimMembers.cpp | 4 + Laptop/BobbyR.cpp | 5 +- Laptop/BobbyRGuns.cpp | 1 + Laptop/BobbyRMailOrder.cpp | 3 +- Laptop/BobbyRMailOrder.h | 1 + Laptop/BobbyRShipments.cpp | 10 + Laptop/BrokenLink.cpp | 7 +- Laptop/CharProfile.cpp | 1 + Laptop/IMP Begin Screen.cpp | 1 + Laptop/IMP Compile Character.cpp | 1 + Laptop/IMP Confirm.cpp | 2 + Laptop/IMP HomePage.cpp | 6 + Laptop/IMP MainPage.cpp | 3 + Laptop/IMP Skill Trait.cpp | 16 + Laptop/IMP Skill Trait.h | 2 + Laptop/IMP Voices.cpp | 3 + Laptop/IMPVideoObjects.cpp | 2 + Laptop/Store Inventory.cpp | 2 + Laptop/email.cpp | 2 + Laptop/files.cpp | 1 + Laptop/finances.cpp | 2 + Laptop/florist Order Form.cpp | 2 + Laptop/history.cpp | 2 + Laptop/insurance Contract.cpp | 1 + Laptop/laptop.cpp | 5 + Laptop/mercs Account.cpp | 1 + Laptop/mercs Files.cpp | 5 + Laptop/mercs.cpp | 2 + Laptop/personnel.cpp | 3 + Loading Screen.cpp | 149 +- Loading Screen.h | 2 +- MainMenuScreen.cpp | 1 + MessageBoxScreen.cpp | 1 + MessageBoxScreen.h | 2 + Options Screen.cpp | 2 + Options Screen.h | 1 + SaveLoadGame.cpp | 15 +- SaveLoadGame.h | 1 + SaveLoadScreen.cpp | 3 +- Standard Gaming Platform/Container.cpp | 2 + Standard Gaming Platform/Cursor Control.h | 9 +- Standard Gaming Platform/DEBUG.H | 7 + Standard Gaming Platform/DirectDraw Calls.cpp | 1 + Standard Gaming Platform/DirectDraw Calls.h | 1 + Standard Gaming Platform/ExceptionHandling.h | 1 + Standard Gaming Platform/himage.cpp | 1 + Standard Gaming Platform/impTGA.cpp | 1 + Standard Gaming Platform/impTGA.h | 8 +- Standard Gaming Platform/sgp.cpp | 19 +- Standard Gaming Platform/soundman.cpp | 1 + Standard Gaming Platform/video.cpp | 6 +- Standard Gaming Platform/vobject_blitters.h | 6 +- Strategic/AI Viewer.cpp | 6 + Strategic/Assignments.cpp | 7 + Strategic/Auto Resolve.cpp | 10 + Strategic/Campaign Init.cpp | 3 + Strategic/Creature Spreading.cpp | 4 + Strategic/Game Clock.cpp | 25 +- Strategic/Game Clock.h | 2 +- Strategic/Game Event Hook.cpp | 7 + Strategic/Game Events.cpp | 1 + Strategic/Game Init.cpp | 13 + Strategic/Hourly Update.cpp | 9 + Strategic/Map Screen Helicopter.cpp | 10 + Strategic/Map Screen Interface Border.cpp | 1 + Strategic/Map Screen Interface Bottom.cpp | 14 + .../Map Screen Interface Map Inventory.cpp | 8 + Strategic/Map Screen Interface Map.cpp | 3 + Strategic/Map Screen Interface Map.h | 1 + .../Map Screen Interface TownMine Info.cpp | 2 + Strategic/Map Screen Interface.cpp | 16 + Strategic/Map Screen Interface.h | 2 +- Strategic/Meanwhile.cpp | 15 + Strategic/Merc Contract.cpp | 4 + Strategic/MilitiaSquads.cpp | 5 + Strategic/Player Command.cpp | 8 + Strategic/PreBattle Interface.cpp | 12 + Strategic/Queen Command.cpp | 17 + Strategic/Quest Debug System.cpp | 19 +- Strategic/Quest Debug System.h | 2 +- Strategic/Quests.cpp | 4 + Strategic/Quests.h | 1 + Strategic/Reinforcement.cpp | 3 + Strategic/Scheduling.cpp | 6 + Strategic/Strategic AI.cpp | 17 + Strategic/Strategic All.h | 1 + Strategic/Strategic Event Handler.cpp | 4 + Strategic/Strategic Merc Handler.cpp | 4 + Strategic/Strategic Mines.cpp | 4 + Strategic/Strategic Movement Costs.cpp | 4 + Strategic/Strategic Movement.cpp | 10 + Strategic/Strategic Pathing.cpp | 1 + Strategic/Strategic Status.cpp | 6 + Strategic/Strategic Town Loyalty.cpp | 11 + Strategic/Town Militia.cpp | 7 + Strategic/XML_Army.cpp | 6 + Strategic/XML_Roaming.cpp | 7 + Strategic/mapscreen.cpp | 13 + Strategic/strategic.cpp | 2 + Strategic/strategicmap.cpp | 19 +- Sys Globals.cpp | 1 + Tactical/Air Raid.cpp | 19 +- Tactical/Animation Control.cpp | 701 +-- Tactical/Animation Control.h | 24 +- Tactical/Animation Data.cpp | 3 +- Tactical/Arms Dealer Init.cpp | 2 + Tactical/ArmsDealerInvInit.cpp | 8 + Tactical/ArmsDealerInvInit.h | 1 + Tactical/Auto Bandage.cpp | 4 +- Tactical/Boxing.cpp | 9 + Tactical/Campaign.cpp | 14 + Tactical/Civ Quotes.cpp | 32 + Tactical/Civ Quotes.h | 2 + Tactical/Dialogue Control.cpp | 32 +- Tactical/DisplayCover.cpp | 49 +- Tactical/Drugs And Alcohol.cpp | 3 + Tactical/End Game.cpp | 26 +- Tactical/Enemy Soldier Save.cpp | 6 + Tactical/Faces.cpp | 5 + Tactical/GAP.cpp | 1 + Tactical/Handle Doors.cpp | 11 + Tactical/Handle Items.cpp | 1871 +++--- Tactical/Handle UI.cpp | 21 +- Tactical/Interface Control.cpp | 3 + Tactical/Interface Cursors.cpp | 3 +- Tactical/Interface Dialogue.cpp | 13 + Tactical/Interface Items.cpp | 63 +- Tactical/Interface Panels.cpp | 3 + Tactical/Interface Utils.cpp | 3 + Tactical/Interface.cpp | 5 +- Tactical/Inventory Choosing.cpp | 12 + Tactical/Items.cpp | 19 +- Tactical/Keys.cpp | 15 +- Tactical/LOS.cpp | 1340 +++-- Tactical/Map Information.cpp | 3 + Tactical/Merc Entering.cpp | 9 + Tactical/Merc Hiring.cpp | 7 + Tactical/Militia Control.cpp | 20 + Tactical/Morale.cpp | 5 + Tactical/Overhead.cpp | 3182 +++++----- Tactical/Overhead.h | 4 +- Tactical/Points.cpp | 59 +- Tactical/Points.h | 4 +- Tactical/Rain.cpp | 11 + Tactical/Real Time Input.cpp | 1964 +++--- Tactical/Rotting Corpses.cpp | 16 + Tactical/ShopKeeper Interface.cpp | 11 +- Tactical/Soldier Add.cpp | 3 + Tactical/Soldier Ani.cpp | 5272 ++++++++-------- Tactical/Soldier Control.cpp | 5112 ++++++++-------- Tactical/Soldier Control.h | 5 +- Tactical/Soldier Create.cpp | 3 + Tactical/Soldier Find.cpp | 15 +- Tactical/Soldier Init List.cpp | 19 + Tactical/Soldier Profile.cpp | 7 + Tactical/Soldier Tile.cpp | 4 + Tactical/Soldier macros.h | 1 + Tactical/SoldierTooltips.cpp | 32 +- Tactical/Spread Burst.cpp | 1 + Tactical/Squads.cpp | 4 + Tactical/Strategic Exit GUI.cpp | 11 + Tactical/Tactical Save.cpp | 122 +- Tactical/Tactical Turns.cpp | 3 + Tactical/TeamTurns.cpp | 12 +- Tactical/Turn Based Input.cpp | 5331 +++++++++-------- Tactical/UI Cursors.cpp | 11 +- Tactical/Vehicles.cpp | 9 + Tactical/Weapons.cpp | 147 +- Tactical/World Items.cpp | 3 + Tactical/XML.h | 2 +- Tactical/XML_ComboMergeInfo.cpp | 2 +- Tactical/XML_EnemyItemChoice.cpp | 1 + Tactical/XML_EnemyWeaponChoice.cpp | 1 + Tactical/XML_SectorLoadscreens.cpp | 2 +- Tactical/bullets.cpp | 70 +- Tactical/fov.cpp | 3 + Tactical/opplist.cpp | 35 +- Tactical/opplist.h | 1 + Tactical/qarray.h | 1 + Tactical/soldier profile type.h | 1 + TacticalAI/AIList.cpp | 4 + TacticalAI/AIMain.cpp | 2393 ++++---- TacticalAI/AIUtils.cpp | 20 +- TacticalAI/Attacks.cpp | 1555 ++--- TacticalAI/DecideAction.cpp | 5305 ++++++++-------- TacticalAI/FindLocations.cpp | 5 + TacticalAI/Knowledge.cpp | 6 + TacticalAI/Medical.cpp | 3 + TacticalAI/Movement.cpp | 2 + TacticalAI/NPC.cpp | 18 +- TacticalAI/PanicButtons.cpp | 4 + TacticalAI/Realtime.cpp | 5 + TileEngine/Ambient Control.cpp | 5 + TileEngine/Buildings.cpp | 1 + TileEngine/Exit Grids.cpp | 1 + TileEngine/Explosion Control.cpp | 3367 +++++------ TileEngine/Interactive Tiles.cpp | 7 + TileEngine/Isometric Utils.cpp | 17 +- TileEngine/Isometric Utils.h | 3 +- TileEngine/LightEffects.cpp | 6 + TileEngine/Map Edgepoints.cpp | 2 + TileEngine/Radar Screen.cpp | 5 + TileEngine/Render Dirty.cpp | 4 + TileEngine/SaveLoadMap.cpp | 1 + TileEngine/Shade Table Util.cpp | 2 + TileEngine/Smell.cpp | 3 + TileEngine/SmokeEffects.cpp | 5 + TileEngine/Tactical Placement GUI.cpp | 3 + TileEngine/Tile Animation.cpp | 282 +- TileEngine/Tile Cache.cpp | 2 + TileEngine/Tile Surface.cpp | 2 + TileEngine/WorldDat.cpp | 2 + TileEngine/XML_ExplosionData.cpp | 7 + TileEngine/environment.cpp | 1 + TileEngine/lighting.cpp | 3 + TileEngine/overhead map.cpp | 8 + TileEngine/physics.cpp | 780 +-- TileEngine/physics.h | 2 +- TileEngine/renderworld.cpp | 383 +- TileEngine/structure.cpp | 43 +- TileEngine/tiledef.cpp | 5 +- TileEngine/worlddef.cpp | 7 + TileEngine/worldman.cpp | 1 + Utils/Animated ProgressBar.cpp | 2 + Utils/Cursors.cpp | 2 + Utils/Event Pump.cpp | 1 + Utils/Font Control.cpp | 1 + Utils/INIReader.cpp | 1 + Utils/Multi Language Graphic Utils.cpp | 13 +- Utils/Multilingual Text Code Generator.cpp | 1 + Utils/STIConvert.cpp | 1 + Utils/Sound Control.cpp | 2 + Utils/Text Input.cpp | 1 + Utils/Text Utils.cpp | 1 + Utils/Timer Control.cpp | 1 + Utils/Utils.vcproj | 2403 +++++--- Utils/WordWrap.cpp | 1 + Utils/XML_Items.cpp | 1 + Utils/_RussianText.cpp | 3 + aniviewscreen.cpp | 1 + builddefines.h | 19 +- gameloop.cpp | 8 + gamescreen.cpp | 8 + gamescreen.h | 2 +- jascreens.cpp | 1 + lua/Console.cpp | 126 + lua/Console.h | 9 + lua/Lua Interpreter.h | 19 + lua/lauxlib.h | 174 + lua/lua.cpp | 332 + lua/lua.h | 385 ++ lua/lua.hpp | 9 + lua/luaconf.h | 762 +++ lua/lualib.h | 53 + lua/lwstring.cpp | 269 + lua/lwstring.h | 32 + lua5.1.lib | Bin 0 -> 472096 bytes 275 files changed, 25107 insertions(+), 20463 deletions(-) create mode 100644 lua/Console.cpp create mode 100644 lua/Console.h create mode 100644 lua/Lua Interpreter.h create mode 100644 lua/lauxlib.h create mode 100644 lua/lua.cpp create mode 100644 lua/lua.h create mode 100644 lua/lua.hpp create mode 100644 lua/luaconf.h create mode 100644 lua/lualib.h create mode 100644 lua/lwstring.cpp create mode 100644 lua/lwstring.h create mode 100644 lua5.1.lib diff --git a/Credits.cpp b/Credits.cpp index 0631a0f7..85434083 100644 --- a/Credits.cpp +++ b/Credits.cpp @@ -10,6 +10,25 @@ #include "Credits.h" //#include "Utils All.h" #include "Language Defines.h" + #include "vsurface.h" + #include "mousesystem.h" + #include "Text.h" + #include "wordwrap.h" + #include "Video.h" + #include "render dirty.h" + #include "local.h" + #include "utilities.h" + #include "WCheck.h" + #include "screenids.h" + #include "Font Control.h" + #include "cursors.h" + #include "font.h" + #include "wordwrap.h" + #include "sysutil.h" + #include "Input.h" + #include "english.h" + #include "encrypted file.h" + #include "Random.h" #endif diff --git a/Editor/Editor Taskbar Creation.cpp b/Editor/Editor Taskbar Creation.cpp index 0ca189b8..8c50e720 100644 --- a/Editor/Editor Taskbar Creation.cpp +++ b/Editor/Editor Taskbar Creation.cpp @@ -21,6 +21,7 @@ //tactical #include "Soldier Create.h" #include "overhead types.h" + #include "local.h" #endif //Category tabs of the editor buttons diff --git a/Editor/Editor Taskbar Utils.cpp b/Editor/Editor Taskbar Utils.cpp index 0317c543..8dfdfb8d 100644 --- a/Editor/Editor Taskbar Utils.cpp +++ b/Editor/Editor Taskbar Utils.cpp @@ -867,15 +867,15 @@ void RenderEditorInfo( ) { CHAR16 FPSText[ 50 ]; static INT32 iSpewWarning = 0; - INT16 iMapIndex; + UINT16 uiMapIndex; SetFont( FONT12POINT1 ); SetFontForeground( FONT_BLACK ); SetFontBackground( FONT_BLACK ); //Display the mapindex position - if( GetMouseMapPos( &iMapIndex ) ) - swprintf( FPSText, L" (%d) ", iMapIndex ); + if( GetMouseMapPos( &uiMapIndex ) ) + swprintf( FPSText, L" (%d) ", uiMapIndex ); else swprintf( FPSText, L" " ); mprintfEditor( (UINT16)(iScreenWidthOffset + 50-StringPixLength( FPSText, FONT12POINT1 )/2), 2 * iScreenHeightOffset + 463, FPSText ); diff --git a/Editor/EditorMercs.cpp b/Editor/EditorMercs.cpp index a70513ec..94e57cea 100644 --- a/Editor/EditorMercs.cpp +++ b/Editor/EditorMercs.cpp @@ -63,6 +63,7 @@ #include "popupmenu.h" #include "Scheduling.h" #include "Timer Control.h" + #include "message.h" #endif extern void GetSoldierAboveGuyPositions( SOLDIERTYPE *pSoldier, INT16 *psX, INT16 *psY, BOOLEAN fRadio ); diff --git a/Editor/LoadScreen.cpp b/Editor/LoadScreen.cpp index d3403c05..1a144a11 100644 --- a/Editor/LoadScreen.cpp +++ b/Editor/LoadScreen.cpp @@ -43,6 +43,7 @@ #include "pits.h" #include "Item Statistics.h" #include "Scheduling.h" + #include "MessageBoxScreen.h" #endif //=========================================================================== diff --git a/Editor/Road Smoothing.cpp b/Editor/Road Smoothing.cpp index 6bcfb348..d31e4771 100644 --- a/Editor/Road Smoothing.cpp +++ b/Editor/Road Smoothing.cpp @@ -13,6 +13,7 @@ #include "tiledat.h" #include "worlddef.h" #include "worldman.h" + #include "Editor Undo.h" #endif diff --git a/Editor/Sector Summary.cpp b/Editor/Sector Summary.cpp index ae06c73d..97f4c07d 100644 --- a/Editor/Sector Summary.cpp +++ b/Editor/Sector Summary.cpp @@ -37,6 +37,7 @@ #include "english.h" #include "World Items.h" #include "text.h" + #include "Soldier Create.h" #endif extern BOOLEAN gfOverheadMapDirty; diff --git a/Editor/editscreen.cpp b/Editor/editscreen.cpp index df46184a..6e9780eb 100644 --- a/Editor/editscreen.cpp +++ b/Editor/editscreen.cpp @@ -73,6 +73,7 @@ #include "Inventory Choosing.h" #include "Music Control.h" #include "Soldier Profile.h" + #include "GameSettings.h" #endif diff --git a/Editor/selectwin.cpp b/Editor/selectwin.cpp index 71c2b636..39d4399c 100644 --- a/Editor/selectwin.cpp +++ b/Editor/selectwin.cpp @@ -20,11 +20,12 @@ #include "Editor Taskbar Utils.h" #endif +#include "vobject_blitters.h" extern BOOLEAN gfOverheadMapDirty; -extern void SetClippingRect(SGPRect *clip); -extern void GetClippingRect(SGPRect *clip); +//extern void SetClippingRect(SGPRect *clip); +//extern void GetClippingRect(SGPRect *clip); extern INT32 iEditorToolbar; diff --git a/GameInitOptionsScreen.cpp b/GameInitOptionsScreen.cpp index 7f6f5323..d014c0ed 100644 --- a/GameInitOptionsScreen.cpp +++ b/GameInitOptionsScreen.cpp @@ -19,6 +19,9 @@ #include "Music Control.h" #include "cursors.h" #include "Intro.h" + #include "Text.h" + #include "_Ja25EnglishText.h" + #include "Soldier Profile.h" #endif //////////////////////////////////////////// diff --git a/GameSettings.cpp b/GameSettings.cpp index bb6e4815..4ef7a539 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -20,6 +20,18 @@ #include "Language Defines.h" #include "HelpScreen.h" #include "INIReader.h" + #include "Shade Table Util.h" + #include "soldier profile type.h" + #include "Random.h" + #include "SaveLoadGame.h" + #include "sgp.h" + #include "screenids.h" + #include "Font Control.h" + #include "message.h" + #include "Campaign.h" + #include "meanwhile.h" + #include "strategicmap.h" + #include "Queen Command.h" #endif #include "Text.h" @@ -471,7 +483,7 @@ void LoadGameExternalOptions() gGameExternalOptions.iStartingCashExperienced = iniReader.ReadInteger("JA2 Gameplay Settings", "EXPERIENCED_CASH",35000); gGameExternalOptions.iStartingCashExpert = iniReader.ReadInteger("JA2 Gameplay Settings", "EXPERT_CASH",30000); gGameExternalOptions.iStartingCashInsane = iniReader.ReadInteger("JA2 Gameplay Settings", "INSANE_CASH",15000); - + //Lalien: Game starting time gGameExternalOptions.iGameStartingTime = iniReader.ReadInteger("JA2 Gameplay Settings", "GAME_STARTING_TIME", 3600); gGameExternalOptions.iFirstArrivalDelay = iniReader.ReadInteger("JA2 Gameplay Settings", "FIRST_ARRIVAL_DELAY", 21600); diff --git a/GameSettings.h b/GameSettings.h index 2c760eeb..b6ae1237 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -454,4 +454,4 @@ BOOLEAN SetMeanwhileSceneSeen( UINT8 ubMeanwhile ); BOOLEAN CanGameBeSaved(); -#endif \ No newline at end of file +#endif diff --git a/HelpScreen.cpp b/HelpScreen.cpp index 4bb67d0f..6f60265d 100644 --- a/HelpScreen.cpp +++ b/HelpScreen.cpp @@ -24,6 +24,14 @@ #include "HelpScreen.h" #include "HelpScreenText.h" #include "Line.h" + #include "Game Clock.h" + #include "GameSettings.h" + #include "laptop.h" + #include "Text Input.h" + #include "english.h" + #include "renderworld.h" + #include "Game Init.h" + #include "Overhead.h" #endif extern INT16 gsVIEWPORT_END_Y; diff --git a/Init.cpp b/Init.cpp index 66254bb1..724a5918 100644 --- a/Init.cpp +++ b/Init.cpp @@ -5,6 +5,7 @@ #include "INIReader.h" #else + #include "builddefines.h" #include #include "sgp.h" #include "Gameloop.h" @@ -54,6 +55,11 @@ #include "jascreens.h" #include "XML.h" #include "SaveLoadGame.h" + #include "weapons.h" + #include "Strategic Movement.h" + #include "Vehicles.h" + #include "Multilingual Text Code Generator.h" + #include "editscreen.h" #endif extern BOOLEAN GetCDromDriveLetter( STR8 pString ); @@ -119,7 +125,7 @@ BOOLEAN LoadExternalGameplayData(STR directoryName) return FALSE; // WANNE: Enemy drops - end - + // WANNE: Sector Loadscreens [2007-05-18] strcpy(fileName, directoryName); strcat(fileName, SECTORLOADSCREENSFILENAME); diff --git a/Intro.cpp b/Intro.cpp index ad49ebf7..692c7aad 100644 --- a/Intro.cpp +++ b/Intro.cpp @@ -22,6 +22,14 @@ #include "Line.h" #include "Intro.h" #include "Cinematics.h" + #include "mainmenuscreen.h" + #include "Music Control.h" + #include "LibraryDataBase.h" + #include "english.h" + #include "Game Init.h" + #include "Soldier Profile.h" + #include "soldier profile type.h" + #include "MessageBoxScreen.h" #endif extern STR16 gzIntroScreen[]; diff --git a/JA2 All.h b/JA2 All.h index 9ddda201..768f5b78 100644 --- a/JA2 All.h +++ b/JA2 All.h @@ -3,6 +3,8 @@ #pragma message("GENERATED PCH FOR JA2 PROJECT.") +#include "builddefines.h" + #include #include #include diff --git a/JA2 Splash.cpp b/JA2 Splash.cpp index e6fec800..64afa20d 100644 --- a/JA2 Splash.cpp +++ b/JA2 Splash.cpp @@ -1,7 +1,11 @@ #ifdef PRECOMPILEDHEADERS #include "JA2 All.h" #else - //add includes here! +#include "Types.h" +#include "vsurface.h" +#include "mainmenuscreen.h" +#include "Video.h" +#include "Timer Control.h" #endif UINT32 guiSplashFrameFade = 10; diff --git a/Laptop/AimFacialIndex.cpp b/Laptop/AimFacialIndex.cpp index cf26eb4a..7a35c371 100644 --- a/Laptop/AimFacialIndex.cpp +++ b/Laptop/AimFacialIndex.cpp @@ -11,6 +11,8 @@ #include "Soldier Profile.h" #include "email.h" #include "Text.h" + #include "aimsort.h" + #include "Assignments.h" #endif diff --git a/Laptop/AimMembers.cpp b/Laptop/AimMembers.cpp index 4c1e3536..1a715553 100644 --- a/Laptop/AimMembers.cpp +++ b/Laptop/AimMembers.cpp @@ -40,6 +40,10 @@ #include "Merc Contract.h" #include "Strategic Merc Handler.h" #include "Language Defines.h" + #include "Assignments.h" + #include "Sound Control.h" + #include "Quests.h" + #include "strategicmap.h" #endif #include "Strategic Town Loyalty.h" diff --git a/Laptop/BobbyR.cpp b/Laptop/BobbyR.cpp index 3e023932..2d54453e 100644 --- a/Laptop/BobbyR.cpp +++ b/Laptop/BobbyR.cpp @@ -17,7 +17,10 @@ #include "Random.h" #include "Text.h" #include "Multi Language Graphic Utils.h" - #include "Utility.h" +// #include "Utility.h" + #include "armsdealerinvinit.h" + #include "GameSettings.h" + #include "message.h" #endif diff --git a/Laptop/BobbyRGuns.cpp b/Laptop/BobbyRGuns.cpp index e396a94c..fb13e33c 100644 --- a/Laptop/BobbyRGuns.cpp +++ b/Laptop/BobbyRGuns.cpp @@ -18,6 +18,7 @@ #include "Overhead.h" #include "Text.h" #include "Weapons.h" + #include "GameSettings.h" #endif diff --git a/Laptop/BobbyRMailOrder.cpp b/Laptop/BobbyRMailOrder.cpp index 19808d00..be3f4687 100644 --- a/Laptop/BobbyRMailOrder.cpp +++ b/Laptop/BobbyRMailOrder.cpp @@ -19,9 +19,10 @@ #include "input.h" #include "line.h" #include "Text.h" - #include "Strategic.h" #include "Campaign Types.h" #include "Multi Language Graphic Utils.h" + #include "strategic.h" + #include "strategicmap.h" #endif diff --git a/Laptop/BobbyRMailOrder.h b/Laptop/BobbyRMailOrder.h index 67513d37..6f364f21 100644 --- a/Laptop/BobbyRMailOrder.h +++ b/Laptop/BobbyRMailOrder.h @@ -1,6 +1,7 @@ #ifndef __BOBBYRMAILORDER_H #define __BOBBYRMAILORDER_H +#include "LaptopSave.h" diff --git a/Laptop/BobbyRShipments.cpp b/Laptop/BobbyRShipments.cpp index 34caf908..b9a3d9dd 100644 --- a/Laptop/BobbyRShipments.cpp +++ b/Laptop/BobbyRShipments.cpp @@ -4,6 +4,16 @@ #else #include "laptop.h" #include "BobbyRShipments.h" + #include "bobbyr.h" + #include "utilities.h" + #include "WCheck.h" + #include "Text.h" + #include "BobbyRGuns.h" + #include "cursors.h" + #include "BobbyRMailOrder.h" + #include "wordwrap.h" + #include "strategic.h" + #include "strategicmap.h" #endif diff --git a/Laptop/BrokenLink.cpp b/Laptop/BrokenLink.cpp index 7fab0f20..a3cc1e9f 100644 --- a/Laptop/BrokenLink.cpp +++ b/Laptop/BrokenLink.cpp @@ -2,7 +2,12 @@ #include "Laptop All.h" #include "BrokenLink.h" #else - + #include "Types.h" + #include "font.h" + #include "laptop.h" + #include "Font Control.h" + #include "Text.h" + #include "wordwrap.h" #endif #define BROKEN_LINK__FONT FONT12ARIAL diff --git a/Laptop/CharProfile.cpp b/Laptop/CharProfile.cpp index 173f698a..2a874d17 100644 --- a/Laptop/CharProfile.cpp +++ b/Laptop/CharProfile.cpp @@ -24,6 +24,7 @@ #include "IMPVideoObjects.h" #include "IMP Confirm.h" #include "messageboxscreen.h" + #include "LaptopSave.h" #endif diff --git a/Laptop/IMP Begin Screen.cpp b/Laptop/IMP Begin Screen.cpp index 201e3c3b..56ad0930 100644 --- a/Laptop/IMP Begin Screen.cpp +++ b/Laptop/IMP Begin Screen.cpp @@ -29,6 +29,7 @@ #include "strategic.h" #include "Game Clock.h" #include "text.h" + #include "LaptopSave.h" #endif #define FULL_NAME_CURSOR_Y LAPTOP_SCREEN_WEB_UL_Y + 138 diff --git a/Laptop/IMP Compile Character.cpp b/Laptop/IMP Compile Character.cpp index 7b0f1441..f0de4a5a 100644 --- a/Laptop/IMP Compile Character.cpp +++ b/Laptop/IMP Compile Character.cpp @@ -33,6 +33,7 @@ #include "Soldier Profile.h" #include "Animation Data.h" #include "random.h" + #include "LaptopSave.h" #endif // how many times should a 'die' be rolled for skills of the same type? diff --git a/Laptop/IMP Confirm.cpp b/Laptop/IMP Confirm.cpp index 39fb9bda..8f871ebc 100644 --- a/Laptop/IMP Confirm.cpp +++ b/Laptop/IMP Confirm.cpp @@ -31,6 +31,8 @@ #include "Game Event Hook.h" #include "LaptopSave.h" #include "strategic.h" + #include "weapons.h" + #include "Random.h" #endif #define IMP_FILENAME_SUFFIX ".dat" diff --git a/Laptop/IMP HomePage.cpp b/Laptop/IMP HomePage.cpp index a0a748ea..9b7ab7d3 100644 --- a/Laptop/IMP HomePage.cpp +++ b/Laptop/IMP HomePage.cpp @@ -20,6 +20,12 @@ #include "LaptopSave.h" #include "line.h" #include "english.h" + #include "Merc Hiring.h" + #include "Text.h" + #include "GameSettings.h" + #include "IMP MainPage.h" + #include "IMP Confirm.h" + #include "Game Clock.h" #endif void GetPlayerKeyBoardInputForIMPHomePage( void ); diff --git a/Laptop/IMP MainPage.cpp b/Laptop/IMP MainPage.cpp index 9c6a4d4c..b9f51b08 100644 --- a/Laptop/IMP MainPage.cpp +++ b/Laptop/IMP MainPage.cpp @@ -21,6 +21,9 @@ #include "LaptopSave.h" #include "IMP Compile Character.h" #include "IMP Portraits.h" + #include "soldier profile type.h" + #include "GameSettings.h" + #include "Soldier Profile.h" #endif diff --git a/Laptop/IMP Skill Trait.cpp b/Laptop/IMP Skill Trait.cpp index fae0d6c5..fbe6ec43 100644 --- a/Laptop/IMP Skill Trait.cpp +++ b/Laptop/IMP Skill Trait.cpp @@ -3,6 +3,22 @@ #include "IMP Skill Trait.h" #include "_Ja25Englishtext.h" #else + #include "IMP Skill Trait.h" + #include "Button System.h" + #include "utilities.h" + #include "Debug.h" + #include "Text.h" + #include "Font Control.h" + #include "font.h" + #include "laptop.h" + #include "cursors.h" + #include "IMP MainPage.h" + #include "IMPVideoObjects.h" + #include "_Ja25EnglishText.h" + #include "wordwrap.h" + #include "CharProfile.h" + #include "soldier profile type.h" + #include "IMP Compile Character.h" #endif diff --git a/Laptop/IMP Skill Trait.h b/Laptop/IMP Skill Trait.h index 4c079d29..7321ed03 100644 --- a/Laptop/IMP Skill Trait.h +++ b/Laptop/IMP Skill Trait.h @@ -1,6 +1,8 @@ #ifndef __IMP_SKILL_TRAIT__H_ #define __IMP_SKILL_TRAIT__H_ +#include "Types.h" + void EnterIMPSkillTrait( void ); void RenderIMPSkillTrait( void ); void ExitIMPSkillTrait( void ); diff --git a/Laptop/IMP Voices.cpp b/Laptop/IMP Voices.cpp index 4454d7ff..b40fc3be 100644 --- a/Laptop/IMP Voices.cpp +++ b/Laptop/IMP Voices.cpp @@ -19,6 +19,9 @@ #include "Sound Control.h" #include "IMP Text System.h" #include "text.h" + #include "soldier profile type.h" + #include "GameSettings.h" + #include "LaptopSave.h" #endif INT32 iCurrentVoice = 0; diff --git a/Laptop/IMPVideoObjects.cpp b/Laptop/IMPVideoObjects.cpp index baf08c4f..96186bc8 100644 --- a/Laptop/IMPVideoObjects.cpp +++ b/Laptop/IMPVideoObjects.cpp @@ -11,6 +11,8 @@ #include "cursors.h" #include "IMP HomePage.h" #include "laptop.h" + #include "Multi Language Graphic Utils.h" + #include "IMP Attribute Selection.h" #endif // globals diff --git a/Laptop/Store Inventory.cpp b/Laptop/Store Inventory.cpp index 7368692b..058196d4 100644 --- a/Laptop/Store Inventory.cpp +++ b/Laptop/Store Inventory.cpp @@ -8,6 +8,8 @@ #include "Debug.h" #include "LaptopSave.h" #include "ShopKeeper Interface.h" + #include "armsdealerinvinit.h" + #include "GameSettings.h" #endif diff --git a/Laptop/email.cpp b/Laptop/email.cpp index d6b951e9..29230943 100644 --- a/Laptop/email.cpp +++ b/Laptop/email.cpp @@ -19,6 +19,8 @@ #include "AimMembers.h" #include "Random.h" #include "Text.h" + #include "LaptopSave.h" + #include "finances.h" #endif //static EmailPtr pEmailList; diff --git a/Laptop/files.cpp b/Laptop/files.cpp index e1efb2c1..e1ddd6ed 100644 --- a/Laptop/files.cpp +++ b/Laptop/files.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Laptop All.h" #else + #include "builddefines.h" #include #include "laptop.h" #include "files.h" diff --git a/Laptop/finances.cpp b/Laptop/finances.cpp index 457960a5..f3a55566 100644 --- a/Laptop/finances.cpp +++ b/Laptop/finances.cpp @@ -15,6 +15,8 @@ #include "Text.h" #include "Strategic Mines.h" #include "LaptopSave.h" + #include "Campaign Types.h" + #include "strategicmap.h" #endif // the global defines diff --git a/Laptop/florist Order Form.cpp b/Laptop/florist Order Form.cpp index 1bb7dbcd..00322e9b 100644 --- a/Laptop/florist Order Form.cpp +++ b/Laptop/florist Order Form.cpp @@ -17,6 +17,8 @@ #include "Game clock.h" #include "english.h" #include "Text.h" + #include "LaptopSave.h" + #include "Random.h" #endif #include "meanwhile.h" diff --git a/Laptop/history.cpp b/Laptop/history.cpp index e0bb949f..4a021941 100644 --- a/Laptop/history.cpp +++ b/Laptop/history.cpp @@ -15,6 +15,8 @@ #include "strategicmap.h" #include "QuestText.h" #include "text.h" + #include "message.h" + #include "LaptopSave.h" #endif diff --git a/Laptop/insurance Contract.cpp b/Laptop/insurance Contract.cpp index d931f633..22b67549 100644 --- a/Laptop/insurance Contract.cpp +++ b/Laptop/insurance Contract.cpp @@ -24,6 +24,7 @@ #include "Random.h" #include "Strategic Status.h" #include "Assignments.h" + #include "Map Screen Interface.h" #endif #define INS_CTRCT_ORDER_GRID_WIDTH 132 diff --git a/Laptop/laptop.cpp b/Laptop/laptop.cpp index 808535c6..61623e68 100644 --- a/Laptop/laptop.cpp +++ b/Laptop/laptop.cpp @@ -79,6 +79,11 @@ #include "Multi Language Graphic Utils.h" #include "BrokenLink.h" #include "BobbyRShipments.h" + #include "Dialogue Control.h" + #include "helpscreen.h" + #include "cheats.h" + #include "Strategic Status.h" + #include "Arms Dealer Init.h" #endif diff --git a/Laptop/mercs Account.cpp b/Laptop/mercs Account.cpp index 8fb8085b..07caf964 100644 --- a/Laptop/mercs Account.cpp +++ b/Laptop/mercs Account.cpp @@ -19,6 +19,7 @@ #include "LaptopSave.h" #include "Text.h" #include "Speck Quotes.h" + #include "Multi Language Graphic Utils.h" #endif #define MERC_ACCOUNT_TEXT_FONT FONT14ARIAL diff --git a/Laptop/mercs Files.cpp b/Laptop/mercs Files.cpp index b3c55757..0b84bdf4 100644 --- a/Laptop/mercs Files.cpp +++ b/Laptop/mercs Files.cpp @@ -22,6 +22,11 @@ #include "LaptopSave.h" #include "Text.h" #include "Speck Quotes.h" + #include "Multi Language Graphic Utils.h" + #include "Quests.h" + #include "Assignments.h" + #include "Input.h" + #include "english.h" #endif #include "Cheats.h" diff --git a/Laptop/mercs.cpp b/Laptop/mercs.cpp index faafec04..d7923630 100644 --- a/Laptop/mercs.cpp +++ b/Laptop/mercs.cpp @@ -23,6 +23,8 @@ #include "Speck Quotes.h" #include "mercs Account.h" #include "Soldier Profile.h" + #include "Game Event Hook.h" + #include "Quests.h" #endif #define MERC_TEXT_FONT FONT12ARIAL diff --git a/Laptop/personnel.cpp b/Laptop/personnel.cpp index 9cd1ce13..0e337a2a 100644 --- a/Laptop/personnel.cpp +++ b/Laptop/personnel.cpp @@ -28,6 +28,9 @@ #include "Soldier Add.h" #include "Interface Items.h" #include "Weapons.h" + #include "strategicmap.h" + #include "GameSettings.h" + #include "Merc Contract.h" #endif #include "Soldier Macros.h" diff --git a/Loading Screen.cpp b/Loading Screen.cpp index 2662ae3f..6057559a 100644 --- a/Loading Screen.cpp +++ b/Loading Screen.cpp @@ -2,6 +2,19 @@ #include "JA2 All.h" #include "Loading Screen.h" #include "INIReader.h" +#else + #include "vsurface.h" + #include "mapscreen.h" + #include "Loading Screen.h" + #include "Campaign Types.h" + #include "Game Clock.h" + #include "GameSettings.h" + #include "Random.h" + #include "Debug.h" + #include "local.h" + #include "Font Control.h" + #include "font.h" + #include "render dirty.h" #endif extern HVSURFACE ghFrameBuffer; @@ -35,7 +48,6 @@ BOOLEAN bShowSmallImage = FALSE; SECTOR_LOADSCREENS gSectorLoadscreens[MAX_SECTOR_LOADSCREENS]; - //returns the UINT8 ID for the specified sector. UINT8 GetLoadScreenID( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ) { @@ -44,8 +56,6 @@ UINT8 GetLoadScreenID( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ) BOOLEAN fNight = FALSE; ubSectorID = SECTOR( sSectorX, sSectorY ); - - if( NightTime() ) //before 5AM or after 9PM { fNight = TRUE; @@ -568,138 +578,13 @@ void DisplayLoadScreenWithID( UINT8 ubLoadScreenID ) HVSURFACE hVSurface; UINT32 uiLoadScreen; STRING512 smallImage; - BOOLEAN fExternalLS = FALSE; bShowSmallImage = FALSE; vs_desc.fCreateFlags = VSURFACE_CREATE_FROMFILE | VSURFACE_SYSTEM_MEM_USAGE; - if (gGameExternalOptions.gfUseExternalLoadscreens) - { - if ((ubLoadScreenID == HELI || ubLoadScreenID == DAY || ubLoadScreenID == DAY_ALT || - ubLoadScreenID == NIGHT || ubLoadScreenID == NIGHT_ALT) && szSector != NULL) - { - fExternalLS = TRUE; - } - else - { - fExternalLS = FALSE; - } - } - else - { - if ((ubLoadScreenID == HELI || ubLoadScreenID == DAY || ubLoadScreenID == DAY_ALT || - ubLoadScreenID == NIGHT || ubLoadScreenID == NIGHT_ALT) && szSector != NULL) - { - fExternalLS = TRUE; - } - else - { - fExternalLS = FALSE; - } - } - - if (fExternalLS) - { - // Get the image path - char szImagePath[80]; - char szImageFormat[5]; - char szFullImagePath[80]; - - // Start screen - if (ubLoadScreenID == HELI) - { - strncpy(szImagePath, gSectorLoadscreens[0].szDay, 80); - - strncpy(szImageFormat, ".", MAX_IMAGE_FORMAT_CHARS); - strcat(szImageFormat, gSectorLoadscreens[0].szImageFormat); - } - else - { - for (int i = 1; i < MAX_SECTOR_LOADSCREENS; i++) - { - // We found the sector - if (strcmp(gSectorLoadscreens[i].szLocation, szSector) == 0) - { - strncpy(szImageFormat, ".", MAX_IMAGE_FORMAT_CHARS); - - strcat(szImageFormat, gSectorLoadscreens[i].szImageFormat); - - BOOLEAN fAlternate = gSectorLoadscreens[i].RandomAltSector; - - if (fAlternate) - { - // Day - if (ubLoadScreenID == DAY) - { - if( Random( 2 ) ) - { - ubLoadScreenID = DAY; - } - else - { - ubLoadScreenID = DAY_ALT; - } - } - // Night - else - { - if( Random( 2 ) ) - { - ubLoadScreenID = NIGHT; - } - else - { - ubLoadScreenID = NIGHT_ALT; - } - } - } - switch (ubLoadScreenID) { - case DAY: - strncpy(szImagePath, gSectorLoadscreens[i].szDay, MAX_IMAGE_PATH_CHARS); - break; - case DAY_ALT: - strncpy(szImagePath, gSectorLoadscreens[i].szDayAlt, MAX_IMAGE_PATH_CHARS); - break; - case NIGHT: - strncpy(szImagePath, gSectorLoadscreens[i].szNight, MAX_IMAGE_PATH_CHARS); - break; - case NIGHT_ALT: - strncpy(szImagePath, gSectorLoadscreens[i].szNightAlt, MAX_IMAGE_PATH_CHARS); - break; - } - break; - } - } - } - - // Small image: 640x480 - strncpy(szFullImagePath, szImagePath, 80); - strcat(szFullImagePath, szImageFormat); - strcpy(smallImage,szFullImagePath); - - // Actual image, depending on the resolution - if (iResolution == 1) - { - strncpy(szFullImagePath, szImagePath, 80); - strcat(szFullImagePath, "_800x600"); - strcat(szFullImagePath, szImageFormat); - } - else if (iResolution == 2) - { - strncpy(szFullImagePath, szImagePath, 80); - strcat(szFullImagePath, "_1024x768"); - strcat(szFullImagePath, szImageFormat); - } - - strcpy(vs_desc.ImageFile,szFullImagePath); - } - else - { - switch( ubLoadScreenID ) - { case LOADINGSCREEN_NOTHING: strcpy(smallImage, "LOADSCREENS\\LS_Heli.sti"); if (iResolution == 0) @@ -715,7 +600,6 @@ void DisplayLoadScreenWithID( UINT8 ubLoadScreenID ) strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Heli_1024x768.sti"); } break; - case LOADINGSCREEN_DAYGENERIC: strcpy(smallImage, "LOADSCREENS\\LS_DayGeneric.sti"); if (iResolution == 0) @@ -970,11 +854,8 @@ void DisplayLoadScreenWithID( UINT8 ubLoadScreenID ) } break; - case LOADINGSCREEN_HELI: - strcpy(smallImage, "LOADSCREENS\\LS_Heli.sti"); - if (iResolution == 0) { strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Heli.sti"); @@ -989,7 +870,6 @@ void DisplayLoadScreenWithID( UINT8 ubLoadScreenID ) } break; - case LOADINGSCREEN_BASEMENT: strcpy(smallImage, "LOADSCREENS\\LS_Basement.sti"); if (iResolution == 0) @@ -1404,9 +1284,6 @@ void DisplayLoadScreenWithID( UINT8 ubLoadScreenID ) strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Heli_1024x768.sti"); } break; - - /* WANNE: Sir tech made - END */ - } // Switch - END } // Sti loadscreen (big image) is not available diff --git a/Loading Screen.h b/Loading Screen.h index c4a7f24e..6db7d22f 100644 --- a/Loading Screen.h +++ b/Loading Screen.h @@ -86,4 +86,4 @@ typedef struct extern SECTOR_LOADSCREENS gSectorLoadscreens[MAX_SECTOR_LOADSCREENS]; -#endif \ No newline at end of file +#endif diff --git a/MainMenuScreen.cpp b/MainMenuScreen.cpp index 1e1c3b8f..1329dc3e 100644 --- a/MainMenuScreen.cpp +++ b/MainMenuScreen.cpp @@ -31,6 +31,7 @@ #include "text.h" #include "Multi Language Graphic Utils.h" #include "Encrypted File.h" + #include "ja2 splash.h" #endif #define MAINMENU_TEXT_FILE "LoadScreens\\MainMenu.edt" diff --git a/MessageBoxScreen.cpp b/MessageBoxScreen.cpp index 5fd35538..f62552ec 100644 --- a/MessageBoxScreen.cpp +++ b/MessageBoxScreen.cpp @@ -23,6 +23,7 @@ #include "cursor control.h" #include "laptop.h" #include "text.h" + #include "overhead map.h" #endif #define MSGBOX_DEFAULT_WIDTH 300 diff --git a/MessageBoxScreen.h b/MessageBoxScreen.h index acd91cc9..a0abaab8 100644 --- a/MessageBoxScreen.h +++ b/MessageBoxScreen.h @@ -1,6 +1,8 @@ #ifndef _MSGBOX_H #define _MSGBOX_H +#include "mousesystem.h" + // Message box flags #define MSG_BOX_FLAG_USE_CENTERING_RECT 0x0001 // Pass in a rect to center in #define MSG_BOX_FLAG_OK 0x0002 // Displays OK button diff --git a/Options Screen.cpp b/Options Screen.cpp index 652a0548..e14e3c20 100644 --- a/Options Screen.cpp +++ b/Options Screen.cpp @@ -35,6 +35,8 @@ #include "Message.h" #include "Language Defines.h" #include "Multi Language Graphic Utils.h" + #include "Map Information.h" + #include "SmokeEffects.h" #endif #include "WorldMan.h" diff --git a/Options Screen.h b/Options Screen.h index 521cc8b3..612a76b9 100644 --- a/Options Screen.h +++ b/Options Screen.h @@ -1,6 +1,7 @@ #ifndef _OPTIONS_SCREEN__H_ #define _OPTIONS_SCREEN__H_ +#include "MessageBoxScreen.h" #define OPT_BUTTON_FONT FONT14ARIAL #define OPT_BUTTON_ON_COLOR 73//FONT_MCOLOR_WHITE diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp index 66d68f61..68bdd096 100644 --- a/SaveLoadGame.cpp +++ b/SaveLoadGame.cpp @@ -90,6 +90,19 @@ #include "lighteffects.h" #include "HelpScreen.h" #include "Animated ProgressBar.h" + #include "merctextbox.h" + #include "render dirty.h" + #include "Map Information.h" + #include "Interface Items.h" + #include "Civ Quotes.h" + #include "Scheduling.h" + #include "Animation Data.h" + #include "Game Init.h" + #include "cheats.h" + #include "Strategic Event Handler.h" + #include "interface panels.h" + #include "interface dialogue.h" + #include "Assignments.h" #endif #include "BobbyR.h" @@ -5481,4 +5494,4 @@ UINT32 CalcJA2EncryptionSet( SAVED_GAME_HEADER * pSaveGameHeader ) } return( uiEncryptionSet ); -} \ No newline at end of file +} diff --git a/SaveLoadGame.h b/SaveLoadGame.h index 9836fba6..ef8991ab 100644 --- a/SaveLoadGame.h +++ b/SaveLoadGame.h @@ -2,6 +2,7 @@ #define _SAVE_LOAD_GAME_H_ #include "Soldier Control.h" +#include "GameSettings.h" #define BYTESINMEGABYTE 1048576 //1024*1024 #define REQUIRED_FREE_SPACE (20 * BYTESINMEGABYTE) diff --git a/SaveLoadScreen.cpp b/SaveLoadScreen.cpp index 9ad3c723..99f3f891 100644 --- a/SaveLoadScreen.cpp +++ b/SaveLoadScreen.cpp @@ -35,6 +35,7 @@ #include "Message.h" #include "Map Screen Interface.h" #include "Multi Language Graphic Utils.h" + #include "Campaign Types.h" #endif #include "Campaign Init.h" @@ -2569,4 +2570,4 @@ void StartFadeOutForSaveLoadScreen() FadeOutNextFrame( ); gfStartedFadingOut = TRUE; gfExitAfterMessageBox = TRUE; -} \ No newline at end of file +} diff --git a/Standard Gaming Platform/Container.cpp b/Standard Gaming Platform/Container.cpp index 7e1fd032..f1728b26 100644 --- a/Standard Gaming Platform/Container.cpp +++ b/Standard Gaming Platform/Container.cpp @@ -32,7 +32,9 @@ #include "MemMan.h" #include "Debug.h" #include "Container.h" + #if _MSC_VER < 1300 //(iostream.h was removed from VC.NET2003) #include + #endif #endif diff --git a/Standard Gaming Platform/Cursor Control.h b/Standard Gaming Platform/Cursor Control.h index 3040db6c..e5b67eff 100644 --- a/Standard Gaming Platform/Cursor Control.h +++ b/Standard Gaming Platform/Cursor Control.h @@ -6,17 +6,16 @@ #include "VObject.h" #include "VSurface.h" -#ifdef __cplusplus -extern "C" { -#endif - - #if defined( JA2 ) || defined( UTIL ) #include "Video.h" #else #include "video2.h" #endif +#ifdef __cplusplus +extern "C" { +#endif + extern UINT32 GetCursorHandle(UINT32 uiCursorIndex); extern void UnloadCursorData(UINT32 uiCursorIndex); diff --git a/Standard Gaming Platform/DEBUG.H b/Standard Gaming Platform/DEBUG.H index aa583661..eb1d7031 100644 --- a/Standard Gaming Platform/DEBUG.H +++ b/Standard Gaming Platform/DEBUG.H @@ -169,6 +169,13 @@ extern void _DebugMessage(UINT8 *pSourceFile, UINT32 uiLineNum, UINT8 *pString) //******************************************************************************************* #endif + +#ifdef DEBUG_ATTACKBUSY +#define DebugAttackBusy(x) OutputDebugString( x) +#else +#define DebugAttackBusy(x) +#endif + /* #ifdef __cplusplus } diff --git a/Standard Gaming Platform/DirectDraw Calls.cpp b/Standard Gaming Platform/DirectDraw Calls.cpp index 90a004ab..2634d2a1 100644 --- a/Standard Gaming Platform/DirectDraw Calls.cpp +++ b/Standard Gaming Platform/DirectDraw Calls.cpp @@ -9,6 +9,7 @@ #include #include "debug.h" #include "video_private.h" + #include "vobject_blitters.h" #endif // DirectDrawSurface2 Calls diff --git a/Standard Gaming Platform/DirectDraw Calls.h b/Standard Gaming Platform/DirectDraw Calls.h index 3e653cef..2d475708 100644 --- a/Standard Gaming Platform/DirectDraw Calls.h +++ b/Standard Gaming Platform/DirectDraw Calls.h @@ -3,6 +3,7 @@ #include "DirectX Common.h" #include +#include "sgp.h" // Direct Draw Functions diff --git a/Standard Gaming Platform/ExceptionHandling.h b/Standard Gaming Platform/ExceptionHandling.h index 0403194e..b5ae4a98 100644 --- a/Standard Gaming Platform/ExceptionHandling.h +++ b/Standard Gaming Platform/ExceptionHandling.h @@ -1,6 +1,7 @@ #ifndef _EXCEPTION_HANDLING__H_ #define _EXCEPTION_HANDLING__H_ +#include //uncomment this line if you want Exceptions to be handled #ifdef JA2 diff --git a/Standard Gaming Platform/himage.cpp b/Standard Gaming Platform/himage.cpp index 562dacc0..98c83414 100644 --- a/Standard Gaming Platform/himage.cpp +++ b/Standard Gaming Platform/himage.cpp @@ -3,6 +3,7 @@ #elif defined( WIZ8_PRECOMPILED_HEADERS ) #include "WIZ8 SGP ALL.H" #else + #include "builddefines.h" #include #include #include "types.h" diff --git a/Standard Gaming Platform/impTGA.cpp b/Standard Gaming Platform/impTGA.cpp index 83418b8f..419e0aab 100644 --- a/Standard Gaming Platform/impTGA.cpp +++ b/Standard Gaming Platform/impTGA.cpp @@ -33,6 +33,7 @@ #else #include "video2.h" #endif + #include "impTGA.h" #endif //************************************************************************** diff --git a/Standard Gaming Platform/impTGA.h b/Standard Gaming Platform/impTGA.h index deeeeab8..b486fbd5 100644 --- a/Standard Gaming Platform/impTGA.h +++ b/Standard Gaming Platform/impTGA.h @@ -39,16 +39,16 @@ // Function Prototypes // //************************************************************************** - +/* #ifdef __cplusplus extern "C" { #endif - +*/ BOOLEAN LoadTGAFileToImage( HIMAGE hImage, UINT16 fContents ); - +/* #ifdef __cplusplus } #endif - +*/ #endif diff --git a/Standard Gaming Platform/sgp.cpp b/Standard Gaming Platform/sgp.cpp index 7ca4a88c..0bc6d627 100644 --- a/Standard Gaming Platform/sgp.cpp +++ b/Standard Gaming Platform/sgp.cpp @@ -30,6 +30,8 @@ #if !defined( JA2 ) && !defined( UTIL ) #include "GameData.h" // for MoveTimer() [Wizardry specific] #endif + #include "LibraryDataBase.h" + #include "utilities.h" #endif #include "input.h" @@ -40,6 +42,7 @@ #include "dbt.h" #include "INIReader.h" +#include "Console.h" #ifdef JA2 #include "BuildDefines.h" @@ -120,7 +123,13 @@ INT32 FAR PASCAL WindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LP { static BOOLEAN fRestore = FALSE; - if(gfIgnoreMessages) + if ( Message == WM_USER ) + { + FreeConsole(); + return 0L; + } + + if(gfIgnoreMessages) return(DefWindowProc(hWindow, Message, wParam, lParam)); // ATE: This is for older win95 or NT 3.51 to get MOUSE_WHEEL Messages @@ -752,6 +761,10 @@ int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR p return 0; } +#ifdef LUACONSOLE + CreateConsole(); +#endif + #ifdef JA2 #ifdef ENGLISH SetIntroType( INTRO_SPLASH ); @@ -779,6 +792,10 @@ int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR p } else { // Windows hasn't processed any messages, therefore we handle the rest +#ifdef LUACONSOLE + PollConsole( ); +#endif + if (gfApplicationActive == FALSE) { // Well we got nothing to do but to wait for a message to activate WaitMessage(); diff --git a/Standard Gaming Platform/soundman.cpp b/Standard Gaming Platform/soundman.cpp index 1bb5adc6..0e7360db 100644 --- a/Standard Gaming Platform/soundman.cpp +++ b/Standard Gaming Platform/soundman.cpp @@ -11,6 +11,7 @@ #elif defined( WIZ8_PRECOMPILED_HEADERS ) #include "WIZ8 SGP ALL.H" #else + #include "builddefines.h" #include #include #include "soundman.h" diff --git a/Standard Gaming Platform/video.cpp b/Standard Gaming Platform/video.cpp index d1499461..a1f379dd 100644 --- a/Standard Gaming Platform/video.cpp +++ b/Standard Gaming Platform/video.cpp @@ -1,6 +1,5 @@ #ifdef JA2_PRECOMPILED_HEADERS #include "JA2 SGP ALL.H" - #include "resource.h" #elif defined( WIZ8_PRECOMPILED_HEADERS ) #include "WIZ8 SGP ALL.H" #else @@ -9,6 +8,7 @@ #include "vobject_blitters.h" #include "sgp.h" #include + #include #include "renderworld.h" #include "Render Dirty.h" #include "Isometric utils.h" @@ -16,8 +16,12 @@ #include "impTGA.h" #include "timer control.h" #include "Fileman.h" + #include "Input.h" + #include "GameSettings.h" #endif +#include "resource.h" + #ifndef _MT #define _MT #endif diff --git a/Standard Gaming Platform/vobject_blitters.h b/Standard Gaming Platform/vobject_blitters.h index ef4db566..636eab1f 100644 --- a/Standard Gaming Platform/vobject_blitters.h +++ b/Standard Gaming Platform/vobject_blitters.h @@ -5,9 +5,11 @@ #include "vsurface.h" #include "vobject.h" +/* #ifdef __cplusplus extern "C" { #endif +*/ extern SGPRect ClippingRect; extern UINT32 guiTranslucentMask; @@ -186,9 +188,9 @@ BOOLEAN Blt8BPPDataTo16BPPBufferTransZPixelateObscured( UINT16 *pBuffer, UINT32 BOOLEAN FillRect8BPP(UINT8 *pBuffer, UINT32 uiDestPitchBYTES, INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT8 color); BOOLEAN FillRect16BPP(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color); - +/* #ifdef __cplusplus } #endif - +*/ #endif diff --git a/Strategic/AI Viewer.cpp b/Strategic/AI Viewer.cpp index e2bb1c6e..59331d9c 100644 --- a/Strategic/AI Viewer.cpp +++ b/Strategic/AI Viewer.cpp @@ -4,6 +4,7 @@ #include "Strategic All.h" #include "INIReader.h" #else + #include "builddefines.h" #include #include "types.h" #include "english.h" @@ -33,6 +34,11 @@ #include "Creature Spreading.h" #include "message.h" #include "Game Init.h" + #include "Strategic AI.h" + #include "Campaign.h" + #include "Auto Resolve.h" + #include "Strategic Status.h" + #include "wordwrap.h" #endif #ifdef JA2BETAVERSION diff --git a/Strategic/Assignments.cpp b/Strategic/Assignments.cpp index 1659513d..59f40b46 100644 --- a/Strategic/Assignments.cpp +++ b/Strategic/Assignments.cpp @@ -56,6 +56,13 @@ #include "math.h" #include "SkillCheck.h" #include "Strategic Pathing.h" + #include "Game Event Hook.h" + #include "Strategic Event Handler.h" + #include "Map Information.h" + #include "Strategic Status.h" + #include "history.h" + #include "Map Screen Interface Map Inventory.h" + #include "interface dialogue.h" #endif #include "MilitiaSquads.h" diff --git a/Strategic/Auto Resolve.cpp b/Strategic/Auto Resolve.cpp index 12f00828..b0bc8de8 100644 --- a/Strategic/Auto Resolve.cpp +++ b/Strategic/Auto Resolve.cpp @@ -4,6 +4,7 @@ #include "Strategic All.h" #include "GameSettings.h" #else + #include "builddefines.h" #include #include "types.h" #include "Auto Resolve.h" @@ -56,6 +57,15 @@ #include "morale.h" #include "Strategic Town Loyalty.h" #include "GameSettings.h" + #include "Soldier macros.h" + #include "strategicmap.h" + #include "Quests.h" + #include "meanwhile.h" + #include "Inventory Choosing.h" + #include "Game Event Hook.h" + #include "Assignments.h" + #include "cheats.h" + #include "Map Information.h" #endif #include "Reinforcement.h" diff --git a/Strategic/Campaign Init.cpp b/Strategic/Campaign Init.cpp index c7a15d63..f8a68027 100644 --- a/Strategic/Campaign Init.cpp +++ b/Strategic/Campaign Init.cpp @@ -14,6 +14,9 @@ #include "Creature Spreading.h" #include "Strategic AI.h" #include "XML.h" + #include "expat.h" + #include "Debug Control.h" + #include "Tactical Save.h" #endif extern BOOLEAN InitStrategicMovementCosts(); diff --git a/Strategic/Creature Spreading.cpp b/Strategic/Creature Spreading.cpp index 554348a7..b639d2f5 100644 --- a/Strategic/Creature Spreading.cpp +++ b/Strategic/Creature Spreading.cpp @@ -27,6 +27,10 @@ #include "Map Edgepoints.h" #include "Animation Data.h" #include "opplist.h" + #include "meanwhile.h" + #include "Strategic AI.h" + #include "MessageBoxScreen.h" + #include "Map Information.h" #endif #ifdef JA2BETAVERSION diff --git a/Strategic/Game Clock.cpp b/Strategic/Game Clock.cpp index face2b1f..e07849ac 100644 --- a/Strategic/Game Clock.cpp +++ b/Strategic/Game Clock.cpp @@ -20,6 +20,11 @@ #include "Event Pump.h" #include "Text.h" #include "Interface Control.h" + #include "Map Screen Interface Map.h" + #include "Map Screen Interface Bottom.h" + #include "gamescreen.h" + #include "Map Information.h" + #include "GameSettings.h" #endif //#define DEBUG_GAME_CLOCK @@ -68,23 +73,23 @@ extern BOOLEAN fMapScreenBottomDirty; //These contain all of the information about the game time, rate of time, etc. //All of these get saved and loaded. -INT32 giTimeCompressMode = TIME_COMPRESS_X0; -UINT8 gubClockResolution = 1; -BOOLEAN gfGamePaused = TRUE; -BOOLEAN gfTimeInterrupt = FALSE; -BOOLEAN gfTimeInterruptPause = FALSE; -BOOLEAN fSuperCompression = FALSE; +INT32 giTimeCompressMode = TIME_COMPRESS_X0; +UINT8 gubClockResolution = 1; +BOOLEAN gfGamePaused = TRUE; +BOOLEAN gfTimeInterrupt = FALSE; +BOOLEAN gfTimeInterruptPause = FALSE; +BOOLEAN fSuperCompression = FALSE; UINT32 guiGameClock = gGameExternalOptions.iGameStartingTime; UINT32 guiPreviousGameClock = 0; // used only for error-checking purposes UINT32 guiGameSecondsPerRealSecond; UINT32 guiTimesThisSecondProcessed = 0; -INT32 iPausedPopUpBox = -1; +INT32 iPausedPopUpBox = -1; UINT32 guiDay; UINT32 guiHour; UINT32 guiMin; CHAR16 gswzWorldTimeStr[20]; -INT32 giTimeCompressSpeeds[ NUM_TIME_COMPRESS_SPEEDS ] = { 0, 1, 5 * 60, 30 * 60, 60 * 60 }; -UINT16 usPausedActualWidth; +INT32 giTimeCompressSpeeds[ NUM_TIME_COMPRESS_SPEEDS ] = { 0, 1, 5 * 60, 30 * 60, 60 * 60 }; +UINT16 usPausedActualWidth; UINT16 usPausedActualHeight; UINT32 guiTimeOfLastEventQuery = 0; BOOLEAN gfLockPauseState = FALSE; @@ -95,7 +100,7 @@ UINT32 guiLockPauseStateLastReasonId = 0; //***When adding new saved time variables, make sure you remove the appropriate amount from the paddingbytes and // more IMPORTANTLY, add appropriate code in Save/LoadGameClock()! #define TIME_PADDINGBYTES 20 -UINT8 gubUnusedTimePadding[TIME_PADDINGBYTES]; +UINT8 gubUnusedTimePadding[TIME_PADDINGBYTES]; diff --git a/Strategic/Game Clock.h b/Strategic/Game Clock.h index d26c1c62..bfbc70ec 100644 --- a/Strategic/Game Clock.h +++ b/Strategic/Game Clock.h @@ -201,4 +201,4 @@ void HandlePlayerPauseUnPauseOfGame( void ); void ClearTacticalStuffDueToTimeCompression( void ); -#endif \ No newline at end of file +#endif diff --git a/Strategic/Game Event Hook.cpp b/Strategic/Game Event Hook.cpp index 9ddc0983..e17e2122 100644 --- a/Strategic/Game Event Hook.cpp +++ b/Strategic/Game Event Hook.cpp @@ -37,6 +37,13 @@ #include "Strategic AI.h" #include "Merc Contract.h" #include "Strategic Status.h" + #include "INIReader.h" + #include "GameSettings.h" + #include "english.h" + #include "Input.h" + #include "Soldier Profile.h" + #include "laptop.h" + #include "Campaign.h" #endif #ifdef JA2BETAVERSION diff --git a/Strategic/Game Events.cpp b/Strategic/Game Events.cpp index 0eb885ca..419ff4ca 100644 --- a/Strategic/Game Events.cpp +++ b/Strategic/Game Events.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Strategic All.h" #else + #include "builddefines.h" #include #include "types.h" #include "Game Events.h" diff --git a/Strategic/Game Init.cpp b/Strategic/Game Init.cpp index e30ce51f..b826cb9a 100644 --- a/Strategic/Game Init.cpp +++ b/Strategic/Game Init.cpp @@ -47,6 +47,19 @@ #include "npc.h" #include "Init.h" #include "GameSettings.h" + #include "opplist.h" + #include "interface dialogue.h" + #include "Map Screen Interface Border.h" + #include "Map Screen Helicopter.h" + #include "Vehicles.h" + #include "Map Screen Interface Map.h" + #include "PreBattle Interface.h" + #include "Arms Dealer Init.h" + #include "bobbyr.h" + #include "helpscreen.h" + #include "Air Raid.h" + #include "Interface.h" + #include "cheats.h" #endif // Temp function diff --git a/Strategic/Hourly Update.cpp b/Strategic/Hourly Update.cpp index 05993e24..941b1e2e 100644 --- a/Strategic/Hourly Update.cpp +++ b/Strategic/Hourly Update.cpp @@ -9,6 +9,15 @@ #include "Morale.h" #include "Quests.h" #include "Game Clock.h" + #include "Overhead.h" + #include "Boxing.h" + #include "jascreens.h" + #include "screenids.h" + #include "Items.h" + #include "Random.h" + #include "finances.h" + #include "history.h" + #include "Dialogue Control.h" #endif void HourlyQuestUpdate( void ); diff --git a/Strategic/Map Screen Helicopter.cpp b/Strategic/Map Screen Helicopter.cpp index 775accbb..4a982be8 100644 --- a/Strategic/Map Screen Helicopter.cpp +++ b/Strategic/Map Screen Helicopter.cpp @@ -28,6 +28,16 @@ #include "Squads.h" #include "Player Command.h" #include "Sound Control.h" + #include "GameSettings.h" + #include "meanwhile.h" + #include "Map Screen Interface Border.h" + #include "Strategic Event Handler.h" + #include "Overhead.h" + #include "Soldier Create.h" + #include "renderworld.h" + #include "soundman.h" + #include "Isometric Utils.h" + #include "Scheduling.h" #endif diff --git a/Strategic/Map Screen Interface Border.cpp b/Strategic/Map Screen Interface Border.cpp index e2d46ed5..adaabe1f 100644 --- a/Strategic/Map Screen Interface Border.cpp +++ b/Strategic/Map Screen Interface Border.cpp @@ -23,6 +23,7 @@ #include "Campaign Types.h" #include "Strategic Town Loyalty.h" #include "strategicmap.h" + #include "Assignments.h" #endif diff --git a/Strategic/Map Screen Interface Bottom.cpp b/Strategic/Map Screen Interface Bottom.cpp index a08d6156..ff63feb6 100644 --- a/Strategic/Map Screen Interface Bottom.cpp +++ b/Strategic/Map Screen Interface Bottom.cpp @@ -36,6 +36,20 @@ #include "LaptopSave.h" #include "Sound Control.h" #include "Interface Items.h" + #include "wordwrap.h" + #include "meanwhile.h" + #include "Dialogue Control.h" + #include "Map Screen Helicopter.h" + #include "Map Screen Interface TownMine Info.h" + #include "Merc Contract.h" + #include "Map Screen Interface Map Inventory.h" + #include "Explosion Control.h" + #include "Creature Spreading.h" + #include "Assignments.h" + #include "Soldier macros.h" + #include "GameSettings.h" + #include "_Ja25EnglishText.h" + #include "SaveLoadScreen.h" #endif diff --git a/Strategic/Map Screen Interface Map Inventory.cpp b/Strategic/Map Screen Interface Map Inventory.cpp index 59af9b4f..54119bb6 100644 --- a/Strategic/Map Screen Interface Map Inventory.cpp +++ b/Strategic/Map Screen Interface Map Inventory.cpp @@ -26,6 +26,14 @@ #include "english.h" #include "Multi Language Graphic Utils.h" #include "GameSettings.h" + #include "Radar Screen.h" + #include "message.h" + #include "weapons.h" + #include "finances.h" + #include "Game Clock.h" + #include "Sound Control.h" + #include "interface panels.h" + #include "wordwrap.h" #endif #include "ShopKeeper Interface.h" diff --git a/Strategic/Map Screen Interface Map.cpp b/Strategic/Map Screen Interface Map.cpp index 2fe1afe4..7a95780e 100644 --- a/Strategic/Map Screen Interface Map.cpp +++ b/Strategic/Map Screen Interface Map.cpp @@ -41,6 +41,9 @@ #include "Town Militia.h" #include "Militia Control.h" #include "GameSettings.h" + #include "Tactical Save.h" + #include "Map Information.h" + #include "Air Raid.h" #endif // zoom x and y coords for map scrolling diff --git a/Strategic/Map Screen Interface Map.h b/Strategic/Map Screen Interface Map.h index 642e25cf..e9ddeb7a 100644 --- a/Strategic/Map Screen Interface Map.h +++ b/Strategic/Map Screen Interface Map.h @@ -3,6 +3,7 @@ #include "Vehicles.h" +#include "mapscreen.h" // functions void DrawMapIndexBigMap( BOOLEAN fSelectedCursorIsYellow ); diff --git a/Strategic/Map Screen Interface TownMine Info.cpp b/Strategic/Map Screen Interface TownMine Info.cpp index f64d4f9c..b07f0097 100644 --- a/Strategic/Map Screen Interface TownMine Info.cpp +++ b/Strategic/Map Screen Interface TownMine Info.cpp @@ -24,6 +24,8 @@ #include "video.h" #include "Town Militia.h" #include "HelpScreen.h" + #include "Map Screen Helicopter.h" + #include "Tactical Save.h" #endif diff --git a/Strategic/Map Screen Interface.cpp b/Strategic/Map Screen Interface.cpp index c3aede8b..963ddfbb 100644 --- a/Strategic/Map Screen Interface.cpp +++ b/Strategic/Map Screen Interface.cpp @@ -38,6 +38,22 @@ #include "WordWrap.h" #include "interface control.h" #include "GameSettings.h" + #include "Campaign Types.h" + #include "Map Screen Interface Map Inventory.h" + #include "strategic.h" + #include "Keys.h" + #include "Soldier macros.h" + #include "Militia Control.h" + #include "Random.h" + #include "Cursor Control.h" + #include "renderworld.h" + #include "Game Init.h" + #include "Strategic Mines.h" + #include "finances.h" + #include "strategic.h" + #include "Air Raid.h" + #include "Queen Command.h" + #include "Render Fun.h" #endif // inventory pool position on screen diff --git a/Strategic/Map Screen Interface.h b/Strategic/Map Screen Interface.h index ac9bb7e9..8cb5e1b5 100644 --- a/Strategic/Map Screen Interface.h +++ b/Strategic/Map Screen Interface.h @@ -5,7 +5,7 @@ #include "Types.h" #include "Soldier Control.h" #include "MessageBoxScreen.h" - +#include "Font Control.h" typedef struct FASTHELPREGION { diff --git a/Strategic/Meanwhile.cpp b/Strategic/Meanwhile.cpp index 5b4bcd1c..cfa45eb7 100644 --- a/Strategic/Meanwhile.cpp +++ b/Strategic/Meanwhile.cpp @@ -21,6 +21,21 @@ #include "assignments.h" #include "strategic.h" #include "text.h" + #include "interface control.h" + #include "Interface Items.h" + #include "Map Information.h" + #include "Map Screen Interface Map.h" + #include "Map Screen Interface.h" + #include "Music Control.h" + #include "Interface.h" + #include "Game Events.h" + #include "GameSettings.h" + #include "Strategic AI.h" + #include "interface dialogue.h" + #include "Quests.h" + #include "Campaign Types.h" + #include "Squads.h" + #include "Random.h" #endif #define MAX_MEANWHILE_PROFILES 10 diff --git a/Strategic/Merc Contract.cpp b/Strategic/Merc Contract.cpp index b4fac297..20a16f4b 100644 --- a/Strategic/Merc Contract.cpp +++ b/Strategic/Merc Contract.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "Strategic All.h" #else @@ -35,6 +37,8 @@ #include "Strategic Status.h" #include "mercs.h" #include "insurance contract.h" + #include "Vehicles.h" + #include "email.h" #endif diff --git a/Strategic/MilitiaSquads.cpp b/Strategic/MilitiaSquads.cpp index 757ebc2e..9050c7bc 100644 --- a/Strategic/MilitiaSquads.cpp +++ b/Strategic/MilitiaSquads.cpp @@ -20,6 +20,11 @@ #include "squads.h" #include "Soldier Create.h" #include "Dialogue Control.h" + #include "GameSettings.h" + #include "Queen Command.h" + #include "math.h" + #include "Auto Resolve.h" + #include "Vehicles.h" #endif #include "MilitiaSquads.h" diff --git a/Strategic/Player Command.cpp b/Strategic/Player Command.cpp index 6fb9528c..652769cc 100644 --- a/Strategic/Player Command.cpp +++ b/Strategic/Player Command.cpp @@ -15,6 +15,14 @@ #include "strategicmap.h" #include "Map Screen Helicopter.h" #include "Game Clock.h" + #include "meanwhile.h" + #include "email.h" + #include "GameSettings.h" + #include "Strategic Status.h" + #include "Strategic AI.h" + #include "PreBattle Interface.h" + #include "Map Screen Interface.h" + #include "Tactical Save.h" #endif diff --git a/Strategic/PreBattle Interface.cpp b/Strategic/PreBattle Interface.cpp index bca4b07e..949e12ce 100644 --- a/Strategic/PreBattle Interface.cpp +++ b/Strategic/PreBattle Interface.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Strategic All.h" #else + #include "builddefines.h" #include #include "PreBattle Interface.h" #include "Button System.h" @@ -32,6 +33,17 @@ #include "Random.h" #include "Creature Spreading.h" #include "Multi Language Graphic Utils.h" + #include "Map Screen Helicopter.h" + #include "Quests.h" + #include "Map Screen Interface Border.h" + #include "Strategic Status.h" + #include "interface control.h" + #include "Strategic Town Loyalty.h" + #include "Squads.h" + #include "Assignments.h" + #include "Soldier macros.h" + #include "history.h" + #include "Cheats.h" #endif extern void InitializeTacticalStatusAtBattleStart(); diff --git a/Strategic/Queen Command.cpp b/Strategic/Queen Command.cpp index 2f8b5e1b..d840f375 100644 --- a/Strategic/Queen Command.cpp +++ b/Strategic/Queen Command.cpp @@ -26,6 +26,23 @@ #include "Soldier Ani.h" #include "Strategic AI.h" #include "GameSettings.h" + #include "MessageBoxScreen.h" + #include "screenids.h" + #include "Strategic Town Loyalty.h" + #include "Soldier Profile.h" + #include "Quests.h" + #include "jascreens.h" + #include "Auto Resolve.h" + #include "Game Event Hook.h" + #include "Animation Data.h" + #include "Game Clock.h" + #include "renderworld.h" + #include "Town Militia.h" + #include "Dialogue Control.h" + #include "Campaign Init.h" + #include "meanwhile.h" + #include "Soldier macros.h" + #include "Morale.h" #endif #ifdef JA2BETAVERSION diff --git a/Strategic/Quest Debug System.cpp b/Strategic/Quest Debug System.cpp index 405a5446..777089e2 100644 --- a/Strategic/Quest Debug System.cpp +++ b/Strategic/Quest Debug System.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "Strategic All.h" #else @@ -37,6 +39,7 @@ #include "Interface Dialogue.h" #include "SysUtil.h" #include "Message.h" + #include "Random.h" #endif //#ifdef JA2BETAVERSION @@ -433,7 +436,7 @@ SCROLL_BOX gItemListBox; // The Npc Scroll box SCROLL_BOX *gpActiveListBox; // Only 1 scroll box is active at a time, this is set to it. -INT16 gsQdsEnteringGridNo =0; +UINT16 gusQdsEnteringGridNo =0; UINT8 gubTextEntryAction = QD_DROP_DOWN_NO_ACTION; @@ -1246,11 +1249,11 @@ void RenderQuestDebugSystem() void DisplayCurrentGridNo() { - if( gsQdsEnteringGridNo != 0 ) + if( gusQdsEnteringGridNo != 0 ) { CHAR16 zTemp[512]; - swprintf( zTemp, L"%s: %d", QuestDebugText[ QUEST_DBS_CURRENT_GRIDNO ], gsQdsEnteringGridNo ); + swprintf( zTemp, L"%s: %d", QuestDebugText[ QUEST_DBS_CURRENT_GRIDNO ], gusQdsEnteringGridNo ); DrawTextToScreen( zTemp, QUEST_DBS_NPC_CURRENT_GRIDNO_X, QUEST_DBS_NPC_CURRENT_GRIDNO_Y, QUEST_DBS_NUMBER_COL_WIDTH, QUEST_DBS_FONT_DYNAMIC_TEXT, QUEST_DBS_COLOR_DYNAMIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); } } @@ -2688,7 +2691,7 @@ void BtnQuestDebugStartMercTalkingButtonButtonCallback(GUI_BUTTON *btn,INT32 rea // DoQDSMessageBox( MSG_BOX_BASIC_STYLE, zTemp, QUEST_DEBUG_SCREEN, MSG_BOX_FLAG_OK, NULL ); //set the initial value - gsQdsEnteringGridNo = 0; + gusQdsEnteringGridNo = 0; TextEntryBox( QuestDebugText[ QUEST_DBS_START_MERC_TALKING_FROM ], StartMercTalkingFromQuoteNum ); @@ -2943,7 +2946,7 @@ void InitQuestDebugTextInputBoxes() } */ - swprintf( sTemp, L"%d", gsQdsEnteringGridNo ); + swprintf( sTemp, L"%d", gusQdsEnteringGridNo ); //Text entry field AddTextInputField( QUEST_DBS_TEB_X+QUEST_DBS_TEB_WIDTH/2-30, QUEST_DBS_TEB_Y+65, 60, 15, MSYS_PRIORITY_HIGH+60, sTemp, QUEST_DBS_TEXT_FIELD_WIDTH, INPUTTYPE_NUMERICSTRICT ); @@ -2986,7 +2989,7 @@ void AddNPCToGridNo( INT32 iGridNo ) //Add all the npc in the current sectory the npc array AddNPCsInSectorToArray(); - gsQdsEnteringGridNo = (INT16)iGridNo; + gusQdsEnteringGridNo = (INT16)iGridNo; } @@ -2995,7 +2998,7 @@ void AddItemToGridNo( INT32 iGridNo ) { OBJECTTYPE Object; - gsQdsEnteringGridNo = (INT16)iGridNo; + gusQdsEnteringGridNo = (INT16)iGridNo; if( Item[ gItemListBox.sCurSelectedItem ].usItemClass == IC_KEY ) @@ -3023,7 +3026,7 @@ void AddKeyToGridNo( INT32 iKeyID ) CreateKeyObject( &Object, 1, (UINT8)iKeyID ); //add the item to the world - AddItemToPool( gsQdsEnteringGridNo, &Object, -1, 0, 0, 0 ); + AddItemToPool( gusQdsEnteringGridNo, &Object, -1, 0, 0, 0 ); } else gfAddKeyNextPass = TRUE; diff --git a/Strategic/Quest Debug System.h b/Strategic/Quest Debug System.h index 99f782c1..9f2b5389 100644 --- a/Strategic/Quest Debug System.h +++ b/Strategic/Quest Debug System.h @@ -6,7 +6,7 @@ extern BOOLEAN gfNpcLogButton; -extern INT16 gsQdsEnteringGridNo; +extern UINT16 gusQdsEnteringGridNo; void NpcRecordLoggingInit( UINT8 ubNpcID, UINT8 ubMercID, UINT8 ubQuoteNum, UINT8 ubApproach ); diff --git a/Strategic/Quests.cpp b/Strategic/Quests.cpp index 805e8a75..100167c0 100644 --- a/Strategic/Quests.cpp +++ b/Strategic/Quests.cpp @@ -27,6 +27,10 @@ #include "GameSettings.h" #include "Arms Dealer Init.h" #include "GameSettings.h" + #include "Random.h" + #include "Assignments.h" + #include "strategic.h" + #include "Strategic Event Handler.h" #endif #include "BobbyRMailOrder.h" diff --git a/Strategic/Quests.h b/Strategic/Quests.h index aa9cc38d..a4f777a7 100644 --- a/Strategic/Quests.h +++ b/Strategic/Quests.h @@ -2,6 +2,7 @@ #define __QUESTS_H #include "FileMan.h" +#include "strategicmap.h" // Quest.ubStatus values #define QUESTNOTSTARTED 0 diff --git a/Strategic/Reinforcement.cpp b/Strategic/Reinforcement.cpp index 8e7691e6..2a6bd1ab 100644 --- a/Strategic/Reinforcement.cpp +++ b/Strategic/Reinforcement.cpp @@ -20,6 +20,9 @@ #include "squads.h" #include "Soldier Create.h" #include "Dialogue Control.h" + #include "Queen Command.h" + #include "GameSettings.h" + #include "Soldier Init List.h" #endif #include "Reinforcement.h" diff --git a/Strategic/Scheduling.cpp b/Strategic/Scheduling.cpp index 714a54be..e2ad74a1 100644 --- a/Strategic/Scheduling.cpp +++ b/Strategic/Scheduling.cpp @@ -22,6 +22,12 @@ #include "Structure Wrap.h" #include "jascreens.h" #include "strategicmap.h" + #include "worldman.h" + #include "Animation Control.h" + #include "Soldier Add.h" + #include "Soldier Profile.h" + #include "soldier profile type.h" + #include "Quests.h" #endif #ifdef JA2EDITOR diff --git a/Strategic/Strategic AI.cpp b/Strategic/Strategic AI.cpp index 1f2bfafd..450b97f5 100644 --- a/Strategic/Strategic AI.cpp +++ b/Strategic/Strategic AI.cpp @@ -3,6 +3,7 @@ #include "Strategic All.h" #include "GameSettings.h" #else + #include "builddefines.h" #include #include "types.h" #include "Strategic Movement.h" @@ -20,6 +21,22 @@ #include "strategic.h" #include "Explosion Control.h" #include "Town Militia.h" + #include "Overhead.h" + #include "Squads.h" + #include "jascreens.h" + #include "screenids.h" + #include "MessageBoxScreen.h" + #include "Quests.h" + #include "Player Command.h" + #include "Campaign.h" + #include "Campaign Init.h" + #include "Game Init.h" + #include "PreBattle Interface.h" + #include "Quests.h" + #include "Soldier Profile.h" + #include "Scheduling.h" + #include "Map Information.h" + #include "interface dialogue.h" #endif #define SAI_VERSION 29 diff --git a/Strategic/Strategic All.h b/Strategic/Strategic All.h index ce390c58..cdaff001 100644 --- a/Strategic/Strategic All.h +++ b/Strategic/Strategic All.h @@ -3,6 +3,7 @@ #pragma message("GENERATED PCH FOR STRATEGIC PROJECT.") +#include "builddefines.h" #include #include "types.h" #include "english.h" diff --git a/Strategic/Strategic Event Handler.cpp b/Strategic/Strategic Event Handler.cpp index e6195ba9..fe1c5707 100644 --- a/Strategic/Strategic Event Handler.cpp +++ b/Strategic/Strategic Event Handler.cpp @@ -27,6 +27,10 @@ #include "Renderworld.h" #include "Soldier Profile.h" #include "email.h" + #include "strategic.h" + #include "structure wrap.h" + #include "GameSettings.h" + #include "history.h" #endif #include "BobbyRMailOrder.h" diff --git a/Strategic/Strategic Merc Handler.cpp b/Strategic/Strategic Merc Handler.cpp index 4cc221c6..e68ea59f 100644 --- a/Strategic/Strategic Merc Handler.cpp +++ b/Strategic/Strategic Merc Handler.cpp @@ -36,6 +36,10 @@ #include "screenids.h" #include "gameloop.h" #include "jascreens.h" + #include "Soldier macros.h" + #include "finances.h" + #include "GameSettings.h" + #include "Quests.h" #endif diff --git a/Strategic/Strategic Mines.cpp b/Strategic/Strategic Mines.cpp index 1784279f..eeb6cc58 100644 --- a/Strategic/Strategic Mines.cpp +++ b/Strategic/Strategic Mines.cpp @@ -17,6 +17,10 @@ #include "message.h" #include "Text.h" #include "Game Event Hook.h" + #include "GameSettings.h" + #include "Strategic AI.h" + #include "Campaign Types.h" + #include "history.h" #endif diff --git a/Strategic/Strategic Movement Costs.cpp b/Strategic/Strategic Movement Costs.cpp index f2d68335..e73ad147 100644 --- a/Strategic/Strategic Movement Costs.cpp +++ b/Strategic/Strategic Movement Costs.cpp @@ -6,6 +6,10 @@ #include "Queen Command.h" #include "Strategic Movement.h" #include "XML.h" + #include "expat.h" + #include "Debug.h" + #include "Debug Control.h" + #include "Tactical Save.h" #endif typedef enum diff --git a/Strategic/Strategic Movement.cpp b/Strategic/Strategic Movement.cpp index a5969681..c5137d5a 100644 --- a/Strategic/Strategic Movement.cpp +++ b/Strategic/Strategic Movement.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Strategic All.h" #else + #include "builddefines.h" #include #include #include "Strategic Movement.h" @@ -37,6 +38,15 @@ #include "Player Command.h" #include "Strategic AI.h" #include "Town Militia.h" + #include "Music Control.h" + #include "Campaign.h" + #include "Isometric Utils.h" + #include "meanwhile.h" + #include "Inventory Choosing.h" + #include "Map Screen Interface Border.h" + #include "Auto Resolve.h" + #include "GameSettings.h" + #include "Quests.h" #endif #include "MilitiaSquads.h" diff --git a/Strategic/Strategic Pathing.cpp b/Strategic/Strategic Pathing.cpp index 3d141404..5b1b6656 100644 --- a/Strategic/Strategic Pathing.cpp +++ b/Strategic/Strategic Pathing.cpp @@ -26,6 +26,7 @@ #include "english.h" #include "Map Screen Interface.h" #include "Game Event Hook.h" + #include "Strategic AI.h" #endif diff --git a/Strategic/Strategic Status.cpp b/Strategic/Strategic Status.cpp index e1bfc46e..2bc0d2bc 100644 --- a/Strategic/Strategic Status.cpp +++ b/Strategic/Strategic Status.cpp @@ -10,6 +10,12 @@ #include "Strategic Mines.h" #include "email.h" #include "Game Clock.h" + #include "TopicIDs.h" + #include "TopicOps.h" + #include "Debug.h" + #include "GameSettings.h" + #include "history.h" + #include "Strategic Town Loyalty.h" #endif diff --git a/Strategic/Strategic Town Loyalty.cpp b/Strategic/Strategic Town Loyalty.cpp index 1beeb15e..eb748df1 100644 --- a/Strategic/Strategic Town Loyalty.cpp +++ b/Strategic/Strategic Town Loyalty.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "Strategic All.h" #else @@ -22,6 +24,15 @@ #include "vehicles.h" #include "Game Clock.h" #include "Game Event Hook.h" + #include "Morale.h" + #include "GameSettings.h" + #include "Text.h" + #include "MessageBoxScreen.h" + #include "Creature Spreading.h" + #include "Town Militia.h" + #include "history.h" + #include "meanwhile.h" + #include "Strategic Status.h" #endif diff --git a/Strategic/Town Militia.cpp b/Strategic/Town Militia.cpp index a67c356c..dfcefe8e 100644 --- a/Strategic/Town Militia.cpp +++ b/Strategic/Town Militia.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "Strategic All.h" #include "GameSettings.h" @@ -22,6 +24,11 @@ #include "Soldier Create.h" #include "Dialogue Control.h" #include "GameSettings.h" + #include "Queen Command.h" + #include "PreBattle Interface.h" + #include "Map Screen Interface Border.h" + #include "interface control.h" + #include "Map Screen Interface Map.h" #endif #include "MilitiaSquads.h" diff --git a/Strategic/XML_Army.cpp b/Strategic/XML_Army.cpp index 7852b630..4fc318ba 100644 --- a/Strategic/XML_Army.cpp +++ b/Strategic/XML_Army.cpp @@ -1,9 +1,15 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "Strategic All.h" #include "XML.h" #else #include #include "XML.h" + #include "Strategic AI.h" + #include "expat.h" + #include "Campaign Types.h" + #include "Debug Control.h" #endif #define MAX_CHAR_DATA_LENGTH 500 diff --git a/Strategic/XML_Roaming.cpp b/Strategic/XML_Roaming.cpp index 94292663..cb6aeaef 100644 --- a/Strategic/XML_Roaming.cpp +++ b/Strategic/XML_Roaming.cpp @@ -2,8 +2,15 @@ #include "Strategic All.h" #include "XML.h" #else + #include "builddefines.h" #include #include "XML.h" + #include "expat.h" + #include "string.h" + #include "Campaign Types.h" + #include "FileMan.h" + #include "MemMan.h" + #include "Debug Control.h" #endif #define MAX_CHAR_DATA_LENGTH 500 diff --git a/Strategic/mapscreen.cpp b/Strategic/mapscreen.cpp index 56088ee9..4fa8a970 100644 --- a/Strategic/mapscreen.cpp +++ b/Strategic/mapscreen.cpp @@ -97,6 +97,19 @@ #include "Player Command.h" #include "Multi Language Graphic Utils.h" #include "HelpScreen.h" + #include "Soldier macros.h" + #include "Map Information.h" + #include "cheats.h" + #include "Strategic Town Loyalty.h" + #include "GameSettings.h" + #include "_Ja25EnglishText.h" + #include "Militia Control.h" + #include "Tactical Save.h" + #include "Explosion Control.h" + #include "Creature Spreading.h" + #include "email.h" + #include "Strategic Status.h" + #include "Soldier Create.h" #endif diff --git a/Strategic/strategic.cpp b/Strategic/strategic.cpp index 7c0c9a6a..de23d677 100644 --- a/Strategic/strategic.cpp +++ b/Strategic/strategic.cpp @@ -14,6 +14,8 @@ #include "personnel.h" #include "Tactical Save.h" #include "Isometric Utils.h" + #include "Vehicles.h" + #include "Game Clock.h" #endif StrategicMapElement StrategicMap[MAP_WORLD_X*MAP_WORLD_Y]; diff --git a/Strategic/strategicmap.cpp b/Strategic/strategicmap.cpp index 2cbf7a64..73fe9e56 100644 --- a/Strategic/strategicmap.cpp +++ b/Strategic/strategicmap.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + // WANNE 2 #ifdef PRECOMPILEDHEADERS #include "Strategic All.h" @@ -88,6 +90,21 @@ #include "render dirty.h" #include "Debug Control.h" #include "expat.h" + #include "Loading Screen.h" + #include "Queen Command.h" + #include "Enemy Soldier Save.h" + #include "Boxing.h" + #include "NPC.h" + #include "Strategic Event Handler.h" + #include "MessageBoxScreen.h" + #include "interface dialogue.h" + #include "Map Screen Interface.h" + #include "history.h" + #include "Bullets.h" + #include "physics.h" + #include "Explosion Control.h" + #include "Auto Resolve.h" + #include "cursors.h" #endif #include "SaveLoadGame.h" @@ -2746,7 +2763,7 @@ void UpdateMercInSector( SOLDIERTYPE *pSoldier, INT16 sSectorX, INT16 sSectorY, } // Get sector ID string makes a string like 'A9 - OMERTA', or just J11 if no town.... -void GetSectorIDString( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ , CHAR16 * zString, BOOLEAN fDetailed ) +void GetSectorIDString( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ , STR16 zString, BOOLEAN fDetailed ) { SECTORINFO *pSector = NULL; UNDERGROUND_SECTORINFO *pUnderground; diff --git a/Sys Globals.cpp b/Sys Globals.cpp index 219c42fb..5006f870 100644 --- a/Sys Globals.cpp +++ b/Sys Globals.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "JA2 All.h" #else + #include "builddefines.h" #include #include #include diff --git a/Tactical/Air Raid.cpp b/Tactical/Air Raid.cpp index 55b81465..1ca63ce9 100644 --- a/Tactical/Air Raid.cpp +++ b/Tactical/Air Raid.cpp @@ -31,6 +31,8 @@ #include "text.h" #include "Morale.h" #include "Map screen helicopter.h" + #include "structure wrap.h" + #include "meanwhile.h" #endif #define SCRIPT_DELAY 10 @@ -548,7 +550,7 @@ void AirRaidLookForDive( ) if ( giNumGridNosMovedThisTurn == 0 ) { // Free up attacker... - FreeUpAttacker( gpRaidSoldier->ubID ); + ReduceAttackBusyCount( ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Tried to free up attacker AIR RAID NO DIVE, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); } } @@ -643,6 +645,7 @@ void BeginDive( ) // Increment attacker bust count.... gTacticalStatus.ubAttackBusyCount++; DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting attack BEGIN DIVE %d", gTacticalStatus.ubAttackBusyCount) ); + DebugAttackBusy( String("!!!!!!! Starting attack BEGIN DIVE %d", gTacticalStatus.ubAttackBusyCount) ); // Pick location... DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("BeginDive: pick location")); @@ -822,7 +825,7 @@ void DoDive( ) //DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting attack AIR RAID ( fire gun ), attack count now %d", gTacticalStatus.ubAttackBusyCount) ); // INcrement bullet fired... - gpRaidSoldier->bBulletsLeft++; + // gpRaidSoldier->bBulletsLeft++; } // For now use first position.... @@ -857,7 +860,7 @@ void DoDive( ) //DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting attack AIR RAID ( second one ), attack count now %d", gTacticalStatus.ubAttackBusyCount) ); // INcrement bullet fired... - gpRaidSoldier->bBulletsLeft++; + // gpRaidSoldier->bBulletsLeft++; } @@ -872,7 +875,7 @@ void DoDive( ) if ( ( gTacticalStatus.uiFlags & INCOMBAT ) ) { // Free up attacker... - FreeUpAttacker( gpRaidSoldier->ubID ); + ReduceAttackBusyCount( ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Tried to free up attacker AIR RAID DIVE DONE FOR THIS TURN, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); } } @@ -999,6 +1002,7 @@ void DoBombing( ) // Increase attacker busy... gTacticalStatus.ubAttackBusyCount++; DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting attack AIR RAID ( bombs away ), attack count now %d", gTacticalStatus.ubAttackBusyCount) ); + DebugAttackBusy( String("!!!!!!! Starting attack AIR RAID ( bombs away ), attack count now %d", gTacticalStatus.ubAttackBusyCount) ); } // Drop bombs... @@ -1013,7 +1017,7 @@ void DoBombing( ) if ( ( gTacticalStatus.uiFlags & INCOMBAT ) ) { // Free up attacker... - FreeUpAttacker( gpRaidSoldier->ubID ); + ReduceAttackBusyCount( ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Tried to free up attacker AIR RAID BOMB ATTACK DONE FOR THIS TURN, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); } } @@ -1192,7 +1196,7 @@ void HandleAirRaid( ) if ( ( gTacticalStatus.uiFlags & INCOMBAT ) ) { // Free up attacker... - FreeUpAttacker( gpRaidSoldier->ubID ); + ReduceAttackBusyCount( ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Tried to free up attacker AIR RAID ENDING DIVE, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); } @@ -1207,7 +1211,7 @@ void HandleAirRaid( ) if ( ( gTacticalStatus.uiFlags & INCOMBAT ) ) { // Free up attacker... - FreeUpAttacker( gpRaidSoldier->ubID ); + ReduceAttackBusyCount( ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Tried to free up attacker AIR RAID ENDING DIVE, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); } @@ -1279,6 +1283,7 @@ BOOLEAN HandleAirRaidEndTurn( UINT8 ubTeam ) // Increment attacker bust count.... gTacticalStatus.ubAttackBusyCount++; DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting attack AIR RAID, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); + DebugAttackBusy( String("!!!!!!! Starting attack AIR RAID, attack count now %d\n", gTacticalStatus.ubAttackBusyCount) ); AddTopMessage( AIR_RAID_TURN_MESSAGE, TacticalStr[ AIR_RAID_TURN_STR ] ); diff --git a/Tactical/Animation Control.cpp b/Tactical/Animation Control.cpp index 7f1bffcb..a20df6bd 100644 --- a/Tactical/Animation Control.cpp +++ b/Tactical/Animation Control.cpp @@ -1,20 +1,23 @@ #ifdef PRECOMPILEDHEADERS - #include "Tactical All.h" -#else #include - #include - #include "wcheck.h" - #include "stdlib.h" - #include "debug.h" - #include "Animation Control.h" - #include "Animation Data.h" - #include "FileMan.h" - #include "weapons.h" - #include "message.h" - #include "structure.h" - #include "worlddef.h" - #include "worldman.h" - #include "rotting corpses.h" - #include "points.h" +#include "Tactical All.h" +#else +#include "builddefines.h" +#include +#include +#include "wcheck.h" +#include "stdlib.h" +#include "debug.h" +#include "Animation Control.h" +#include "Animation Data.h" +#include "FileMan.h" +#include "weapons.h" +#include "message.h" +#include "structure.h" +#include "worlddef.h" +#include "worldman.h" +#include "rotting corpses.h" +#include "points.h" +#include "Debug Control.h" #endif // Defines for Anim inst reading, taken from orig Jagged @@ -72,7 +75,7 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = //PRONE DOWN {"PRONE DOWN" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_STANCECHANGEANIM | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT, ANIM_CROUCH, ANIM_PRONE, -1}, - + //CRAWL {"CRAWL" , 0, 0, (FLOAT).8, ANIM_MOVING | ANIM_TURNING | ANIM_NORESTART | ANIM_RAISE_WEAPON | ANIM_MODERATE_EFFORT, ANIM_PRONE, ANIM_PRONE, -1}, @@ -89,7 +92,7 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"AIM (R) STAND" , 0, 250, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FIREREADY | ANIM_FASTTURN | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1}, // SHOOT_RIFLE_STAND - {"SHOOT (R) STAND" , 0, 100, (FLOAT)0, ANIM_NORESTART | ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_RT_NONINTERRUPT, ANIM_STAND, ANIM_STAND, -1}, + {"SHOOT (R) STAND" , 0, 100, (FLOAT)0, ANIM_NORESTART | ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_RT_NONINTERRUPT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, // END_RIFLE_STAND {"END RIFLE STAND" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_NOCHANGE_PENDINGCOUNT | ANIM_MIN_EFFORT, ANIM_STAND, ANIM_STAND, -1}, @@ -101,7 +104,7 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"SWAT TO CROUCH" , 0, 40, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1}, // FLYBACK HIT ANIMATION - {"FLYBACK HIT" , 0, 80, (FLOAT)1.6, ANIM_SPECIALMOVE | ANIM_HITSTART | ANIM_HITFINISH | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE, ANIM_STAND, ANIM_PRONE, -1}, + {"FLYBACK HIT" , 0, 80, (FLOAT)1.6, ANIM_SPECIALMOVE | ANIM_HITSTART | ANIM_HITFINISH | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1}, // READY_RIFLE_PRONE {"READY (R) PRONE" , 0, 150, (FLOAT)0, ANIM_OK_CHARGE_AP_FOR_TURN | ANIM_NORESTART | ANIM_STATIONARY | ANIM_TURNING| ANIM_RAISE_WEAPON | ANIM_MIN_EFFORT, ANIM_PRONE, ANIM_PRONE, -1}, @@ -110,22 +113,22 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"AIM (R) PRONE" , 0, 250, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FIREREADY | ANIM_FASTTURN| ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT, ANIM_PRONE, ANIM_PRONE, -1}, // SHOOT_RIFLE_PRONE - {"SHOOT (R) PRONE" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_RT_NONINTERRUPT, ANIM_PRONE, ANIM_PRONE, -1}, + {"SHOOT (R) PRONE" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_RT_NONINTERRUPT | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // END_RIFLE_PRONE {"END (R) AIM PRONE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_NOCHANGE_PENDINGCOUNT | ANIM_MIN_EFFORT, ANIM_PRONE, ANIM_PRONE, -1}, // DEATH TWITCH ONE - {"DEATH TWITCH ONE" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"DEATH TWITCH ONE" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // GENERIC_HIT STANDING - {"GENERIC HIT STAND" , 0, 130, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTART | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE, ANIM_STAND, ANIM_STAND, -1}, + {"GENERIC HIT STAND" , 0, 130, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTART | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, // FLYBACK HIT ANIMATION W/ BLOOD - {"FLYBACK HIT w/B" , 0, 80, (FLOAT)1.6, ANIM_SPECIALMOVE | ANIM_HITSTART | ANIM_HITFINISH | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE, ANIM_PRONE, ANIM_PRONE, -1}, + {"FLYBACK HIT w/B" , 0, 80, (FLOAT)1.6, ANIM_SPECIALMOVE | ANIM_HITSTART | ANIM_HITFINISH | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // FLYBACK HIT DEATH - {"FLYBACK HIT DEATH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"FLYBACK HIT DEATH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // READY_RIFLE_CROUCH {"READY (R) CROUCH" , 0, 150, (FLOAT)0, ANIM_OK_CHARGE_AP_FOR_TURN | ANIM_NORESTART | ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_MIN_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1}, @@ -134,13 +137,13 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"AIM (R) CROUCH" , 0, 250, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FIREREADY | ANIM_FASTTURN | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1}, // SHOOT_RIFLE_CROUCH - {"SHOOT (R) CROUCH" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_RT_NONINTERRUPT, ANIM_CROUCH, ANIM_CROUCH, -1}, + {"SHOOT (R) CROUCH" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_RT_NONINTERRUPT | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1}, // END_RIFLE_CROUCH {"END (R) CROUCH" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_NOCHANGE_PENDINGCOUNT | ANIM_MIN_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1}, // FALLBACK HIT STANDING - {"FALLBACK HIT STAND" , 0, 130, (FLOAT)1.6, ANIM_SPECIALMOVE | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE, ANIM_STAND, ANIM_PRONE, -1}, + {"FALLBACK HIT STAND" , 0, 130, (FLOAT)1.6, ANIM_SPECIALMOVE | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1}, // ROLLOVER {"ROOLOVER" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, @@ -149,7 +152,7 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"CLIMBROOF" , 0, 30, (FLOAT)0, ANIM_NONINTERRUPT | ANIM_NORESTART | ANIM_STATIONARY | ANIM_NOSHOW_MARKER | ANIM_MODERATE_EFFORT | ANIM_LOWER_WEAPON, ANIM_STAND, ANIM_CROUCH, -1}, // FALL - {"FALL" , 0, 60, (FLOAT)0, ANIM_NONINTERRUPT | ANIM_STATIONARY | ANIM_HITFINISH | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE, ANIM_STAND, ANIM_PRONE, -1}, + {"FALL" , 0, 60, (FLOAT)0, ANIM_NONINTERRUPT | ANIM_STATIONARY | ANIM_HITFINISH | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1}, //GETUP FROM ROLLOVER {"GETUP FROM ROLLOVER" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_STAND, -1}, @@ -158,58 +161,58 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"CLIMBDOWNROOF" , 0, 30, (FLOAT)0, ANIM_NONINTERRUPT | ANIM_NORESTART | ANIM_STATIONARY | ANIM_NOSHOW_MARKER | ANIM_MODERATE_EFFORT | ANIM_LOWER_WEAPON, ANIM_CROUCH, ANIM_STAND, -1}, // FALL FORWARD - {"FALL FORWARD ROOF" , 0, 60, (FLOAT)0, ANIM_NONINTERRUPT | ANIM_STATIONARY | ANIM_HITFINISH | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE, ANIM_STAND, ANIM_PRONE, -1}, + {"FALL FORWARD ROOF" , 0, 60, (FLOAT)0, ANIM_NONINTERRUPT | ANIM_STATIONARY | ANIM_HITFINISH | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1}, // GENERIC HIT DEATHTWICH NO BLOOD - {"BELLY DEATHHIT NB" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"BELLY DEATHHIT NB" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // GENERIC HIT DEATHTWICH BLOOD - {"BELLY DEATHHIT B" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"BELLY DEATHHIT B" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // FALLBACK HIT DEATHTWICH NO BLOOD - {"FALLBACK DEATHHIT NB", 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"FALLBACK DEATHHIT NB", 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // FALLBACK HIT DEATHTWICH BLOOD - {"FALLBACK DEATHHIT B" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"FALLBACK DEATHHIT B" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // GENERIC HIT DEATH - {"BELLY HIT DEATH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"BELLY HIT DEATH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // FALLBACK HIT DEATH - {"FALLBACK HIT DEATH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"FALLBACK HIT DEATH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // GENERIC HIT CROUCHED - {"GENERIC HIT CROUCH" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_CROUCH, ANIM_CROUCH, -1}, + {"GENERIC HIT CROUCH" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1}, // STAND BURST // Lesh: AniDelay, speed=0 for control it - {"STAND BURST SHOOT" , 0, 0, (FLOAT)0, ANIM_NORESTART | ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_FIRE, ANIM_STAND, ANIM_STAND, -1}, + {"STAND BURST SHOOT" , 0, 0, (FLOAT)0, ANIM_NORESTART | ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_FIRE | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, // STANDING BURST HIT - {"STAND BUTST HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE, ANIM_STAND, ANIM_STAND, -1}, + {"STAND BUTST HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, // FALL FORWARD FROM HIT STAND - {"FALL FROM STAND" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_PRONE, -1}, + {"FALL FROM STAND" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1}, // FALL FORWARD FROM HIT CROUCH - {"FALL FROM CROUCH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_CROUCH, ANIM_PRONE, -1}, + {"FALL FROM CROUCH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_CROUCH, ANIM_PRONE, -1}, // END FALL FORWARD FROM HIT CROUCH - {"END FALL F CROUCH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"END FALL F CROUCH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // GENERIC HIT PRONE - {"GENERIC HIT PRONE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"GENERIC HIT PRONE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // PRONE HIT DEATH - {"PRONE HIT DEATH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"PRONE HIT DEATH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // PRONE LAY FROM HIT - {"PRONE LAY FROM HIT" , 0, 160, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"PRONE LAY FROM HIT" , 0, 160, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // PRONE HIT DEATHTWICH NO BLOOD - {"PRONE DEATHHIT NB", 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"PRONE DEATHHIT NB", 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // PRONE HIT DEATHTWICH BLOOD - {"PRONE DEATHHIT B" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"PRONE DEATHHIT B" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // FEMALE MONSTER BREATHING {"FEMADMON BREATHING", 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1}, @@ -218,7 +221,7 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"FEMADMON WALKING", 0 , 30, (FLOAT)2.5, ANIM_MOVING | ANIM_TURNING | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1}, // FEMALE MONSTER ATTACK - {"FEMADMON ATTACK", 0 , 70, (FLOAT)2.5, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1}, + {"FEMADMON ATTACK", 0 , 70, (FLOAT)2.5, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, {"FLYBACK HIT DEATH STOP" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, @@ -243,10 +246,10 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"HOP FENCE" , 0, 50, (FLOAT)0, ANIM_NOCHANGE_PENDINGCOUNT | ANIM_NORESTART | ANIM_STATIONARY | ANIM_NOSHOW_MARKER | ANIM_MODERATE_EFFORT | ANIM_LOWER_WEAPON | ANIM_NONINTERRUPT, ANIM_STAND, ANIM_CROUCH, -1}, // GENERIC HIT CROUCHED - {"FEMMONS HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1}, + {"FEMMONS HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, // FALL FORWARD FROM HIT STAND - {"FEMMONS DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_PRONE, -1}, + {"FEMMONS DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1}, // FALL FORWARD FROM HIT STAND {"FEMMONS DIE STOP" , 0, 350, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, @@ -255,45 +258,45 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"PUNCH BREATH" , 0, 150, (FLOAT)0, ANIM_NORESTART | ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1}, // Punch - {"PUNCH" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NORESTART, ANIM_STAND, ANIM_STAND, -1}, + {"PUNCH" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NORESTART | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, //Breathing {"NOTHING_STAND" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1}, // JFK HIT DEATH - {"JFK HIT DEATH" , 0, 160, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_HITSTART | ANIM_HITFINISH | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_PRONE, -1}, + {"JFK HIT DEATH" , 0, 160, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_HITSTART | ANIM_HITFINISH | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1}, {"JFK HIT DEATH STOP" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, - {"JFK DEATHHIT B" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"JFK DEATHHIT B" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // STAND BURST // Lesh: AniDelay, speed=0 for control it - {"STAND BURST SPREAD" , 0, 0, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1}, + {"STAND BURST SPREAD" , 0, 0, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, // FALLOFF DEATH - {"FALLOFF DEATH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"FALLOFF DEATH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, - // FALLOFF DEATH STOP + // FALLOFF DEATH STOP {"FALLOFF DEATH STOP" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, - // FALLOFF TWITCHB - {"FALLOFF TWITCH BLOOD" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + // FALLOFF TWITCHB + {"FALLOFF TWITCH BLOOD" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, - // FALLOFF TWITCH NB - {"FALLOFF TWITCH NOBLOOD" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + // FALLOFF TWITCH NB + {"FALLOFF TWITCH NOBLOOD" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, // FALLOFF FORWARD DEATH - {"FALLOFF FORWARD DEATH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + {"FALLOFF FORWARD DEATH" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, - // FALLOFF FORWARD DEATH STOP + // FALLOFF FORWARD DEATH STOP {"FALLOFF FORWARD DEATH STOP" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, - // FALLOFF FORWARD TWITCHB - {"FALLOFF FORWARD TWITCH BLOOD" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + // FALLOFF FORWARD TWITCHB + {"FALLOFF FORWARD TWITCH BLOOD" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, - // FALLOFF TWITCH NB - {"FALLOFF FORWARD TWITCH NOBLOOD" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, + // FALLOFF TWITCH NB + {"FALLOFF FORWARD TWITCH NOBLOOD" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_HITWHENDOWN | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, //OPEN DOOR {"OPEN DOOR" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1}, @@ -308,13 +311,13 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"DROP ITEM" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1}, //SLICE - {"SLICE" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT , ANIM_STAND, ANIM_STAND, -1}, + {"SLICE" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_ATTACK , ANIM_STAND, ANIM_STAND, -1}, //STAB - {"STAB" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT , ANIM_STAND, ANIM_STAND, -1}, + {"STAB" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_ATTACK , ANIM_STAND, ANIM_STAND, -1}, //CROUCH STAB - {"CROUCH STAB" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT , ANIM_CROUCH, ANIM_CROUCH, -1}, + {"CROUCH STAB" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_ATTACK , ANIM_CROUCH, ANIM_CROUCH, -1}, //START GIVING AID {"START AID" , 0, 90, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT , ANIM_CROUCH, ANIM_CROUCH, -1}, @@ -326,7 +329,7 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"END AID" , 0, 90, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_RAISE_WEAPON | ANIM_NO_EFFORT | ANIM_NOCHANGE_PENDINGCOUNT, ANIM_CROUCH, ANIM_CROUCH, -1}, //DODGE ONE - {"DODGE ONE" , 0, 40, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1}, + {"DODGE ONE" , 0, 40, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, //FATCIV_ASSSCRATCH {"FATCIV ASS SCRATCH" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1}, @@ -338,7 +341,7 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"AIM (DW) STAND" , 0, 250, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FIREREADY | ANIM_FASTTURN | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1}, // SHOOT_RIFLE_STAND - {"SHOOT (DW) STAND" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT | ANIM_FIRE, ANIM_STAND, ANIM_STAND, -1}, + {"SHOOT (DW) STAND" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, // END_RIFLE_STAND {"END DUAL STAND" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NOCHANGE_PENDINGCOUNT | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1}, @@ -350,23 +353,23 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"LOWER RIFLE" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_NOCHANGE_WEAPON | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1}, //BOD BLOW - {"BOD BLOW" , 0, 200, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NONINTERRUPT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE, ANIM_STAND, ANIM_STAND, -1}, + {"BOD BLOW" , 0, 200, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NONINTERRUPT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, //THROW ITEM - {"THROW ITEM" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_NONINTERRUPT | ANIM_MIN_EFFORT , ANIM_STAND, ANIM_STAND, -1}, + {"THROW ITEM" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_NONINTERRUPT | ANIM_MIN_EFFORT | ANIM_ATTACK , ANIM_STAND, ANIM_STAND, -1}, //LOB ITEM - {"LOB ITEM" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_NONINTERRUPT | ANIM_MIN_EFFORT , ANIM_STAND, ANIM_STAND, -1}, + {"LOB ITEM" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_NONINTERRUPT | ANIM_MIN_EFFORT | ANIM_ATTACK , ANIM_STAND, ANIM_STAND, -1}, //QUEEN MONSTER STATIONARY {"MONSTER_STATIONARY" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_BREATH, ANIM_STAND, ANIM_STAND, -1}, // CROUCHED BURST // Lesh: AniDelay, speed=0 for control it - {"CROUCHED BURST SHOOT" , 0, 0, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT | ANIM_FIRE, ANIM_CROUCH, ANIM_CROUCH, -1}, + {"CROUCHED BURST SHOOT" , 0, 0, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1}, // PRONE BURST // Lesh: AniDelay, speed=0 for control it - {"PRONE BURST SHOOT" , 0, 0, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT | ANIM_FIRE, ANIM_PRONE, ANIM_PRONE, -1}, -//180 + {"PRONE BURST SHOOT" , 0, 0, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1}, + //180 {"NOT USED 1" , 20, 20, (FLOAT)0.9, ANIM_MOVING | ANIM_TURNING | ANIM_NORESTART | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1}, // BIG GUY FLEX @@ -385,7 +388,7 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"MINI GIRL STOCKING" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1}, //GIVE ITEM - {"GIVE ITEM" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT , ANIM_STAND, ANIM_STAND, -1}, + {"GIVE ITEM" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT | ANIM_ATTACK , ANIM_STAND, ANIM_STAND, -1}, //CLIMB MOUNTIAIN {"CLIMB MOUNTAIN" , 0, 50, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NOSHOW_MARKER | ANIM_MODERATE_EFFORT, ANIM_STAND, ANIM_CROUCH, -1}, @@ -393,19 +396,19 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"COW EATING" , 0, 200, (FLOAT)0.0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1}, // COW HIT - {"COW HIT" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1}, + {"COW HIT" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, // COW DIE - {"COW DIE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT, ANIM_STAND, ANIM_PRONE, -1}, + {"COW DIE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1}, // COW DIE STOP {"COW DIE STOP" , 0, 350, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NO_EFFORT, ANIM_PRONE, ANIM_PRONE, -1}, // WATER HIT - {"WATER HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1}, + {"WATER HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, // WATER DIE - {"WATER DIE" , 0, 160, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_PRONE, -1}, + {"WATER DIE" , 0, 160, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1}, // WATER DIE STOP {"WATER DIE STOP" , 0, 340, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1}, @@ -420,7 +423,7 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"CROW EAT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_MIN_EFFORT, ANIM_STAND, ANIM_STAND, -1}, - {"HELIDROP" , 0, 60, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT, ANIM_STAND, ANIM_CROUCH, -1}, + {"HELIDROP" , 0, 60, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_CROUCH, -1}, {"FEM CLEAN" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_MERCIDLE | ANIM_NOCHANGE_WEAPON | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1}, @@ -440,9 +443,9 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = {"KID ARMPIT" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1}, - {"ADULT MONSTER CLOSE ATTACK", 0 , 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1}, + {"ADULT MONSTER CLOSE ATTACK", 0 , 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1}, - "ADULT MONSTER SPIT ATTACK", 0 , 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, + "ADULT MONSTER SPIT ATTACK", 0 , 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, "ADULT MONSTER BEGIN EATING", 0 , 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1, @@ -461,25 +464,25 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "BLOODCAT END READY" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1, // CAT HIT - "BLOODCAT HIT" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1, + "BLOODCAT HIT" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // CAT DIE - "BLOODCAT DIE" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER, ANIM_STAND, ANIM_PRONE, -1, + "BLOODCAT DIE" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1, // CAT DIE STOP "BLOODCAT DIE STOP" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NO_EFFORT, ANIM_PRONE, ANIM_PRONE, -1, - "BLOODCAT SWIPE" , 0 , 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_MIN_EFFORT, ANIM_STAND, ANIM_STAND, -1, + "BLOODCAT SWIPE" , 0 , 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_MIN_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, "NINJA GOTO BREATH" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, "NINJA BREATH" , 0, 0, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, - "NINJA LOWKICK" , 0, 50, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NORESTART, ANIM_STAND, ANIM_STAND, -1, + "NINJA LOWKICK" , 0, 50, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NORESTART | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, - "NINJA PUNCH" , 0, 50, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NORESTART, ANIM_STAND, ANIM_STAND, -1, + "NINJA PUNCH" , 0, 50, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NORESTART | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, - "NINJA SPIN KICK" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_MODERATE_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NORESTART, ANIM_STAND, ANIM_STAND, -1, + "NINJA SPIN KICK" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_MODERATE_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NORESTART | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //END OPEN DOOR "END OPEN DOOR" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_MIN_EFFORT, ANIM_STAND, ANIM_STAND, -1, @@ -488,13 +491,13 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "END OPEN LOCKED DOOR" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LOWER_WEAPON | ANIM_MIN_EFFORT, ANIM_STAND, ANIM_STAND, -1, //KICK DOOR - "KICK DOOR" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1, + "KICK DOOR" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //KICK DOOR "CLOSE DOOR" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_MIN_EFFORT, ANIM_STAND, ANIM_STAND, -1, // HIT STANDING RIFLE - "HIT STAND RIFLE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTART | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_NOCHANGE_WEAPON | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1, + "HIT STAND RIFLE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTART | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_NOCHANGE_WEAPON | ANIM_NO_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // DEEP WATER TREAD "DEEP WATER TREAD" , 0, 200, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NOCHANGE_WEAPON | ANIM_MODERATE_EFFORT, ANIM_STAND, ANIM_STAND, -1, @@ -503,10 +506,10 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "DEEP WATER SWIM" , 0, 160, (FLOAT)1.3, ANIM_MOVING | ANIM_TURNING | ANIM_NORESTART | ANIM_NOCHANGE_WEAPON | ANIM_MODERATE_EFFORT, ANIM_STAND, ANIM_STAND, -1, // DEEP WATER HIT - "DEEP WATER HIT" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1, + "DEEP WATER HIT" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // DEEP WATER DIE - "DEEP WATER DIE" , 0, 210, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_PRONE, -1, + "DEEP WATER DIE" , 0, 210, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1, // DEEP WATER DIE STOPPING "DEEP WATER DIE STOPPING" , 0, 340, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_HITSTOP | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1, @@ -530,19 +533,19 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "WAKEUP" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_RAISE_WEAPON | ANIM_NO_EFFORT, ANIM_PRONE, ANIM_CROUCH, -1, // SHOOT_RIFLE_STAND LOW - "SHOOT (R) STAND LOW" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE, ANIM_STAND, ANIM_STAND, -1, + "SHOOT (R) STAND LOW" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // SHOOT_RIFLE_STAND LOW // Lesh: AniDelay, speed=0 for control it - "BURST SHOOT (R) STAND LOW" , 0, 0, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE, ANIM_STAND, ANIM_STAND, -1, + "BURST SHOOT (R) STAND LOW" , 0, 0, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //LARVAE Breathing "LARVAE BREATH" , 0, 250, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, // GENERIC HIT CROUCHED - "LARVAE HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, + "LARVAE HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // FALL FORWARD FROM HIT STAND - "LARVAE DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_PRONE, -1, + "LARVAE DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1, // FALL FORWARD FROM HIT STAND "LARVAE DIE STOP" , 0, 350, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1, @@ -551,15 +554,15 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "LARVAE WALKING" , 0 , 110, (FLOAT)0.5, ANIM_MOVING | ANIM_TURNING | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, // GENERIC HIT CROUCHED - "INFANT HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, + "INFANT HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // FALL FORWARD FROM HIT STAND - "INFANT DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_PRONE, -1, + "INFANT DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1, // FALL FORWARD FROM HIT STAND "INFANT DIE STOP" , 0, 350, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1, - "INFANT MONSTER SPIT ATTACK", 0 , 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, + "INFANT MONSTER SPIT ATTACK", 0 , 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, "INFANT MONSTER BEGIN EATING", 0 , 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, @@ -572,19 +575,19 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "ADULT MONSTER JUMP", 0 , 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, // UNJAM STANDING - "UNJAM STANDING" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT , ANIM_STAND, ANIM_STAND, -1, + "UNJAM STANDING" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // UNJAM CROUCH - "UNJAM CROUCH" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT , ANIM_CROUCH, ANIM_CROUCH, -1, + "UNJAM CROUCH" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1, // UNJAM PRONE - "UNJAM PRONE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT , ANIM_PRONE, ANIM_PRONE, -1, + "UNJAM PRONE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1, // UNJAM STAND DWEL - "UNJAM STAND DWEL" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT , ANIM_STAND, ANIM_STAND, -1, + "UNJAM STAND DWEL" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // UNJAM STAND LOW - "UNJAM STAND LOW" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT , ANIM_STAND, ANIM_STAND, -1, + "UNJAM STAND LOW" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // READY_RIFLE_CROUCH "READY AIM (DW) CROUCH" , 0, 150, (FLOAT)0, ANIM_OK_CHARGE_AP_FOR_TURN | ANIM_NORESTART | ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_LIGHT_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1, @@ -593,72 +596,72 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "AIM (DW) CROUCH" , 0, 250, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FIREREADY | ANIM_FASTTURN | ANIM_LIGHT_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1, // SHOOT_RIFLE_CROUCH - "SHOOT (DW) CROUCH" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT | ANIM_FIRE, ANIM_CROUCH, ANIM_CROUCH, -1, + "SHOOT (DW) CROUCH" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1, // END_RIFLE_STAND "END DUAL CROUCH" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NOCHANGE_PENDINGCOUNT | ANIM_LIGHT_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1, // UNJAM CROUCH DWEL - "UNJAM CROUCH DWEL" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT , ANIM_CROUCH, ANIM_CROUCH, -1, + "UNJAM CROUCH DWEL" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1, //GET ADJACENT ITEM "GET ADJACENT ITEM" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1, //CUTTING FENCE - "CUTTING FENCE" , 0, 90, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT , ANIM_CROUCH, ANIM_CROUCH, -1, + "CUTTING FENCE" , 0, 90, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1, "CRIPPLE BEG" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_MERCIDLE | ANIM_NOCHANGE_WEAPON | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1, // CRIPPLE HIT - "CRIPPLE HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, + "CRIPPLE HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // CRIPPLE DIE - "CRIPPLE DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_PRONE, -1, + "CRIPPLE DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1, // CRIPPLE DIE STOP "CRIPPLE DIE STOP" , 0, 350, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1, // CRIPPLE FLYBACK DIE - "CRIPPLE FLYBACK DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_PRONE, -1, + "CRIPPLE FLYBACK DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1, // CRIPPLE FLYBACK DIE STOP "CRIPPLE FLYBACK DIE STOP" , 0, 350, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1, // CRIPPLE KICK - "CRIPPLE KICK" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_NOMOVE_MARKER | ANIM_MIN_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, + "CRIPPLE KICK" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_NOMOVE_MARKER | ANIM_MIN_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // INJURED TRANSITION "INJURED TRANSITION" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_NOMOVE_MARKER | ANIM_MIN_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, //THROW KNIFE - "THROW KNIFE" , 0, 50, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_NONINTERRUPT | ANIM_MIN_EFFORT , ANIM_STAND, ANIM_STAND, -1, + "THROW KNIFE" , 0, 50, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_NONINTERRUPT | ANIM_MIN_EFFORT | ANIM_ATTACK , ANIM_STAND, ANIM_STAND, -1, //Breathing "KNIFE BREATH" , 0, 150, (FLOAT)0, ANIM_NORESTART | ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, //Breathing - "KNIFE GOTO BREATH" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NONINTERRUPT, ANIM_STAND, ANIM_STAND, -1, + "KNIFE GOTO BREATH" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NONINTERRUPT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //Breathing "KNIFE END BREATH" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NONINTERRUPT, ANIM_STAND, ANIM_STAND, -1, // ROBOT HIT - "ROBOT HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, + "ROBOT HIT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NONINTERRUPT | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // ROBOT DIE - "ROBOT DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_PRONE, -1, + "ROBOT DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1, // ROBOT DIE STOP "ROBOT DIE STOP" , 0, 350, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1, //Catch Standing - "Catch Standing" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_LOWER_WEAPON, ANIM_STAND, ANIM_STAND, -1, + "Catch Standing" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_LOWER_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //Catch Crouched - "Catch Crouched" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_LOWER_WEAPON, ANIM_CROUCH, ANIM_CROUCH, -1, + "Catch Crouched" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_LOWER_WEAPON | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1, //PLANT BOMB - "PLANT BOMB" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1, + "PLANT BOMB" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //Use remote "Use Remote" , 0, 80, (FLOAT)0, ANIM_NORESTART | ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NONINTERRUPT, ANIM_STAND, ANIM_STAND, -1, @@ -673,19 +676,19 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "End Cower" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE, ANIM_CROUCH, ANIM_STAND, -1, //STEAL ITEM - "STEAL ITEM" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT , ANIM_STAND, ANIM_STAND, -1, + "STEAL ITEM" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT | ANIM_ATTACK , ANIM_STAND, ANIM_STAND, -1, //LAUNCH ROCKET - "LAUNCH ROCKET" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT , ANIM_STAND, ANIM_STAND, -1, + "LAUNCH ROCKET" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_ATTACK , ANIM_STAND, ANIM_STAND, -1, // CIV ALT DIE - "CIV ALT DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_PRONE, -1, + "CIV ALT DIE" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1, //SHOOT MORTAR - "SHOOT MORTAR" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT , ANIM_CROUCH, ANIM_CROUCH, -1, + "SHOOT MORTAR" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT | ANIM_ATTACK , ANIM_CROUCH, ANIM_CROUCH, -1, //CROW DIE - "CROW_DIE" , 0, 130, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NOCHANGE_WEAPON | ANIM_LIGHT_EFFORT , ANIM_STAND, ANIM_STAND, -1, + "CROW_DIE" , 0, 130, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NOCHANGE_WEAPON | ANIM_LIGHT_EFFORT , ANIM_STAND, ANIM_STAND, -1, //SIDE STEPPING "SIDE STEPPING" , 0, 50, (FLOAT)0.4, ANIM_MOVING | ANIM_NORESTART | ANIM_RAISE_WEAPON | ANIM_VARIABLE_EFFORT, ANIM_STAND, ANIM_STAND, -1, @@ -703,15 +706,15 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "END OPEN LOCKED STRUCT" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1, // Punch LOw - "LOW PUNCH" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_CROUCH, ANIM_CROUCH, -1, + "LOW PUNCH" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1, // SHOOT_PISTOL_STAND LOW - "SHOOT (P) STAND LOW" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE, ANIM_STAND, ANIM_STAND, -1, + "SHOOT (P) STAND LOW" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //DECAPITATE - "DECAPITATE" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NONINTERRUPT, ANIM_CROUCH, ANIM_CROUCH, -1, + "DECAPITATE" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NONINTERRUPT | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1, - "BLOODCAT BITE" , 0 , 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_MIN_EFFORT, ANIM_STAND, ANIM_STAND, -1, + "BLOODCAT BITE" , 0 , 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_MIN_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, "BIGMERC S NECK" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_MERCIDLE | ANIM_NOCHANGE_WEAPON | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1, @@ -746,19 +749,19 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "END REPAIRMAN" , 0, 90, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_RAISE_WEAPON | ANIM_NO_EFFORT | ANIM_NOCHANGE_PENDINGCOUNT, ANIM_CROUCH, ANIM_CROUCH, -1, //FALL INTO PIT - "FALL INTO PIT" , 0, 60, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_PRONE, -1, + "FALL INTO PIT" , 0, 60, (FLOAT)0, ANIM_STATIONARY | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1, // ROBOT WALK "ROBOT WALKING" , 0 , 80, (FLOAT)1.5, ANIM_MOVING | ANIM_TURNING | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, // ROBOT SHOOT - "ROBOT SHOOT" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE, ANIM_STAND, ANIM_STAND, -1, + "ROBOT SHOOT" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // QUEEN HIT - "QUEEN HIT" , 0, 200, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, + "QUEEN HIT" , 0, 200, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITSTART | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // QUEEN DIE - "QUEEN DIE" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_PRONE, -1, + "QUEEN DIE" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_PRONE, -1, // QUEEN DIE STOP "QUEEN DIE STOP" , 0, 350, (FLOAT)0, ANIM_STATIONARY | ANIM_HITSTOP | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1, @@ -769,54 +772,54 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "QUEEN END READY" , 0, 130, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1, - "QUEEN CALL" , 0, 130, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1, + "QUEEN CALL" , 0, 130, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NO_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, - "QUEEN MONSTER SPIT ATTACK", 0 , 130, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, + "QUEEN MONSTER SPIT ATTACK", 0 , 130, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, - "QUEEN MONSTER SWIPE ATTACK", 0 , 130, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, + "QUEEN MONSTER SWIPE ATTACK", 0 , 130, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //RELOAD ROBOT - "RELOAD ROBOT" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1, + "RELOAD ROBOT" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1, //End Catch Standing - "Catch Standing" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NONINTERRUPT, ANIM_STAND, ANIM_STAND, -1, + "Catch Standing" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NONINTERRUPT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //End Catch Crouched - "Catch Crouched" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NONINTERRUPT, ANIM_CROUCH, ANIM_CROUCH, -1, + "Catch Crouched" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_FIREREADY | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NONINTERRUPT | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1, - "RADIO" , 0, 130, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1, + "RADIO" , 0, 130, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NO_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, - "CROUCH RADIO" , 0, 130, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NO_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1, + "CROUCH RADIO" , 0, 130, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NORESTART | ANIM_NO_EFFORT | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1, // TANK SHOOT - "TANK SHOOT" , 0, 200, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NOCHANGE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE, ANIM_STAND, ANIM_STAND, -1, + "TANK SHOOT" , 0, 200, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NOCHANGE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // TANK SHOOT // Lesh: AniDelay, speed=0 for control it - "TANK BURST" , 0, 0, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NOCHANGE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE, ANIM_STAND, ANIM_STAND, -1, + "TANK BURST" , 0, 0, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NOCHANGE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //Queen Slap - "QUEEN SLAP" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, + "QUEEN SLAP" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, - //Slap hit - "SLAP HIT" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, + //Slap hit + "SLAP HIT" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //GET BLOOD "GET BLOOD" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1, //VEHICLE DIE - "VEHICLE DIE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_NOCHANGE_WEAPON | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1, + "VEHICLE DIE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_NOCHANGE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //Queen Frustrated Slap - "QUEEN FRUSTRATED SLAP" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, + "QUEEN FRUSTRATED SLAP" , 0, 120, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //SOLDIER BRUN - "FIRE FIRE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_NOCHANGE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_IGNORE_AUTOSTANCE, ANIM_STAND, ANIM_STAND, -1, + "FIRE FIRE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_NOCHANGE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_IGNORE_AUTOSTANCE | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //AI TRIGGER "AI TRIGGER" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1, // MONSTER MELT - "MONSTERMELT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_PRONE, ANIM_PRONE, -1, + "MONSTERMELT" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NONINTERRUPT | ANIM_HITFINISH | ANIM_NOMOVE_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1, "MERC INJURED IDLE ANIM" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_MERCIDLE | ANIM_NOCHANGE_WEAPON | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1, @@ -824,10 +827,10 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "END INJURED WALK" , 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NOMOVE_MARKER | ANIM_MIN_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, //PASS OBJECT - "PASS OBJECT" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT , ANIM_STAND, ANIM_STAND, -1, + "PASS OBJECT" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT | ANIM_ATTACK , ANIM_STAND, ANIM_STAND, -1, //ADJACENT DROP OBJECT - "ADJACENT DROP OBJECT" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT , ANIM_STAND, ANIM_STAND, -1, + "ADJACENT DROP OBJECT" , 0, 110, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT | ANIM_ATTACK , ANIM_STAND, ANIM_STAND, -1, // READY_RIFLE_PRONE "READY AIM (DW) PRONE" , 0, 150, (FLOAT)0, ANIM_NORESTART | ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_LIGHT_EFFORT, ANIM_PRONE, ANIM_PRONE, -1, @@ -836,16 +839,16 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "AIM (DW) PRONE" , 0, 250, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FIREREADY | ANIM_FASTTURN | ANIM_LIGHT_EFFORT, ANIM_PRONE, ANIM_PRONE, -1, // SHOOT_RIFLE_PRONE - "SHOOT (DW) PRONE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT | ANIM_FIRE, ANIM_PRONE, ANIM_PRONE, -1, + "SHOOT (DW) PRONE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_LIGHT_EFFORT | ANIM_FIRE | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1, // END_RIFLE_PRONE "END DUAL PRONE" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NOCHANGE_PENDINGCOUNT | ANIM_LIGHT_EFFORT, ANIM_PRONE, ANIM_PRONE, -1, // UNJAM PRONE DWEL - "UNJAM PRONE DWEL" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT , ANIM_PRONE, ANIM_PRONE, -1, + "UNJAM PRONE DWEL" , 0, 150, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NOCHANGE_WEAPON | ANIM_MIN_EFFORT | ANIM_ATTACK, ANIM_PRONE, ANIM_PRONE, -1, //PICK LOCK - "PICK LOCK" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1, + "PICK LOCK" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //OPEN DOOR CROUCHED "OPEN DOOR CROUCHED" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1, @@ -874,10 +877,10 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "DRUNK IDLE" , 0, 170, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_MERCIDLE | ANIM_NOCHANGE_WEAPON | ANIM_NO_EFFORT, ANIM_STAND, ANIM_STAND, -1, // CROWBAR - "CROWBAR" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NORESTART, ANIM_STAND, ANIM_STAND, -1, + "CROWBAR" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_NORESTART | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, // COWER HIT ANIMATION - "COWER HIT" , 0, 80, (FLOAT)1.6, ANIM_HITSTART | ANIM_HITFINISH | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE, ANIM_CROUCH, ANIM_CROUCH, -1, + "COWER HIT" , 0, 80, (FLOAT)1.6, ANIM_HITSTART | ANIM_HITFINISH | ANIM_NONINTERRUPT | ANIM_NOSHOW_MARKER | ANIM_NO_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_IGNORE_AUTOSTANCE | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1, // BLOODCAT WALK BACKWARDS "BLOODCAT WALKING BACKWARDS", 0 , 30, (FLOAT)1.2, ANIM_MOVING | ANIM_TURNING | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, @@ -889,16 +892,16 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "KID SKIPPING", 0 , 70, (FLOAT)2.0, ANIM_MOVING | ANIM_TURNING | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON, ANIM_STAND, ANIM_STAND, -1, // STAND BURST // Lesh: AniDelay, speed=0 for control it - "STAND BURST SHOOT" , 0, 0, (FLOAT)0, ANIM_NORESTART | ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_FIRE, ANIM_STAND, ANIM_STAND, -1, + "STAND BURST SHOOT" , 0, 0, (FLOAT)0, ANIM_NORESTART | ANIM_STATIONARY | ANIM_TURNING | ANIM_RAISE_WEAPON | ANIM_LIGHT_EFFORT | ANIM_NOCHANGE_WEAPON | ANIM_FIRE | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //Attach string - "Attach String" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1, + "Attach String" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1, //SWAT BACKWARDS "SWAT BACKWARDS" , 0, 110, (FLOAT)1.4, ANIM_MOVING | ANIM_NORESTART | ANIM_LIGHT_EFFORT | ANIM_TURNING, ANIM_CROUCH, ANIM_CROUCH, -1, - - //JUMP OVER BLOCKING PERSON - "JUMP OVER" , 0, 110, (FLOAT)3.6, ANIM_SPECIALMOVE | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_MODERATE_EFFORT | ANIM_TURNING, ANIM_STAND, ANIM_STAND, -1, + + //JUMP OVER BLOCKING PERSON + "JUMP OVER" , 0, 110, (FLOAT)3.6, ANIM_SPECIALMOVE | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_MODERATE_EFFORT | ANIM_TURNING | ANIM_ATTACK, ANIM_STAND, ANIM_STAND, -1, //REFUEL VEHICLE "REFUEL VEHICLE" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_NONINTERRUPT | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1, @@ -909,7 +912,7 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = //CRIPPLE OPEN DOOR "CRIPPLE OPEN DOOR" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LIGHT_EFFORT, ANIM_STAND, ANIM_STAND, -1, - //CRIPPLE CLOSE DOOR + //CRIPPLE CLOSE DOOR "CRIPPLE CLOSE DOOR" , 0, 100, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_MIN_EFFORT, ANIM_STAND, ANIM_STAND, -1, //CRIPPLE END OPEN DOOR @@ -922,7 +925,7 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] = "CROUCH PICK LOCK" , 0, 70, (FLOAT)0, ANIM_STATIONARY | ANIM_TURNING | ANIM_FASTTURN | ANIM_NORESTART | ANIM_LOWER_WEAPON | ANIM_LIGHT_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1, // crouch throwing - "THROW ITEM CROUCHED", 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_NONINTERRUPT | ANIM_MIN_EFFORT, ANIM_CROUCH, ANIM_CROUCH, -1, + "THROW ITEM CROUCHED", 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_NONINTERRUPT | ANIM_MIN_EFFORT | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1, // crouch throwing gubAnimSurfaceIndex[ REGMALE ][ THROW_ITEM_CROUCHED ] = RGMCRTHROW; // @@ -1420,7 +1423,7 @@ void InitAnimationSurfacesPerBodytype( ) gubAnimSurfaceItemSubIndex[ REGMALE ][ END_HURT_WALKING ] = RGMHURTSTANDINGN; gubAnimSurfaceItemSubIndex[ REGMALE ][ WALK_BACKWARDS ] = RGMNOTHING_WALK; gubAnimSurfaceItemSubIndex[ REGMALE ][ DRUNK_IDLE ] = RGMPISTOLDRUNK; - + gubAnimSurfaceCorpseID[ REGMALE ][ GENERIC_HIT_DEATH ] = SMERC_FWD; gubAnimSurfaceCorpseID[ REGMALE ][ FALLBACK_HIT_DEATH ] = SMERC_BCK; @@ -2427,7 +2430,7 @@ void InitAnimationSurfacesPerBodytype( ) gubAnimSurfaceItemSubIndex[ REGFEMALE ][ END_HURT_WALKING ] = RGFHURTSTANDINGN; gubAnimSurfaceItemSubIndex[ REGFEMALE ][ WALK_BACKWARDS ] = RGFNOTHING_WALK; gubAnimSurfaceItemSubIndex[ REGFEMALE ][ DRUNK_IDLE ] = RGMPISTOLDRUNK; - + gubAnimSurfaceMidWaterSubIndex[ REGFEMALE ][ STANDING][0] = RGFWATER_R_STD; gubAnimSurfaceMidWaterSubIndex[ REGFEMALE ][ WALKING ][0] = RGFWATER_R_WALK; @@ -2483,7 +2486,7 @@ void InitAnimationSurfacesPerBodytype( ) gubAnimSurfaceCorpseID[ REGFEMALE ][ PRONE_LAYFROMHIT_STOP ] = FMERC_PRN; gubAnimSurfaceCorpseID[ REGFEMALE ][ CHARIOTS_OF_FIRE ] = BURNT_DEAD; gubAnimSurfaceCorpseID[ REGFEMALE ][ BODYEXPLODING ] = EXPLODE_DEAD; - + //Setup some random stuff gRandomAnimDefs[ REGFEMALE ][ 0 ].ubHandRestriction = RANDOM_ANIM_RIFLEINHAND; @@ -2636,7 +2639,7 @@ void InitAnimationSurfacesPerBodytype( ) gubAnimSurfaceCorpseID[ INFANT_MONSTER ][ INFANT_DIE ] = INFANTMONSTER_DEAD; - + gubAnimSurfaceIndex[ QUEENMONSTER ][ QUEEN_MONSTER_BREATHING ] = QUEENMONSTERSTANDING; gubAnimSurfaceIndex[ QUEENMONSTER ][ QUEEN_HIT ] = QUEENMONSTERDEATH; gubAnimSurfaceIndex[ QUEENMONSTER ][ QUEEN_DIE ] = QUEENMONSTERDEATH; @@ -2676,7 +2679,7 @@ void InitAnimationSurfacesPerBodytype( ) gubAnimSurfaceIndex[ FATCIV ][ END_COWER ] = FATMANCOWER; gubAnimSurfaceIndex[ FATCIV ][ CIV_DIE2 ] = FATMANDIE2; gubAnimSurfaceIndex[ FATCIV ][ CIV_COWER_HIT ] = FATMANCOWERHIT; - + gubAnimSurfaceCorpseID[ FATCIV ][ GENERIC_HIT_DEATH ] = FT_DEAD1; gubAnimSurfaceCorpseID[ FATCIV ][ CIV_DIE2 ] = FT_DEAD2; @@ -3008,12 +3011,12 @@ void InitAnimationSurfacesPerBodytype( ) gubAnimSurfaceIndex[ TANK_NE ][ TANK_BURST ] = TANKNE_SHOOT; gubAnimSurfaceIndex[ TANK_NE ][ VEHICLE_DIE ] = TANKNE_DIE; gubAnimSurfaceCorpseID[ TANK_NE ][ STANDING ] = TANK2_DEAD; - + // ELDORADO gubAnimSurfaceIndex[ ELDORADO ][ STANDING ] = ELDORADO_BASIC; gubAnimSurfaceIndex[ ELDORADO ][ WALKING ] = ELDORADO_BASIC; gubAnimSurfaceIndex[ ELDORADO ][ VEHICLE_DIE ] = ELDORADO_DIE; - + // ICECREAMTRUCK gubAnimSurfaceIndex[ ICECREAMTRUCK ][ STANDING ] = ICECREAMTRUCK_BASIC; gubAnimSurfaceIndex[ ICECREAMTRUCK ][ WALKING ] = ICECREAMTRUCK_BASIC; @@ -3028,30 +3031,30 @@ void InitAnimationSurfacesPerBodytype( ) BOOLEAN LoadAnimationStateInstructions( ) { - HWFILE hFile; - UINT32 uiBytesRead; + HWFILE hFile; + UINT32 uiBytesRead; - // Open ani file - hFile = FileOpen( ANIMFILENAME, FILE_ACCESS_READ, FALSE ); + // Open ani file + hFile = FileOpen( ANIMFILENAME, FILE_ACCESS_READ, FALSE ); - if ( !hFile ) - { - return( FALSE ); - } + if ( !hFile ) + { + return( FALSE ); + } - //Read in block - if ( !FileRead( hFile, gusAnimInst, sizeof( gusAnimInst ), &uiBytesRead ) ) - { - return( FALSE ); - } + //Read in block + if ( !FileRead( hFile, gusAnimInst, sizeof( gusAnimInst ), &uiBytesRead ) ) + { + return( FALSE ); + } - FileClose( hFile ); + FileClose( hFile ); // crouch throwing memcpy(gusAnimInst[ THROW_ITEM_CROUCHED ],CrouchedThrowAnimationScript,sizeof(CrouchedThrowAnimationScript)); // crouch throwing - return( TRUE ); + return( TRUE ); } BOOLEAN IsAnimationValidForBodyType( SOLDIERTYPE *pSoldier, UINT16 usNewState ) @@ -3080,135 +3083,135 @@ BOOLEAN SubstituteBodyTypeAnimation( SOLDIERTYPE *pSoldier, UINT16 usTestState, if ( pSoldier->ubBodyType == QUEENMONSTER ) { - switch( usTestState ) - { - case STANDING: - case WALKING: - case RUNNING: + switch( usTestState ) + { + case STANDING: + case WALKING: + case RUNNING: - *pusSubState = QUEEN_MONSTER_BREATHING; - fSubFound = TRUE; - break; - } + *pusSubState = QUEEN_MONSTER_BREATHING; + fSubFound = TRUE; + break; + } } if ( pSoldier->ubBodyType == LARVAE_MONSTER ) { - switch( usTestState ) - { - case STANDING: + switch( usTestState ) + { + case STANDING: - *pusSubState = LARVAE_BREATH; - fSubFound = TRUE; - break; + *pusSubState = LARVAE_BREATH; + fSubFound = TRUE; + break; - case WALKING: - case RUNNING: + case WALKING: + case RUNNING: - *pusSubState = LARVAE_WALK; - fSubFound = TRUE; - break; + *pusSubState = LARVAE_WALK; + fSubFound = TRUE; + break; - } + } } if ( pSoldier->ubBodyType == CROW ) { - switch( usTestState ) - { - case WALKING: + switch( usTestState ) + { + case WALKING: - *pusSubState = CROW_WALK; - fSubFound = TRUE; - break; + *pusSubState = CROW_WALK; + fSubFound = TRUE; + break; - case STANDING: + case STANDING: - *pusSubState = CROW_EAT; - fSubFound = TRUE; - break; + *pusSubState = CROW_EAT; + fSubFound = TRUE; + break; - } + } } if ( pSoldier->ubBodyType == BLOODCAT ) { - switch( usTestState ) - { - case RUNNING: - *pusSubState = BLOODCAT_RUN; - fSubFound = TRUE; - break; + switch( usTestState ) + { + case RUNNING: + *pusSubState = BLOODCAT_RUN; + fSubFound = TRUE; + break; - } + } } if ( pSoldier->ubBodyType == ADULTFEMALEMONSTER || pSoldier->ubBodyType == AM_MONSTER || - pSoldier->ubBodyType == YAF_MONSTER || pSoldier->ubBodyType == YAM_MONSTER ) + pSoldier->ubBodyType == YAF_MONSTER || pSoldier->ubBodyType == YAM_MONSTER ) { - switch( usTestState ) - { - case WALKING: - *pusSubState = ADULTMONSTER_WALKING; - fSubFound = TRUE; - break; + switch( usTestState ) + { + case WALKING: + *pusSubState = ADULTMONSTER_WALKING; + fSubFound = TRUE; + break; - case RUNNING: - *pusSubState = ADULTMONSTER_WALKING; - fSubFound = TRUE; - break; + case RUNNING: + *pusSubState = ADULTMONSTER_WALKING; + fSubFound = TRUE; + break; - } + } } if ( pSoldier->ubBodyType == ROBOTNOWEAPON ) { - switch( usTestState ) - { - case STANDING: + switch( usTestState ) + { + case STANDING: - // OK, if they are on the CIV_TEAM, sub for no camera moving - if ( pSoldier->bTeam == CIV_TEAM ) - { - *pusSubState = ROBOT_CAMERA_NOT_MOVING; - fSubFound = TRUE; - } - break; + // OK, if they are on the CIV_TEAM, sub for no camera moving + if ( pSoldier->bTeam == CIV_TEAM ) + { + *pusSubState = ROBOT_CAMERA_NOT_MOVING; + fSubFound = TRUE; + } + break; - case WALKING: - *pusSubState = ROBOT_WALK; - fSubFound = TRUE; - break; + case WALKING: + *pusSubState = ROBOT_WALK; + fSubFound = TRUE; + break; - case RUNNING: - *pusSubState = ROBOT_WALK; - fSubFound = TRUE; - break; + case RUNNING: + *pusSubState = ROBOT_WALK; + fSubFound = TRUE; + break; - } + } } if ( IS_CIV_BODY_TYPE( pSoldier ) ) { switch( usTestState ) { - case KNEEL_UP: - *pusSubState = END_COWER; - fSubFound = TRUE; - break; - case KNEEL_DOWN: - *pusSubState = START_COWER; - fSubFound = TRUE; - break; + case KNEEL_UP: + *pusSubState = END_COWER; + fSubFound = TRUE; + break; + case KNEEL_DOWN: + *pusSubState = START_COWER; + fSubFound = TRUE; + break; - case WKAEUP_FROM_SLEEP: - case GOTO_SLEEP: - case SLEEPING: - *pusSubState = STANDING; - fSubFound = TRUE; - break; + case WKAEUP_FROM_SLEEP: + case GOTO_SLEEP: + case SLEEPING: + *pusSubState = STANDING; + fSubFound = TRUE; + break; } } @@ -3220,86 +3223,86 @@ INT8 GetBodyTypePaletteSubstitutionCode( SOLDIERTYPE *pSoldier, UINT8 ubBodyType { switch( ubBodyType ) { - case REGMALE: - case BIGMALE: - case STOCKYMALE: - case REGFEMALE: + case REGMALE: + case BIGMALE: + case STOCKYMALE: + case REGFEMALE: - if ( pSoldier != NULL ) + if ( pSoldier != NULL ) + { + // Are we on fire? + if ( pSoldier->usAnimState == CHARIOTS_OF_FIRE || pSoldier->usAnimState == BODYEXPLODING ) { - // Are we on fire? - if ( pSoldier->usAnimState == CHARIOTS_OF_FIRE || pSoldier->usAnimState == BODYEXPLODING ) - { - return( 0 ); - } - - - // Check for camo... - - //stealth has priority - if ( GetWornStealth(pSoldier) >= 50 ) - { - strcpy( zColFilename, "ANIMS\\stealth.col" ); - return( 1 ); - } - - int urban = pSoldier->urbanCamo + pSoldier->wornUrbanCamo; - int jungle = pSoldier->bCamo + pSoldier->wornCamo; - int desert = pSoldier->desertCamo + pSoldier->wornDesertCamo; - int snow = pSoldier->snowCamo + pSoldier->wornSnowCamo; - int total = urban + jungle + desert + snow; - - // display camo depending on which is higher - if ( total >= 50 ) - { - if ( jungle >= urban && jungle >= desert && jungle >= snow ) - strcpy( zColFilename, "ANIMS\\camo.COL" ); - else if ( urban >= jungle && urban >= desert && urban >= snow ) - strcpy( zColFilename, "ANIMS\\urban.col" ); - else if ( desert >= urban && desert >= jungle && desert >= snow ) - strcpy( zColFilename, "ANIMS\\desert.col" ); - else if ( snow >= urban && snow >= desert && snow >= jungle ) - strcpy( zColFilename, "ANIMS\\snow.col" ); - - return( 1 ); - } + return( 0 ); } - return( -1 ); - case YAF_MONSTER: + // Check for camo... - strcpy( zColFilename, "ANIMS\\MONSTERS\\fm_brite.COL" ); - return( 1 ); + //stealth has priority + if ( GetWornStealth(pSoldier) >= 50 ) + { + strcpy( zColFilename, "ANIMS\\stealth.col" ); + return( 1 ); + } - case YAM_MONSTER: + int urban = pSoldier->urbanCamo + pSoldier->wornUrbanCamo; + int jungle = pSoldier->bCamo + pSoldier->wornCamo; + int desert = pSoldier->desertCamo + pSoldier->wornDesertCamo; + int snow = pSoldier->snowCamo + pSoldier->wornSnowCamo; + int total = urban + jungle + desert + snow; - strcpy( zColFilename, "ANIMS\\MONSTERS\\mn_brite.COL" ); - return( 1 ); + // display camo depending on which is higher + if ( total >= 50 ) + { + if ( jungle >= urban && jungle >= desert && jungle >= snow ) + strcpy( zColFilename, "ANIMS\\camo.COL" ); + else if ( urban >= jungle && urban >= desert && urban >= snow ) + strcpy( zColFilename, "ANIMS\\urban.col" ); + else if ( desert >= urban && desert >= jungle && desert >= snow ) + strcpy( zColFilename, "ANIMS\\desert.col" ); + else if ( snow >= urban && snow >= desert && snow >= jungle ) + strcpy( zColFilename, "ANIMS\\snow.col" ); - case ADULTFEMALEMONSTER: - - strcpy( zColFilename, "ANIMS\\MONSTERS\\femmon.COL" ); - return( 1 ); + return( 1 ); + } + } + return( -1 ); - case AM_MONSTER: - strcpy( zColFilename, "ANIMS\\MONSTERS\\monster.COL" ); - return( 1 ); + case YAF_MONSTER: - case QUEENMONSTER: - case COW: - case CROW: - case BLOODCAT: - case HUMVEE: - case ELDORADO: - case ICECREAMTRUCK: - case JEEP: - case ROBOTNOWEAPON: - case TANK_NW: - case TANK_NE: + strcpy( zColFilename, "ANIMS\\MONSTERS\\fm_brite.COL" ); + return( 1 ); - return( 0 ); + case YAM_MONSTER: + + strcpy( zColFilename, "ANIMS\\MONSTERS\\mn_brite.COL" ); + return( 1 ); + + case ADULTFEMALEMONSTER: + + strcpy( zColFilename, "ANIMS\\MONSTERS\\femmon.COL" ); + return( 1 ); + + case AM_MONSTER: + + strcpy( zColFilename, "ANIMS\\MONSTERS\\monster.COL" ); + return( 1 ); + + case QUEENMONSTER: + case COW: + case CROW: + case BLOODCAT: + case HUMVEE: + case ELDORADO: + case ICECREAMTRUCK: + case JEEP: + case ROBOTNOWEAPON: + case TANK_NW: + case TANK_NE: + + return( 0 ); } return( -1 ); @@ -3311,7 +3314,7 @@ BOOLEAN SetSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimState ) { UINT16 usAnimSurface; - // Delete any structure info! + // Delete any structure info! if ( pSoldier->pLevelNode != NULL ) { DeleteStructureFromWorld( pSoldier->pLevelNode->pStructureData ); @@ -3383,7 +3386,7 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta BOOLEAN fAdjustedForItem = FALSE; UINT16 usNewAnimState; - //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DetermineSoldierAnimationSurface")); + //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DetermineSoldierAnimationSurface")); ubBodyType = pSoldier->ubBodyType; @@ -3418,7 +3421,7 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta INT8 bDir; // Assume a target gridno is here.... get direction... - // ATE: use +2 in gridno because here head is far from body + // ATE: use +2 in gridno because here head is far from body bDir = (INT8)GetDirectionToGridNoFromGridNo( (INT16)( pSoldier->sGridNo + 2 ), pSoldier->sTargetGridNo ); return( gusQueenMonsterSpitAnimPerDir[ bDir ] ); @@ -3488,7 +3491,7 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta { if ( ( Item[ usItem ].usItemClass == IC_GUN || Item[ usItem ].usItemClass == IC_LAUNCHER ) && !Item[usItem].rocketlauncher) { -// if ( (Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) + // if ( (Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) if ( (Item[ usItem ].twohanded ) ) { ubWaterHandIndex = 0; @@ -3498,7 +3501,7 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta // CHANGE BASED ON HIEGHT OF WATER usAltAnimSurface = gubAnimSurfaceMidWaterSubIndex[pSoldier->ubBodyType][usAnimState][ ubWaterHandIndex ]; - + if ( usAltAnimSurface != INVALID_ANIMATION ) { usAnimSurface = usAltAnimSurface; @@ -3520,7 +3523,7 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta else { usAltAnimSurface = gubAnimSurfaceItemSubIndex[pSoldier->ubBodyType][usAnimState]; - + if ( usAltAnimSurface != INVALID_ANIMATION ) { usAnimSurface = usAltAnimSurface; @@ -3533,7 +3536,7 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta // CHECK FOR HANDGUN if ( ( Item[ usItem ].usItemClass == IC_GUN || Item[ usItem ].usItemClass == IC_LAUNCHER ) && !Item[usItem].rocketlauncher ) { -// if ( !(Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) + // if ( !(Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) if ( !(Item[ usItem ].twohanded ) ) { usAltAnimSurface = gubAnimSurfaceItemSubIndex[pSoldier->ubBodyType][usAnimState]; @@ -3559,7 +3562,7 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta else { usAltAnimSurface = gubAnimSurfaceItemSubIndex[pSoldier->ubBodyType][usAnimState]; - + if ( usAltAnimSurface != INVALID_ANIMATION ) { usAnimSurface = usAltAnimSurface; @@ -3603,7 +3606,7 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta } - //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DetermineSoldierAnimationSurface done")); + //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DetermineSoldierAnimationSurface done")); return( usAnimSurface ); } @@ -3621,10 +3624,10 @@ UINT16 GetSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimState ) if ( gAnimSurfaceDatabase[ usAnimSurface ].hVideoObject == NULL ) { ScreenMsg( FONT_MCOLOR_RED, MSG_BETAVERSION, L"IAnimation Surface for Body %d, animation %S, surface %d not loaded.", pSoldier->ubBodyType, gAnimControl[ usAnimState ].zAnimStr, usAnimSurface ); - AnimDebugMsg( String( "Surface Database: PROBLEMS!!!!!!" ) ); - usAnimSurface = INVALID_ANIMATION_SURFACE; + AnimDebugMsg( String( "Surface Database: PROBLEMS!!!!!!" ) ); + usAnimSurface = INVALID_ANIMATION_SURFACE; } } return( usAnimSurface ); -} \ No newline at end of file +} diff --git a/Tactical/Animation Control.h b/Tactical/Animation Control.h index ba888a9d..3c63f3a2 100644 --- a/Tactical/Animation Control.h +++ b/Tactical/Animation Control.h @@ -56,10 +56,20 @@ #define ANIM_RAISE_WEAPON 0x00080000 #define ANIM_NOCHANGE_WEAPON 0x00100000 #define ANIM_NOCHANGE_PENDINGCOUNT 0x00200000 -#define ANIM_NO_EFFORT 0x00400000 -#define ANIM_MIN_EFFORT 0x00800000 -#define ANIM_LIGHT_EFFORT 0x01000000 -#define ANIM_MODERATE_EFFORT 0x02000000 +// I'm commandeering the effort flags. I do not expect to see multiple efforts for the same tasks, so I'm turning them into a 2-bit +// level instead. So there :P +#define ANIM_NO_EFFORT 0x00000000 +#define ANIM_MIN_EFFORT 0x00400000 +#define ANIM_LIGHT_EFFORT 0x00800000 +#define ANIM_MODERATE_EFFORT 0x00C00000 + +// Return a number between 0 and 4 to indicate effort. 4 means variable +#define EFFORT(flags) (((flags) & ANIM_VARIABLE_EFFORT) ? 4 : ((flags) & 0x00C00000) >> 22) + +// Now I have room for a new flag. And there's still room for one more! +#define ANIM_ATTACK 0x01000000 +#define ANIM_FREEFORUSE 0x02000000 + #define ANIM_RT_NONINTERRUPT 0x04000000 #define ANIM_VARIABLE_EFFORT 0x08000000 #define ANIM_UPDATEMOVEMENTMODE 0x10000000 @@ -92,7 +102,7 @@ typedef struct INT16 sAP; INT16 sSpeed; FLOAT dMovementChange; - UINT32 uiFlags; + UINT32 uiFlags; UINT8 ubHeight; UINT8 ubEndHeight; INT8 bProfile; @@ -530,7 +540,7 @@ enum AnimationStates LOCKPICK_CROUCHED, // crouch throwing - THROW_ITEM_CROUCHED, + THROW_ITEM_CROUCHED, // NUMANIMATIONSTATES @@ -572,4 +582,4 @@ UINT16 LoadSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimState ); UINT16 GetSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimState ); -#endif \ No newline at end of file +#endif diff --git a/Tactical/Animation Data.cpp b/Tactical/Animation Data.cpp index 67786424..5e384697 100644 --- a/Tactical/Animation Data.cpp +++ b/Tactical/Animation Data.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Tactical All.h" #else + #include "builddefines.h" #include #include #include "wcheck.h" @@ -1131,4 +1132,4 @@ void ZeroAnimSurfaceCounts( ) } memset( gbAnimUsageHistory, 0, sizeof( gbAnimUsageHistory ) ); -} \ No newline at end of file +} diff --git a/Tactical/Arms Dealer Init.cpp b/Tactical/Arms Dealer Init.cpp index 37c87af6..ebf4588e 100644 --- a/Tactical/Arms Dealer Init.cpp +++ b/Tactical/Arms Dealer Init.cpp @@ -14,6 +14,8 @@ #include "Message.h" #include "soldier profile.h" #include "Handle Items.h" + #include "Quests.h" + #include "Scheduling.h" #endif diff --git a/Tactical/ArmsDealerInvInit.cpp b/Tactical/ArmsDealerInvInit.cpp index 6f84af10..f350aa22 100644 --- a/Tactical/ArmsDealerInvInit.cpp +++ b/Tactical/ArmsDealerInvInit.cpp @@ -6,6 +6,14 @@ #include "Item Types.h" #include "Arms Dealer Init.h" #include "DEbug.h" + #include "weapons.h" + #include "Campaign.h" + #include "GameSettings.h" + #include "AIInternals.h" + #include "LaptopSave.h" + #include "bobbyr.h" + #include "Random.h" + #include "Shopkeeper Interface.h" #endif diff --git a/Tactical/ArmsDealerInvInit.h b/Tactical/ArmsDealerInvInit.h index 39fc147e..30f8c7e4 100644 --- a/Tactical/ArmsDealerInvInit.h +++ b/Tactical/ArmsDealerInvInit.h @@ -1,6 +1,7 @@ #ifndef _ARMS_DEALER_INV_INIT__H_ #define _ARMS_DEALER_INV_INIT__H_ +#include "Item Types.h" #define LAST_DEALER_ITEM 0//-1 #define NO_DEALER_ITEM 0 diff --git a/Tactical/Auto Bandage.cpp b/Tactical/Auto Bandage.cpp index c6c57916..10468c51 100644 --- a/Tactical/Auto Bandage.cpp +++ b/Tactical/Auto Bandage.cpp @@ -339,7 +339,7 @@ BOOLEAN CreateAutoBandageString( void ) uiDoctorNameStringLength += wcslen( Message[STR_ARE_APPLYING_FIRST_AID] ); } - sAutoBandageString = (STR16) MemRealloc( sAutoBandageString, uiDoctorNameStringLength * sizeof( CHAR16 ) ); + sAutoBandageString = (STR16) MemRealloc( sAutoBandageString, uiDoctorNameStringLength * sizeof( CHAR16 ) ); if (!sAutoBandageString) { return( FALSE ); @@ -352,7 +352,7 @@ BOOLEAN CreateAutoBandageString( void ) else { // make a temporary string to hold most of the doctors names joined by commas - sTemp = (STR16) MemAlloc( uiDoctorNameStringLength * sizeof( CHAR16 ) ); + sTemp = (STR16) MemAlloc( uiDoctorNameStringLength * sizeof( CHAR16 ) ); // sTemp = MemAlloc( 1000 ); if (!sTemp) { diff --git a/Tactical/Boxing.cpp b/Tactical/Boxing.cpp index 914be127..37041b95 100644 --- a/Tactical/Boxing.cpp +++ b/Tactical/Boxing.cpp @@ -15,6 +15,15 @@ #include "Handle UI.h" #include "Points.h" #include "interface.h" + #include "interface dialogue.h" + #include "TeamTurns.h" + #include "Music Control.h" + #include "history.h" + #include "strategicmap.h" + #include "Game Clock.h" + #include "Animation Data.h" + #include "Font Control.h" + #include "message.h" #endif INT16 gsBoxerGridNo[ NUM_BOXERS ] = { 11393, 11233, 11073 }; diff --git a/Tactical/Campaign.cpp b/Tactical/Campaign.cpp index f10fc77f..7b3672af 100644 --- a/Tactical/Campaign.cpp +++ b/Tactical/Campaign.cpp @@ -2,6 +2,7 @@ #ifdef PRECOMPILEDHEADERS #include "Tactical All.h" #else + #include "builddefines.h" #include #include #include @@ -22,6 +23,19 @@ #include "Sys Globals.h" #include "Text.h" #include "GameSettings.h" + #include "Assignments.h" + #include "Interface.h" + #include "Game Event Hook.h" + #include "Overhead.h" + #include "meanwhile.h" + #include "Quests.h" + #include "Squads.h" + #include "Soldier macros.h" + #include "strategic.h" + #include "strategicmap.h" + #include "Town Militia.h" + #include "Campaign Types.h" + #include "Tactical Save.h" #endif #include "email.h" diff --git a/Tactical/Civ Quotes.cpp b/Tactical/Civ Quotes.cpp index b6a240e2..7bdecdcc 100644 --- a/Tactical/Civ Quotes.cpp +++ b/Tactical/Civ Quotes.cpp @@ -1,6 +1,38 @@ // WANNE 2 #ifdef PRECOMPILEDHEADERS #include "Tactical All.h" +#else +#include "builddefines.h" +#include +#include "Types.h" +#include "civ quotes.h" +#include "mousesystem.h" +#include "strategicmap.h" +#include "WCheck.h" +#include "FileMan.h" +#include "encrypted file.h" +#include "MessageBoxScreen.h" +#include "Queen Command.h" +#include "Overhead.h" +#include "render dirty.h" +#include "merctextbox.h" +#include "ai.h" +#include "Text.h" +#include "screenids.h" +#include "Animation Data.h" +#include "Video.h" +#include "Font Control.h" +#include "message.h" +#include "local.h" +#include "renderworld.h" +#include "Interface.h" +#include "cursors.h" +#include "Dialogue Control.h" +#include "Quests.h" +#include "Strategic Town Loyalty.h" +#include "NPC.h" +#include "Strategic Mines.h" +#include "Random.h" #endif diff --git a/Tactical/Civ Quotes.h b/Tactical/Civ Quotes.h index 65de54d9..2847b0ae 100644 --- a/Tactical/Civ Quotes.h +++ b/Tactical/Civ Quotes.h @@ -1,6 +1,8 @@ #ifndef __CIV_QUOTES_H #define __CIV_QUOTES_H +#include "Soldier Control.h" + #define CIV_TYPE_NA 0 #define CIV_TYPE_ADULT 1 #define CIV_TYPE_KID 2 diff --git a/Tactical/Dialogue Control.cpp b/Tactical/Dialogue Control.cpp index 52f7817f..7c275f77 100644 --- a/Tactical/Dialogue Control.cpp +++ b/Tactical/Dialogue Control.cpp @@ -46,6 +46,16 @@ #include "SkillCheck.h" #include "Interface Control.h" #include "finances.h" + #include "civ quotes.h" + #include "Map Screen Interface Map.h" + #include "opplist.h" + #include "ai.h" + #include "worldman.h" + #include "Map Screen Interface Bottom.h" + #include "Campaign.h" + #include "end game.h" + #include "los.h" + #include "qarray.h" #endif #define DIALOGUESIZE 480 @@ -2255,21 +2265,23 @@ void HandleDialogueEnd( FACETYPE *pFace ) case DIALOGUE_TACTICAL_UI: case DIALOGUE_EXTERNAL_NPC_UI: // Remove if created + // 0verhaul: Both of these events are more or less independent. Most often the gTextBoxOverlay fails to init. + // Therefore I am removing the dependency on giTextBoxOverlay before it decides to destroy the popup box region. + // This should prevent blockage of buttons and also clicks on the tactical map. if ( giTextBoxOverlay != -1 ) { RemoveVideoOverlay( giTextBoxOverlay ); giTextBoxOverlay = -1; - - if ( fTextBoxMouseRegionCreated ) - { - RemoveMercPopupBoxFromIndex( iDialogueBox ); + } + + if ( fTextBoxMouseRegionCreated ) + { + RemoveMercPopupBoxFromIndex( iDialogueBox ); - // reset box id - iDialogueBox = -1; - MSYS_RemoveRegion( &gTextBoxMouseRegion ); - fTextBoxMouseRegionCreated = FALSE; - } - + // reset box id + iDialogueBox = -1; + MSYS_RemoveRegion( &gTextBoxMouseRegion ); + fTextBoxMouseRegionCreated = FALSE; } break; diff --git a/Tactical/DisplayCover.cpp b/Tactical/DisplayCover.cpp index 4d81ed39..4950de45 100644 --- a/Tactical/DisplayCover.cpp +++ b/Tactical/DisplayCover.cpp @@ -5,6 +5,31 @@ #include "opplist.h" #include "_Ja25Englishtext.h" //#include "Ja25 Strategic Ai.h" +#else +#include "builddefines.h" +#include "Types.h" +#include "Isometric Utils.h" +#include "Soldier Control.h" +#include "Overhead.h" +#include "displaycover.h" +#include "Font Control.h" +#include "_Ja25EnglishText.h" +#include "message.h" +#include "GameSettings.h" +#include "renderworld.h" +#include "Interface.h" +#include "Debug.h" +#include "PATHAI.H" +#include "worldman.h" +#include "opplist.h" +#include "los.h" +#include "weapons.h" +#include "Game Clock.h" +#include "Animation Control.h" +#include "lighting.h" +#include "Text.h" +#include "strategicmap.h" +#include "Render Fun.h" #endif //******* Local Defines ************************************************** @@ -79,10 +104,10 @@ BOOLEAN IsTheRoofVisible( INT16 sGridNo ); void DisplayCoverOfSelectedGridNo( ) { - INT16 sGridNo; + UINT16 usGridNo; INT8 bStance; - GetMouseMapPos( &sGridNo ); + GetMouseMapPos( &usGridNo ); //Only allowed in if there is someone selected if( gusSelectedSoldier == NOBODY ) @@ -91,12 +116,12 @@ void DisplayCoverOfSelectedGridNo( ) } //if the cursor is in a the tactical map - if( sGridNo != NOWHERE && sGridNo != 0 ) + if( usGridNo != NOWHERE && usGridNo != 0 ) { bStance = GetCurrentMercForDisplayCoverStance(); //if the gridno is different then the last one that was displayed - if( sGridNo != gsLastCoverGridNo || + if( usGridNo != gsLastCoverGridNo || gbLastStance != bStance || MercPtrs[ gusSelectedSoldier ]->sGridNo != gsLastSoldierGridNo ) { @@ -126,11 +151,11 @@ void DisplayCoverOfSelectedGridNo( ) } gbLastStance = bStance; - gsLastCoverGridNo = sGridNo; + gsLastCoverGridNo = usGridNo; gsLastSoldierGridNo = MercPtrs[ gusSelectedSoldier ]->sGridNo; //Fill the array of gridno and cover values - CalculateCoverInRadiusAroundGridno( sGridNo, gGameSettings.ubSizeOfDisplayCover ); + CalculateCoverInRadiusAroundGridno( usGridNo, gGameSettings.ubSizeOfDisplayCover ); //Add the graphics to each gridno AddCoverTileToEachGridNo(); @@ -641,10 +666,10 @@ void DisplayRangeToTarget( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ) void DisplayGridNoVisibleToSoldierGrid( ) { - INT16 sGridNo; + UINT16 usGridNo; // INT8 bStance; - GetMouseMapPos( &sGridNo ); + GetMouseMapPos( &usGridNo ); //Only allowed in if there is someone selected if( gusSelectedSoldier == NOBODY ) @@ -653,10 +678,10 @@ void DisplayGridNoVisibleToSoldierGrid( ) } //if the cursor is in a the tactical map - if( sGridNo != NOWHERE && sGridNo != 0 ) + if( usGridNo != NOWHERE && usGridNo != 0 ) { //if the gridno is different then the last one that was displayed - if( sGridNo != gsLastVisibleToSoldierGridNo || MercPtrs[ gusSelectedSoldier ]->sGridNo != gsLastSoldierGridNo ) + if( usGridNo != gsLastVisibleToSoldierGridNo || MercPtrs[ gusSelectedSoldier ]->sGridNo != gsLastSoldierGridNo ) { //if the cover is currently being displayed if( gsLastVisibleToSoldierGridNo != NOWHERE || gsLastSoldierGridNo != NOWHERE ) @@ -680,12 +705,12 @@ void DisplayGridNoVisibleToSoldierGrid( ) //gJa25SaveStruct.uiDisplayLosCounter++; } - gsLastVisibleToSoldierGridNo = sGridNo; + gsLastVisibleToSoldierGridNo = usGridNo; gsLastSoldierGridNo = MercPtrs[ gusSelectedSoldier ]->sGridNo; //Fill the array of gridno and cover values - CalculateVisibleToSoldierAroundGridno( sGridNo, gGameSettings.ubSizeOfLOS ); + CalculateVisibleToSoldierAroundGridno( usGridNo, gGameSettings.ubSizeOfLOS ); //Add the graphics to each gridno AddVisibleToSoldierToEachGridNo(); diff --git a/Tactical/Drugs And Alcohol.cpp b/Tactical/Drugs And Alcohol.cpp index 0f4709b8..54cfcb80 100644 --- a/Tactical/Drugs And Alcohol.cpp +++ b/Tactical/Drugs And Alcohol.cpp @@ -10,6 +10,9 @@ #include "morale.h" #include "points.h" #include "message.h" +#include "Random.h" +#include "Text.h" +#include "Interface.h" #endif UINT8 ubDrugTravelRate[] = { 4, 2 }; diff --git a/Tactical/End Game.cpp b/Tactical/End Game.cpp index 0ab5c5cb..e4f31142 100644 --- a/Tactical/End Game.cpp +++ b/Tactical/End Game.cpp @@ -19,6 +19,29 @@ #include "interface.h" #include "end game.h" #include "Intro.h" + #include "Exit Grids.h" + #include "strategicmap.h" + #include "Quests.h" + #include "SaveLoadMap.h" + #include "Sound Control.h" + #include "renderworld.h" + #include "Isometric Utils.h" + #include "Music Control.h" + #include "Soldier macros.h" + #include "qarray.h" + #include "los.h" + #include "Strategic AI.h" + #include "Squads.h" + #include "PreBattle Interface.h" + #include "Strategic Movement.h" + #include "strategic.h" + #include "Morale.h" + #include "Queen Command.h" + #include "Strategic Town Loyalty.h" + #include "Player Command.h" + #include "Campaign Types.h" + #include "Tactical Save.h" + #include "screenids.h" #endif INT16 sStatueGridNos[] = { 13829, 13830, 13669, 13670 }; @@ -415,7 +438,8 @@ void BeginHandleQueenBitchDeath( SOLDIERTYPE *pKillerSoldier, INT16 sGridNo, INT // HELLO! THESE ARE CREATURES! THEY CAN'T BE NEUTRAL! //if ( !pTeamSoldier->bNeutral && (pTeamSoldier->bSide != gbPlayerNum ) ) { - gTacticalStatus.ubAttackBusyCount++; +// gTacticalStatus.ubAttackBusyCount++; + DebugAttackBusy( "Killing off a queen ally.\n"); EVENT_SoldierGotHit( pTeamSoldier, 0, 10000, 0, pTeamSoldier->bDirection, 320, NOBODY , FIRE_WEAPON_NO_SPECIAL, pTeamSoldier->bAimShotLocation, 0, NOWHERE ); } } diff --git a/Tactical/Enemy Soldier Save.cpp b/Tactical/Enemy Soldier Save.cpp index 6b8ea75f..feb32caa 100644 --- a/Tactical/Enemy Soldier Save.cpp +++ b/Tactical/Enemy Soldier Save.cpp @@ -2,6 +2,7 @@ #include "Tactical All.h" #include "Enemy Soldier Save.h" #else + #include "builddefines.h" #include #include @@ -27,6 +28,11 @@ #include "Animation Data.h" #include "message.h" #include "Font Control.h" + #include "Campaign Types.h" + #include "Tactical Save.h" + #include "Game Clock.h" + #include "Queen Command.h" + #include "Scheduling.h" #endif BOOLEAN AddPlacementToWorld( SOLDIERINITNODE *pNode ); diff --git a/Tactical/Faces.cpp b/Tactical/Faces.cpp index 8e8d4fa2..90f49dd2 100644 --- a/Tactical/Faces.cpp +++ b/Tactical/Faces.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Tactical All.h" #else + #include "builddefines.h" #include "math.h" #include #include @@ -32,6 +33,10 @@ #include "interface.h" #include "Quests.h" #include "animation control.h" + #include "drugs and alcohol.h" + #include "Interface Items.h" + #include "meanwhile.h" + #include "Map Screen Interface.h" #endif // Defines diff --git a/Tactical/GAP.cpp b/Tactical/GAP.cpp index bbbf32a4..58e50c51 100644 --- a/Tactical/GAP.cpp +++ b/Tactical/GAP.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Tactical All.h" #else + #include "builddefines.h" #include "debug.h" #include "types.h" //#include "mssw.h" diff --git a/Tactical/Handle Doors.cpp b/Tactical/Handle Doors.cpp index 8f27aea6..c81ba723 100644 --- a/Tactical/Handle Doors.cpp +++ b/Tactical/Handle Doors.cpp @@ -2,6 +2,7 @@ #include "Tactical All.h" #include "language defines.h" #else + #include "builddefines.h" #include #include #include @@ -23,6 +24,16 @@ #include "message.h" #include "text.h" #include "random.h" + #include "SkillCheck.h" + #include "Dialogue Control.h" + #include "strategicmap.h" + #include "Quests.h" + #include "Render Fun.h" + #include "Map Screen Interface Map.h" + #include "Soldier Profile.h" + #include "Isometric Utils.h" + #include "ai.h" + #include "Soldier macros.h" #endif BOOLEAN gfSetPerceivedDoorState = FALSE; diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp index f0e694ef..a374fba4 100644 --- a/Tactical/Handle Items.cpp +++ b/Tactical/Handle Items.cpp @@ -55,6 +55,11 @@ #include "qarray.h" #include "render fun.h" #include "environment.h" + #include "Map Information.h" + #include "GameSettings.h" + #include "end game.h" + #include "interface control.h" + #include "Map Screen Interface Map Inventory.h" #endif #define NUM_ITEMS_LISTED 8 @@ -202,7 +207,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us pSoldier->usAttackingWeapon = usHandItem; // Find soldier flags depend on if it's our own merc firing or a NPC - //if ( FindSoldier( usGridNo, &usSoldierIndex, &uiMercFlags, FIND_SOLDIER_GRIDNO ) ) + //if ( FindSoldier( usGridNo, &usSoldierIndex, &uiMercFlags, FIND_SOLDIER_GRIDNO ) ) if ( ( usSoldierIndex = WhoIsThere2( usGridNo, bLevel ) ) != NO_SOLDIER ) { pTargetSoldier = MercPtrs[ usSoldierIndex ]; @@ -212,11 +217,11 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us // ATE: Check if we are targeting an interactive tile, and adjust gridno accordingly... pIntNode = GetCurInteractiveTileGridNoAndStructure( &sGridNo, &pStructure ); - if ( pIntNode != NULL && pTargetSoldier == pSoldier ) - { - // Truncate target sioldier - pTargetSoldier = NULL; - } + if ( pIntNode != NULL && pTargetSoldier == pSoldier ) + { + // Truncate target sioldier + pTargetSoldier = NULL; + } } } @@ -227,10 +232,10 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us gTacticalStatus.ubAttackBusyCount = 0; } - if ( pTargetSoldier ) - { - pTargetSoldier->bBeingAttackedCount = 0; - } +// if ( pTargetSoldier ) +// { +// pTargetSoldier->bBeingAttackedCount = 0; +// } // Check our soldier's life for unconscious! @@ -297,8 +302,8 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us if (pSoldier->bTeam == gbPlayerNum) { PlayJA2Sample( RG_ID_IMPRINTED, RATE_11025, HIGHVOLUME, 1, MIDDLE ); - - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"\"%s\"", TacticalStr[ GUN_GOT_FINGERPRINT ] ); + + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"\"%s\"", TacticalStr[ GUN_GOT_FINGERPRINT ] ); return( ITEM_HANDLE_BROKEN ); } @@ -362,6 +367,9 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us } // Get gridno - either soldier's position or the gridno + // ??? Why isn't the target's gridno the same as the gridno of the soldier on that grid? + // Real example: Soldier fires at 16701. It finds a soldier there. That soldier's sGridNo is 16547. So why + // isn't this soldier at grid 16547? if ( pTargetSoldier != NULL ) { sTargetGridNo = pTargetSoldier->sGridNo; @@ -405,14 +413,14 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us } /*else { - // If raising gun, don't charge turning! - if ( fAddingTurningCost ) - { - pSoldier->fDontChargeReadyAPs = TRUE; - } + // If raising gun, don't charge turning! + if ( fAddingTurningCost ) + { + pSoldier->fDontChargeReadyAPs = TRUE; + } }*/ - + // If this is a player guy, show message about no APS @@ -441,7 +449,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us pSoldier->bWeaponMode = WM_BURST; pSoldier->bDoAutofire = 0; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 26 ], pSoldier->name ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 26 ], pSoldier->name ); } } @@ -454,11 +462,11 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us //UINT32 diceSides = RAND_MAX; //Madd: tried to make this more marksmanship dependent than agility, a level 10 auto-weapons specialist with 100 in all stats was wasting wayyy too many APs on this fucker //UINT32 diceSides = RAND_MAX / ( max(1,pSoldier->bMarksmanship) / 10) ; - + //Kaiden: Had to change the minimum value to 10 instead of 1, //Rounding down resulted in division by zero and caused a crash. UINT32 diceSides = RAND_MAX / ( max(10,pSoldier->bMarksmanship) / 10) ; - + DOUBLE avgAPadded = max(((400.0f-2.0f*pSoldier->bAgility))*(63.0f-5.0f*(pSoldier->bExpLevel+2.0f*NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPS )))/2700.0f,1); //Important! don't make this zero, the formulae don't like it. UINT32 chanceToMisfire = (UINT32)(((DOUBLE)diceSides*(2.0f*avgAPadded+1.0f-sqrt(4.0f*avgAPadded+1.0f)))/(2.0f*avgAPadded)); //derive the chace to misfire from the desired average AP overspent, derived suing UINT32 chanceToMisfireDry = (UINT32)(((DOUBLE)diceSides*(avgAPadded+1.0f-sqrt(2.0f*avgAPadded+1.0f)))/(avgAPadded)); //chance to misfire if weapon is dry. Designed to waste avgAPadded/2 APs @@ -473,7 +481,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us if((pSoldier->ubProfile != NO_PROFILE) && (gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait == PSYCHO) && Random(100) < 20) { chanceToMisfire = diceSides; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 26 ], pSoldier->name ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 26 ], pSoldier->name ); } chanceToMisfire = __min(diceSides-1, chanceToMisfire); //cap the misfire chance, no-one has reflexes this bad @@ -499,7 +507,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us //note that we could misfire more bullets than we have rounds //this represents the soldier running out of ammo and not noticing //the max that can be lost this way is 1AP - + pSoldier->bDoAutofire -= misfirePenalty; sAPCost = CalcTotalAPsToAttack( pSoldier, sTargetGridNo, TRUE, 0 ); @@ -516,17 +524,17 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 63 ], pSoldier->name, __min(pSoldier->bDoAutofire,pSoldier->inv[ pSoldier->ubAttackingHand ].ubGunShotsLeft) - startAuto ); } } - - + + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Chance:%d.%d, AvgAps=%f, APs=%d", chanceToMisfire/(diceSides/100),chanceToMisfire%(diceSides/100), avgAPadded,sAPCost-startAPcost); } // Deduct points if our target is different! // if attacking a new target (or if the specific target is uncertain) - - // DEF: Made into an event -// EVENT_FireSoldierWeapon( pSoldier, sTargetGridNo ); + + // DEF: Made into an event + // EVENT_FireSoldierWeapon( pSoldier, sTargetGridNo ); if (fFromUI) { // set the target level; if the AI calls this it will have set the level already... @@ -576,12 +584,12 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us // Descrease aim by two if in real time if ( (gTacticalStatus.uiFlags & REALTIME ) || !(gTacticalStatus.uiFlags & INCOMBAT) ) { - //pSoldier->bShownAimTime -= 2; - //if ( pSoldier->bShownAimTime < REFINE_AIM_1 ) - //{ + //pSoldier->bShownAimTime -= 2; + //if ( pSoldier->bShownAimTime < REFINE_AIM_1 ) + //{ // pSoldier->bShownAimTime = REFINE_AIM_1; - //} - //pSoldier->fPauseAim = TRUE; + //} + //pSoldier->fPauseAim = TRUE; } // If in turn based - refresh aim to first level @@ -613,84 +621,84 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us //TRY PUNCHING if ( Item[ usHandItem ].usItemClass == IC_PUNCH ) { - INT16 sCnt; - INT16 sSpot; - UINT8 ubGuyThere; - INT16 sGotLocation = NOWHERE; - BOOLEAN fGotAdjacent = FALSE; + INT16 sCnt; + INT16 sSpot; + UINT8 ubGuyThere; + INT16 sGotLocation = NOWHERE; + BOOLEAN fGotAdjacent = FALSE; - for ( sCnt = 0; sCnt < NUM_WORLD_DIRECTIONS; sCnt++ ) - { - sSpot = NewGridNo( pSoldier->sGridNo, DirectionInc( sCnt ) ); + for ( sCnt = 0; sCnt < NUM_WORLD_DIRECTIONS; sCnt++ ) + { + sSpot = NewGridNo( pSoldier->sGridNo, DirectionInc( sCnt ) ); - // Make sure movement costs are OK.... - if ( gubWorldMovementCosts[ sSpot ][ sCnt ][ bLevel ] >= TRAVELCOST_BLOCKED ) - { - continue; - } + // Make sure movement costs are OK.... + if ( gubWorldMovementCosts[ sSpot ][ sCnt ][ bLevel ] >= TRAVELCOST_BLOCKED ) + { + continue; + } - // Check for who is there... - ubGuyThere = WhoIsThere2( sSpot, pSoldier->bLevel ); + // Check for who is there... + ubGuyThere = WhoIsThere2( sSpot, pSoldier->bLevel ); - if ( pTargetSoldier != NULL && ubGuyThere == pTargetSoldier->ubID ) - { - // We've got a guy here.... - // Who is the one we want...... - sGotLocation = sSpot; - sAdjustedGridNo = pTargetSoldier->sGridNo; - ubDirection = ( UINT8 )sCnt; - break; - } - } + if ( pTargetSoldier != NULL && ubGuyThere == pTargetSoldier->ubID ) + { + // We've got a guy here.... + // Who is the one we want...... + sGotLocation = sSpot; + sAdjustedGridNo = pTargetSoldier->sGridNo; + ubDirection = ( UINT8 )sCnt; + break; + } + } - if ( sGotLocation == NOWHERE ) - { - // See if we can get there to punch - sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); - if ( sActionGridNo != -1 ) - { - // OK, we've got somebody... - sGotLocation = sActionGridNo; + if ( sGotLocation == NOWHERE ) + { + // See if we can get there to punch + sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); + if ( sActionGridNo != -1 ) + { + // OK, we've got somebody... + sGotLocation = sActionGridNo; - fGotAdjacent = TRUE; - } - } - - // Did we get a loaction? - if ( sGotLocation != NOWHERE ) - { - pSoldier->sTargetGridNo = usGridNo; + fGotAdjacent = TRUE; + } + } - pSoldier->usActionData = usGridNo; - // CHECK IF WE ARE AT THIS GRIDNO NOW - if ( pSoldier->sGridNo != sGotLocation && fGotAdjacent ) - { - // SEND PENDING ACTION - pSoldier->ubPendingAction = MERC_PUNCH; - pSoldier->sPendingActionData2 = sAdjustedGridNo; - pSoldier->bPendingActionData3 = ubDirection; - pSoldier->ubPendingActionAnimCount = 0; + // Did we get a loaction? + if ( sGotLocation != NOWHERE ) + { + pSoldier->sTargetGridNo = usGridNo; - // WALK UP TO DEST FIRST - EVENT_InternalGetNewSoldierPath( pSoldier, sGotLocation, pSoldier->usUIMovementMode, FALSE, TRUE ); - } - else - { - pSoldier->bAction = AI_ACTION_KNIFE_STAB; - EVENT_SoldierBeginPunchAttack( pSoldier, sAdjustedGridNo, ubDirection ); - } + pSoldier->usActionData = usGridNo; + // CHECK IF WE ARE AT THIS GRIDNO NOW + if ( pSoldier->sGridNo != sGotLocation && fGotAdjacent ) + { + // SEND PENDING ACTION + pSoldier->ubPendingAction = MERC_PUNCH; + pSoldier->sPendingActionData2 = sAdjustedGridNo; + pSoldier->bPendingActionData3 = ubDirection; + pSoldier->ubPendingActionAnimCount = 0; - // OK, set UI - SetUIBusy( pSoldier->ubID ); + // WALK UP TO DEST FIRST + EVENT_InternalGetNewSoldierPath( pSoldier, sGotLocation, pSoldier->usUIMovementMode, FALSE, TRUE ); + } + else + { + pSoldier->bAction = AI_ACTION_KNIFE_STAB; + EVENT_SoldierBeginPunchAttack( pSoldier, sAdjustedGridNo, ubDirection ); + } - gfResetUIMovementOptimization = TRUE; + // OK, set UI + SetUIBusy( pSoldier->ubID ); - return( ITEM_HANDLE_OK ); - } - else - { - return( ITEM_HANDLE_CANNOT_GETTO_LOCATION ); - } + gfResetUIMovementOptimization = TRUE; + + return( ITEM_HANDLE_OK ); + } + else + { + return( ITEM_HANDLE_CANNOT_GETTO_LOCATION ); + } } //USING THE MEDKIT @@ -709,65 +717,111 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us GetMouseMapPos( &usMapPos ); } - // See if we can get there to stab - sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); - if ( sActionGridNo == -1 ) - { - // Try another location... - sActionGridNo = FindAdjacentGridEx( pSoldier, usMapPos, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); + // See if we can get there to stab + sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); + if ( sActionGridNo == -1 ) + { + // Try another location... + sActionGridNo = FindAdjacentGridEx( pSoldier, usMapPos, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); - if ( sActionGridNo == -1 ) - { - return( ITEM_HANDLE_CANNOT_GETTO_LOCATION ); - } + if ( sActionGridNo == -1 ) + { + return( ITEM_HANDLE_CANNOT_GETTO_LOCATION ); + } - if ( !gTacticalStatus.fAutoBandageMode ) - { - fHadToUseCursorPos = TRUE; - } - } + if ( !gTacticalStatus.fAutoBandageMode ) + { + fHadToUseCursorPos = TRUE; + } + } - // Calculate AP costs... - sAPCost = GetAPsToBeginFirstAid( pSoldier ); - sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints); + // Calculate AP costs... + sAPCost = GetAPsToBeginFirstAid( pSoldier ); + sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints); + + if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) ) + { + // OK, set UI + SetUIBusy( pSoldier->ubID ); + + // CHECK IF WE ARE AT THIS GRIDNO NOW + if ( pSoldier->sGridNo != sActionGridNo ) + { + // SEND PENDING ACTION + pSoldier->ubPendingAction = MERC_GIVEAID; + + if ( fHadToUseCursorPos ) + { + pSoldier->sPendingActionData2 = usMapPos; + } + else + { + if ( pTargetSoldier != NULL ) + { + pSoldier->sPendingActionData2 = pTargetSoldier->sGridNo; + } + else + { + pSoldier->sPendingActionData2 = usGridNo; + } + } + pSoldier->bPendingActionData3 = ubDirection; + pSoldier->ubPendingActionAnimCount = 0; + + // WALK UP TO DEST FIRST + EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE ); + } + else + { + EVENT_SoldierBeginFirstAid( pSoldier, sAdjustedGridNo, ubDirection ); + } + + if ( fFromUI ) + { + guiPendingOverrideEvent = A_CHANGE_TO_MOVE; + } + + return( ITEM_HANDLE_OK ); + } + else + { + return( ITEM_HANDLE_NOAPS ); + } + } + + if ( Item[usHandItem].wirecutters && pTargetSoldier == NULL ) // Madd: quick fix to allow wirecutter/knives + { + // See if we can get there to stab + sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); + if ( sActionGridNo != -1 ) + { + // Calculate AP costs... + sAPCost = GetAPsToCutFence( pSoldier ); + sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints); if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) ) { // OK, set UI + // ATE: Set UI here, not below so that if UI is unset, we don't set again! SetUIBusy( pSoldier->ubID ); - // CHECK IF WE ARE AT THIS GRIDNO NOW if ( pSoldier->sGridNo != sActionGridNo ) { // SEND PENDING ACTION - pSoldier->ubPendingAction = MERC_GIVEAID; - - if ( fHadToUseCursorPos ) - { - pSoldier->sPendingActionData2 = usMapPos; - } - else - { - if ( pTargetSoldier != NULL ) - { - pSoldier->sPendingActionData2 = pTargetSoldier->sGridNo; - } - else - { - pSoldier->sPendingActionData2 = usGridNo; - } - } + pSoldier->ubPendingAction = MERC_CUTFFENCE; + pSoldier->sPendingActionData2 = sAdjustedGridNo; pSoldier->bPendingActionData3 = ubDirection; pSoldier->ubPendingActionAnimCount = 0; // WALK UP TO DEST FIRST - EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE ); + EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode , FALSE, TRUE ); } else { - EVENT_SoldierBeginFirstAid( pSoldier, sAdjustedGridNo, ubDirection ); + EVENT_SoldierBeginCutFence( pSoldier, sAdjustedGridNo, ubDirection ); } + if ( fFromUI ) { guiPendingOverrideEvent = A_CHANGE_TO_MOVE; @@ -775,56 +829,10 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us return( ITEM_HANDLE_OK ); } - else - { + else + { return( ITEM_HANDLE_NOAPS ); - } - } - - if ( Item[usHandItem].wirecutters && pTargetSoldier == NULL ) // Madd: quick fix to allow wirecutter/knives - { - // See if we can get there to stab - sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); - if ( sActionGridNo != -1 ) - { - // Calculate AP costs... - sAPCost = GetAPsToCutFence( pSoldier ); - sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints); - - if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) ) - { - // OK, set UI - // ATE: Set UI here, not below so that if UI is unset, we don't set again! - SetUIBusy( pSoldier->ubID ); - // CHECK IF WE ARE AT THIS GRIDNO NOW - if ( pSoldier->sGridNo != sActionGridNo ) - { - // SEND PENDING ACTION - pSoldier->ubPendingAction = MERC_CUTFFENCE; - pSoldier->sPendingActionData2 = sAdjustedGridNo; - pSoldier->bPendingActionData3 = ubDirection; - pSoldier->ubPendingActionAnimCount = 0; - - // WALK UP TO DEST FIRST - EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode , FALSE, TRUE ); - } - else - { - EVENT_SoldierBeginCutFence( pSoldier, sAdjustedGridNo, ubDirection ); - } - - - if ( fFromUI ) - { - guiPendingOverrideEvent = A_CHANGE_TO_MOVE; - } - - return( ITEM_HANDLE_OK ); - } - else - { - return( ITEM_HANDLE_NOAPS ); - } + } } else { @@ -832,151 +840,151 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us } } - if ( Item[usHandItem].toolkit ) + if ( Item[usHandItem].toolkit ) { - UINT8 ubMercID; - BOOLEAN fVehicle = FALSE; - INT16 sVehicleGridNo=-1; + UINT8 ubMercID; + BOOLEAN fVehicle = FALSE; + INT16 sVehicleGridNo=-1; - // For repair, check if we are over a vehicle, then get gridnot to edge of that vehicle! - if ( IsRepairableStructAtGridNo( usGridNo, &ubMercID ) == 2 ) - { - INT16 sNewGridNo; - UINT8 ubDirection; - - sNewGridNo = FindGridNoFromSweetSpotWithStructDataFromSoldier( pSoldier, pSoldier->usUIMovementMode, 5, &ubDirection, 0, MercPtrs[ ubMercID ] ); - - if ( sNewGridNo != NOWHERE ) - { - usGridNo = sNewGridNo; - - sVehicleGridNo = MercPtrs[ ubMercID ]->sGridNo; - - fVehicle = TRUE; - } - } - - // See if we can get there to stab - sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); - - if ( sActionGridNo != -1 ) - { - // Calculate AP costs... - sAPCost = GetAPsToBeginRepair( pSoldier ); - sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints); - - if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) ) - { - // CHECK IF WE ARE AT THIS GRIDNO NOW - if ( pSoldier->sGridNo != sActionGridNo ) - { - // SEND PENDING ACTION - pSoldier->ubPendingAction = MERC_REPAIR; - pSoldier->sPendingActionData2 = sAdjustedGridNo; - - if ( fVehicle ) - { - pSoldier->sPendingActionData2 = sVehicleGridNo; - } - - pSoldier->bPendingActionData3 = ubDirection; - pSoldier->ubPendingActionAnimCount = 0; - - // WALK UP TO DEST FIRST - EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE ); - } - else - { - EVENT_SoldierBeginRepair( pSoldier, sAdjustedGridNo, ubDirection ); - } - - // OK, set UI - SetUIBusy( pSoldier->ubID ); - - if ( fFromUI ) - { - guiPendingOverrideEvent = A_CHANGE_TO_MOVE; - } - - return( ITEM_HANDLE_OK ); - } - else - { - return( ITEM_HANDLE_NOAPS ); - } - } - else + // For repair, check if we are over a vehicle, then get gridnot to edge of that vehicle! + if ( IsRepairableStructAtGridNo( usGridNo, &ubMercID ) == 2 ) { - return( ITEM_HANDLE_CANNOT_GETTO_LOCATION ); + INT16 sNewGridNo; + UINT8 ubDirection; + + sNewGridNo = FindGridNoFromSweetSpotWithStructDataFromSoldier( pSoldier, pSoldier->usUIMovementMode, 5, &ubDirection, 0, MercPtrs[ ubMercID ] ); + + if ( sNewGridNo != NOWHERE ) + { + usGridNo = sNewGridNo; + + sVehicleGridNo = MercPtrs[ ubMercID ]->sGridNo; + + fVehicle = TRUE; + } } - } - if ( Item[usHandItem].gascan ) - { - UINT8 ubMercID; - INT16 sVehicleGridNo=-1; + // See if we can get there to stab + sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); - // For repair, check if we are over a vehicle, then get gridnot to edge of that vehicle! - if ( IsRefuelableStructAtGridNo( usGridNo, &ubMercID ) ) - { - INT16 sNewGridNo; - UINT8 ubDirection; + if ( sActionGridNo != -1 ) + { + // Calculate AP costs... + sAPCost = GetAPsToBeginRepair( pSoldier ); + sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints); - sNewGridNo = FindGridNoFromSweetSpotWithStructDataFromSoldier( pSoldier, pSoldier->usUIMovementMode, 5, &ubDirection, 0, MercPtrs[ ubMercID ] ); - - if ( sNewGridNo != NOWHERE ) + if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) ) + { + // CHECK IF WE ARE AT THIS GRIDNO NOW + if ( pSoldier->sGridNo != sActionGridNo ) { - usGridNo = sNewGridNo; + // SEND PENDING ACTION + pSoldier->ubPendingAction = MERC_REPAIR; + pSoldier->sPendingActionData2 = sAdjustedGridNo; - sVehicleGridNo = MercPtrs[ ubMercID ]->sGridNo; - - } - } - - // See if we can get there to stab - sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); - - if ( sActionGridNo != -1 ) - { - // Calculate AP costs... - sAPCost = GetAPsToRefuelVehicle( pSoldier ); - sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints); - - if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) ) - { - // CHECK IF WE ARE AT THIS GRIDNO NOW - if ( pSoldier->sGridNo != sActionGridNo ) + if ( fVehicle ) { - // SEND PENDING ACTION - pSoldier->ubPendingAction = MERC_FUEL_VEHICLE; - pSoldier->sPendingActionData2 = sAdjustedGridNo; - pSoldier->sPendingActionData2 = sVehicleGridNo; - pSoldier->bPendingActionData3 = ubDirection; - pSoldier->ubPendingActionAnimCount = 0; - - // WALK UP TO DEST FIRST - EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE ); - } - else - { - EVENT_SoldierBeginRefuel( pSoldier, sAdjustedGridNo, ubDirection ); } - // OK, set UI - SetUIBusy( pSoldier->ubID ); + pSoldier->bPendingActionData3 = ubDirection; + pSoldier->ubPendingActionAnimCount = 0; - if ( fFromUI ) - { - guiPendingOverrideEvent = A_CHANGE_TO_MOVE; - } + // WALK UP TO DEST FIRST + EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE ); + } + else + { + EVENT_SoldierBeginRepair( pSoldier, sAdjustedGridNo, ubDirection ); + } - return( ITEM_HANDLE_OK ); - } - else - { - return( ITEM_HANDLE_NOAPS ); - } + // OK, set UI + SetUIBusy( pSoldier->ubID ); + + if ( fFromUI ) + { + guiPendingOverrideEvent = A_CHANGE_TO_MOVE; + } + + return( ITEM_HANDLE_OK ); + } + else + { + return( ITEM_HANDLE_NOAPS ); + } + } + else + { + return( ITEM_HANDLE_CANNOT_GETTO_LOCATION ); + } + } + + if ( Item[usHandItem].gascan ) + { + UINT8 ubMercID; + INT16 sVehicleGridNo=-1; + + // For repair, check if we are over a vehicle, then get gridnot to edge of that vehicle! + if ( IsRefuelableStructAtGridNo( usGridNo, &ubMercID ) ) + { + INT16 sNewGridNo; + UINT8 ubDirection; + + sNewGridNo = FindGridNoFromSweetSpotWithStructDataFromSoldier( pSoldier, pSoldier->usUIMovementMode, 5, &ubDirection, 0, MercPtrs[ ubMercID ] ); + + if ( sNewGridNo != NOWHERE ) + { + usGridNo = sNewGridNo; + + sVehicleGridNo = MercPtrs[ ubMercID ]->sGridNo; + + } + } + + // See if we can get there to stab + sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); + + if ( sActionGridNo != -1 ) + { + // Calculate AP costs... + sAPCost = GetAPsToRefuelVehicle( pSoldier ); + sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints); + + if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) ) + { + // CHECK IF WE ARE AT THIS GRIDNO NOW + if ( pSoldier->sGridNo != sActionGridNo ) + { + // SEND PENDING ACTION + pSoldier->ubPendingAction = MERC_FUEL_VEHICLE; + pSoldier->sPendingActionData2 = sAdjustedGridNo; + + pSoldier->sPendingActionData2 = sVehicleGridNo; + pSoldier->bPendingActionData3 = ubDirection; + pSoldier->ubPendingActionAnimCount = 0; + + // WALK UP TO DEST FIRST + EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE ); + } + else + { + EVENT_SoldierBeginRefuel( pSoldier, sAdjustedGridNo, ubDirection ); + } + + // OK, set UI + SetUIBusy( pSoldier->ubID ); + + if ( fFromUI ) + { + guiPendingOverrideEvent = A_CHANGE_TO_MOVE; + } + + return( ITEM_HANDLE_OK ); + } + else + { + return( ITEM_HANDLE_NOAPS ); + } } else { @@ -985,14 +993,73 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us } - if ( Item[usHandItem].jar ) + if ( Item[usHandItem].jar ) { - sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); + sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); - if ( sActionGridNo != -1 ) - { + if ( sActionGridNo != -1 ) + { + // Calculate AP costs... + sAPCost = GetAPsToUseJar( pSoldier, sActionGridNo ); + sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints); + + if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) ) + { + // CHECK IF WE ARE AT THIS GRIDNO NOW + if ( pSoldier->sGridNo != sActionGridNo ) + { + // SEND PENDING ACTION + pSoldier->ubPendingAction = MERC_TAKEBLOOD; + pSoldier->sPendingActionData2 = sAdjustedGridNo; + pSoldier->bPendingActionData3 = ubDirection; + pSoldier->ubPendingActionAnimCount = 0; + + // WALK UP TO DEST FIRST + EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE ); + } + else + { + EVENT_SoldierBeginTakeBlood( pSoldier, sAdjustedGridNo, ubDirection ); + } + + // OK, set UI + SetUIBusy( pSoldier->ubID ); + + if ( fFromUI ) + { + guiPendingOverrideEvent = A_CHANGE_TO_MOVE; + } + + return( ITEM_HANDLE_OK ); + } + else + { + return( ITEM_HANDLE_NOAPS ); + } + } + else + { + return( ITEM_HANDLE_CANNOT_GETTO_LOCATION ); + } + } + + if ( Item[usHandItem].canandstring ) + { + STRUCTURE *pStructure; + LEVELNODE *pIntTile; + + // Get structure info for in tile! + pIntTile = GetCurInteractiveTileGridNoAndStructure( (INT16 *)&usGridNo, &pStructure ); + + // We should not have null here if we are given this flag... + if ( pIntTile != NULL ) + { + sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, FALSE, TRUE ); + + if ( sActionGridNo != -1 ) + { // Calculate AP costs... - sAPCost = GetAPsToUseJar( pSoldier, sActionGridNo ); + sAPCost = AP_ATTACH_CAN; sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints); if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) ) @@ -1001,8 +1068,8 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us if ( pSoldier->sGridNo != sActionGridNo ) { // SEND PENDING ACTION - pSoldier->ubPendingAction = MERC_TAKEBLOOD; - pSoldier->sPendingActionData2 = sAdjustedGridNo; + pSoldier->ubPendingAction = MERC_ATTACH_CAN; + pSoldier->sPendingActionData2 = usGridNo; pSoldier->bPendingActionData3 = ubDirection; pSoldier->ubPendingActionAnimCount = 0; @@ -1011,7 +1078,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us } else { - EVENT_SoldierBeginTakeBlood( pSoldier, sAdjustedGridNo, ubDirection ); + EVENT_SoldierBeginTakeBlood( pSoldier, usGridNo, ubDirection ); } // OK, set UI @@ -1023,70 +1090,11 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us } return( ITEM_HANDLE_OK ); - } - else - { + } + else + { return( ITEM_HANDLE_NOAPS ); - } - } - else - { - return( ITEM_HANDLE_CANNOT_GETTO_LOCATION ); - } - } - - if ( Item[usHandItem].canandstring ) - { - STRUCTURE *pStructure; - LEVELNODE *pIntTile; - - // Get structure info for in tile! - pIntTile = GetCurInteractiveTileGridNoAndStructure( (INT16 *)&usGridNo, &pStructure ); - - // We should not have null here if we are given this flag... - if ( pIntTile != NULL ) - { - sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, FALSE, TRUE ); - - if ( sActionGridNo != -1 ) - { - // Calculate AP costs... - sAPCost = AP_ATTACH_CAN; - sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints); - - if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) ) - { - // CHECK IF WE ARE AT THIS GRIDNO NOW - if ( pSoldier->sGridNo != sActionGridNo ) - { - // SEND PENDING ACTION - pSoldier->ubPendingAction = MERC_ATTACH_CAN; - pSoldier->sPendingActionData2 = usGridNo; - pSoldier->bPendingActionData3 = ubDirection; - pSoldier->ubPendingActionAnimCount = 0; - - // WALK UP TO DEST FIRST - EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE ); - } - else - { - EVENT_SoldierBeginTakeBlood( pSoldier, usGridNo, ubDirection ); - } - - // OK, set UI - SetUIBusy( pSoldier->ubID ); - - if ( fFromUI ) - { - guiPendingOverrideEvent = A_CHANGE_TO_MOVE; - } - - return( ITEM_HANDLE_OK ); - } - else - { - return( ITEM_HANDLE_NOAPS ); - } + } } else { @@ -1095,7 +1103,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us } else { - return( ITEM_HANDLE_CANNOT_GETTO_LOCATION ); + return( ITEM_HANDLE_CANNOT_GETTO_LOCATION ); } } @@ -1109,7 +1117,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us DeductPoints( pSoldier, sAPCost, 0 ); if ( Item[usHandItem].xray ) { - PlayJA2Sample( USE_X_RAY_MACHINE, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); + PlayJA2Sample( USE_X_RAY_MACHINE, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); ActivateXRayDevice( pSoldier ); return( ITEM_HANDLE_OK ); @@ -1182,90 +1190,91 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us return( ITEM_HANDLE_OK ); } - + //USING THE BLADE if ( Item[ usHandItem ].usItemClass == IC_BLADE ) { - // See if we can get there to stab - if ( pSoldier->ubBodyType == BLOODCAT ) - { + // See if we can get there to stab + if ( pSoldier->ubBodyType == BLOODCAT ) + { sActionGridNo = FindNextToAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); - } - else if ( CREATURE_OR_BLOODCAT( pSoldier ) && PythSpacesAway( pSoldier->sGridNo, usGridNo ) > 1 ) - { + } + else if ( CREATURE_OR_BLOODCAT( pSoldier ) && PythSpacesAway( pSoldier->sGridNo, usGridNo ) > 1 ) + { sActionGridNo = FindNextToAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); if (sActionGridNo == -1) { - sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); + sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); } - } - else - { + } + else + { sActionGridNo = FindAdjacentGridEx( pSoldier, usGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); - } - - if ( sActionGridNo != -1 ) - { - pSoldier->usActionData = sActionGridNo; + } - // CHECK IF WE ARE AT THIS GRIDNO NOW - if ( pSoldier->sGridNo != sActionGridNo ) - { - // SEND PENDING ACTION - pSoldier->ubPendingAction = MERC_KNIFEATTACK; - pSoldier->sPendingActionData2 = sAdjustedGridNo; - pSoldier->bPendingActionData3 = ubDirection; - pSoldier->ubPendingActionAnimCount = 0; + if ( sActionGridNo != -1 ) + { + pSoldier->usActionData = sActionGridNo; - // WALK UP TO DEST FIRST - EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE ); - } - else - { - // for the benefit of the AI - pSoldier->bAction = AI_ACTION_KNIFE_STAB; - EVENT_SoldierBeginBladeAttack( pSoldier, sAdjustedGridNo, ubDirection ); - } + // CHECK IF WE ARE AT THIS GRIDNO NOW + if ( pSoldier->sGridNo != sActionGridNo ) + { + // SEND PENDING ACTION + pSoldier->ubPendingAction = MERC_KNIFEATTACK; + pSoldier->sPendingActionData2 = sAdjustedGridNo; + pSoldier->bPendingActionData3 = ubDirection; + pSoldier->ubPendingActionAnimCount = 0; - // OK, set UI - SetUIBusy( pSoldier->ubID ); + // WALK UP TO DEST FIRST + EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE ); + } + else + { + // for the benefit of the AI + pSoldier->bAction = AI_ACTION_KNIFE_STAB; + EVENT_SoldierBeginBladeAttack( pSoldier, sAdjustedGridNo, ubDirection ); + } - if ( fFromUI ) - { - guiPendingOverrideEvent = A_CHANGE_TO_MOVE; - gfResetUIMovementOptimization = TRUE; - } + // OK, set UI + SetUIBusy( pSoldier->ubID ); - return( ITEM_HANDLE_OK ); - } - else - { - return( ITEM_HANDLE_CANNOT_GETTO_LOCATION ); - } + if ( fFromUI ) + { + guiPendingOverrideEvent = A_CHANGE_TO_MOVE; + gfResetUIMovementOptimization = TRUE; + } + + return( ITEM_HANDLE_OK ); + } + else + { + return( ITEM_HANDLE_CANNOT_GETTO_LOCATION ); + } } if ( Item[ usHandItem ].usItemClass == IC_TENTACLES ) { - // See if we can get there to stab - //pSoldier->sTargetGridNo = sTargetGridNo; - //pSoldier->sLastTarget = sTargetGridNo; - //pSoldier->ubTargetID = WhoIsThere2( sTargetGridNo, pSoldier->bTargetLevel ); + // See if we can get there to stab + //pSoldier->sTargetGridNo = sTargetGridNo; + //pSoldier->sLastTarget = sTargetGridNo; + //pSoldier->ubTargetID = WhoIsThere2( sTargetGridNo, pSoldier->bTargetLevel ); - gTacticalStatus.ubAttackBusyCount++; - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting swipe attack, incrementing a.b.c in HandleItems to %d", gTacticalStatus.ubAttackBusyCount) ); +// gTacticalStatus.ubAttackBusyCount++; + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting swipe attack, incrementing a.b.c in HandleItems to %d", gTacticalStatus.ubAttackBusyCount) ); + DebugAttackBusy( "Swipe attack\n"); - sAPCost = CalcTotalAPsToAttack( pSoldier, sGridNo, FALSE, pSoldier->bAimTime ); + sAPCost = CalcTotalAPsToAttack( pSoldier, sGridNo, FALSE, pSoldier->bAimTime ); - DeductPoints( pSoldier, sAPCost, 0 ); + DeductPoints( pSoldier, sAPCost, 0 ); - EVENT_InitNewSoldierAnim( pSoldier, QUEEN_SWIPE, 0 , FALSE ); + EVENT_InitNewSoldierAnim( pSoldier, QUEEN_SWIPE, 0 , FALSE ); - //FireWeapon( pSoldier, sTargetGridNo ); - pSoldier->bAction = AI_ACTION_KNIFE_STAB; + //FireWeapon( pSoldier, sTargetGridNo ); + pSoldier->bAction = AI_ACTION_KNIFE_STAB; - return( ITEM_HANDLE_OK ); + return( ITEM_HANDLE_OK ); } @@ -1315,11 +1324,11 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us } /*else { - // If raising gun, don't charge turning! - if ( fAddingTurningCost ) - { - pSoldier->fDontChargeReadyAPs = TRUE; - } + // If raising gun, don't charge turning! + if ( fAddingTurningCost ) + { + pSoldier->fDontChargeReadyAPs = TRUE; + } }*/ } @@ -1338,7 +1347,9 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us pSoldier->ubTargetID = WhoIsThere2( sTargetGridNo, pSoldier->bTargetLevel ); // Increment attack counter... - gTacticalStatus.ubAttackBusyCount++; +// gTacticalStatus.ubAttackBusyCount++; + DebugAttackBusy( "Weapon fire\n"); + // ATE: Don't charge turning... pSoldier->fDontChargeTurningAPs = TRUE; @@ -1470,38 +1481,38 @@ void HandleSoldierThrowItem( SOLDIERTYPE *pSoldier, INT16 sGridNo ) // Alrighty, switch based on stance! switch( gAnimControl[ pSoldier->usAnimState ].ubHeight ) { - case ANIM_STAND: + case ANIM_STAND: - // CHECK IF WE ARE NOT ON THE SAME GRIDNO - if ( sGridNo == pSoldier->sGridNo ) + // CHECK IF WE ARE NOT ON THE SAME GRIDNO + if ( sGridNo == pSoldier->sGridNo ) + { + PickDropItemAnimation( pSoldier ); + } + else + { + // CHANGE DIRECTION AT LEAST + ubDirection = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier ); + + SoldierGotoStationaryStance( pSoldier ); + + EVENT_SetSoldierDesiredDirection( pSoldier, ubDirection ); + pSoldier->fTurningUntilDone = TRUE; + + // Draw item depending on distance from buddy + if ( GetRangeFromGridNoDiff( sGridNo, pSoldier->sGridNo ) < MIN_LOB_RANGE ) { - PickDropItemAnimation( pSoldier ); + pSoldier->usPendingAnimation = LOB_ITEM; } else { - // CHANGE DIRECTION AT LEAST - ubDirection = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier ); + pSoldier->usPendingAnimation = THROW_ITEM; + } - SoldierGotoStationaryStance( pSoldier ); - - EVENT_SetSoldierDesiredDirection( pSoldier, ubDirection ); - pSoldier->fTurningUntilDone = TRUE; - - // Draw item depending on distance from buddy - if ( GetRangeFromGridNoDiff( sGridNo, pSoldier->sGridNo ) < MIN_LOB_RANGE ) - { - pSoldier->usPendingAnimation = LOB_ITEM; - } - else - { - pSoldier->usPendingAnimation = THROW_ITEM; - } - - } - break; + } + break; // crouch throwing - case ANIM_PRONE: + case ANIM_PRONE: if ( sGridNo == pSoldier->sGridNo ) { // OK, JUST DROP ITEM! @@ -1518,31 +1529,31 @@ void HandleSoldierThrowItem( SOLDIERTYPE *pSoldier, INT16 sGridNo ) ChangeSoldierStance( pSoldier, ANIM_CROUCH ); case ANIM_CROUCH: - // CHECK IF WE ARE NOT ON THE SAME GRIDNO - if ( sGridNo == pSoldier->sGridNo ) + // CHECK IF WE ARE NOT ON THE SAME GRIDNO + if ( sGridNo == pSoldier->sGridNo ) + { + // OK, JUST DROP ITEM! + if ( pSoldier->pTempObject != NULL ) { - // OK, JUST DROP ITEM! - if ( pSoldier->pTempObject != NULL ) - { - AddItemToPool( sGridNo, pSoldier->pTempObject, 1, pSoldier->bLevel, 0, -1 ); - NotifySoldiersToLookforItems( ); + AddItemToPool( sGridNo, pSoldier->pTempObject, 1, pSoldier->bLevel, 0, -1 ); + NotifySoldiersToLookforItems( ); - MemFree( pSoldier->pTempObject ); - pSoldier->pTempObject = NULL; - } + MemFree( pSoldier->pTempObject ); + pSoldier->pTempObject = NULL; } - else - { + } + else + { // CHANGE DIRECTION AT LEAST - ubDirection = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier ); + ubDirection = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier ); SoldierGotoStationaryStance( pSoldier ); - EVENT_SetSoldierDesiredDirection( pSoldier, ubDirection ); + EVENT_SetSoldierDesiredDirection( pSoldier, ubDirection ); pSoldier->fTurningUntilDone = TRUE; pSoldier->usPendingAnimation = THROW_ITEM_CROUCHED; - } + } break; // } @@ -1555,52 +1566,52 @@ void SoldierGiveItem( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pTargetSoldier, OBJECT INT16 sActionGridNo, sAdjustedGridNo; UINT8 ubDirection; - // Remove any previous actions - pSoldier->ubPendingAction = NO_PENDING_ACTION; + // Remove any previous actions + pSoldier->ubPendingAction = NO_PENDING_ACTION; - // See if we can get there to stab - sActionGridNo = FindAdjacentGridEx( pSoldier, pTargetSoldier->sGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); - if ( sActionGridNo != -1 ) - { - // SEND PENDING ACTION - pSoldier->ubPendingAction = MERC_GIVEITEM; + // See if we can get there to stab + sActionGridNo = FindAdjacentGridEx( pSoldier, pTargetSoldier->sGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); + if ( sActionGridNo != -1 ) + { + // SEND PENDING ACTION + pSoldier->ubPendingAction = MERC_GIVEITEM; - pSoldier->bPendingActionData5 = bInvPos; - // Copy temp object - pSoldier->pTempObject = (OBJECTTYPE *)MemAlloc( sizeof( OBJECTTYPE ) ); - memcpy( pSoldier->pTempObject, pObject, sizeof( OBJECTTYPE ) ); + pSoldier->bPendingActionData5 = bInvPos; + // Copy temp object + pSoldier->pTempObject = (OBJECTTYPE *)MemAlloc( sizeof( OBJECTTYPE ) ); + memcpy( pSoldier->pTempObject, pObject, sizeof( OBJECTTYPE ) ); - pSoldier->sPendingActionData2 = pTargetSoldier->sGridNo; - pSoldier->bPendingActionData3 = ubDirection; - pSoldier->uiPendingActionData4 = pTargetSoldier->ubID; - pSoldier->ubPendingActionAnimCount = 0; + pSoldier->sPendingActionData2 = pTargetSoldier->sGridNo; + pSoldier->bPendingActionData3 = ubDirection; + pSoldier->uiPendingActionData4 = pTargetSoldier->ubID; + pSoldier->ubPendingActionAnimCount = 0; - // Set soldier as engaged! - pSoldier->uiStatusFlags |= SOLDIER_ENGAGEDINACTION; + // Set soldier as engaged! + pSoldier->uiStatusFlags |= SOLDIER_ENGAGEDINACTION; - // CHECK IF WE ARE AT THIS GRIDNO NOW - if ( pSoldier->sGridNo != sActionGridNo ) - { - // WALK UP TO DEST FIRST - EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE ); - } - else - { - EVENT_SoldierBeginGiveItem( pSoldier ); - // CHANGE DIRECTION OF TARGET TO OPPOSIDE DIRECTION! - EVENT_SetSoldierDesiredDirection( pSoldier, ubDirection ); - } + // CHECK IF WE ARE AT THIS GRIDNO NOW + if ( pSoldier->sGridNo != sActionGridNo ) + { + // WALK UP TO DEST FIRST + EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE ); + } + else + { + EVENT_SoldierBeginGiveItem( pSoldier ); + // CHANGE DIRECTION OF TARGET TO OPPOSIDE DIRECTION! + EVENT_SetSoldierDesiredDirection( pSoldier, ubDirection ); + } - // Set target as engaged! - pTargetSoldier->uiStatusFlags |= SOLDIER_ENGAGEDINACTION; + // Set target as engaged! + pTargetSoldier->uiStatusFlags |= SOLDIER_ENGAGEDINACTION; - return; - } - else - { - return; - } + return; + } + else + { + return; + } } BOOLEAN SoldierDropItem( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj ) @@ -1699,7 +1710,7 @@ void SoldierGetItemFromWorld( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT16 sGr INT32 iItemIndexToDelete; BOOLEAN fShouldSayCoolQuote = FALSE; BOOLEAN fDidSayCoolQuote = FALSE; - BOOLEAN fSaidBoobyTrapQuote = FALSE; + BOOLEAN fSaidBoobyTrapQuote = FALSE; // OK. CHECK IF WE ARE DOING ALL IN THIS POOL.... if ( iItemIndex == ITEM_PICKUP_ACTION_ALL || iItemIndex == ITEM_PICKUP_SELECTION ) @@ -1721,7 +1732,7 @@ void SoldierGetItemFromWorld( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT16 sGr fPickup = FALSE; } } - + // Increment counter... //:ATE: Only incremrnt counter for items we can see.. cnt++; @@ -1767,18 +1778,18 @@ void SoldierGetItemFromWorld( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT16 sGr // handle theft.. will return true if theft has failed ( if soldier was caught ) if( pSoldier->bTeam == OUR_TEAM ) { - // check to see if object was owned by another - if( Object.fFlags & OBJECT_OWNED_BY_CIVILIAN ) - { - // owned by a civilian - if( HandleLoyaltyAdjustmentForRobbery( pSoldier ) == TRUE ) - { - // implememnt actual tactical reaction for theft..shoot robber, yell out, etc - } + // check to see if object was owned by another + if( Object.fFlags & OBJECT_OWNED_BY_CIVILIAN ) + { + // owned by a civilian + if( HandleLoyaltyAdjustmentForRobbery( pSoldier ) == TRUE ) + { + // implememnt actual tactical reaction for theft..shoot robber, yell out, etc + } - // reset who owns object - Object.fFlags &= ~( OBJECT_OWNED_BY_CIVILIAN ); - } + // reset who owns object + Object.fFlags &= ~( OBJECT_OWNED_BY_CIVILIAN ); + } } */ @@ -1840,24 +1851,24 @@ void SoldierGetItemFromWorld( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT16 sGr } else { -/* + /* // handle theft.. will return true if theft has failed ( if soldier was caught ) if( pSoldier->bTeam == OUR_TEAM ) { - // check to see if object was owned by another - if( Object.fFlags & OBJECT_OWNED_BY_CIVILIAN ) - { - // owned by a civilian - if( HandleLoyaltyAdjustmentForRobbery( pSoldier ) == TRUE ) - { - // implememnt actual tactical reaction for theft..shoot robber, yell out, etc - } - - // reset who owns object - Object.fFlags &= ~( OBJECT_OWNED_BY_CIVILIAN ); - } + // check to see if object was owned by another + if( Object.fFlags & OBJECT_OWNED_BY_CIVILIAN ) + { + // owned by a civilian + if( HandleLoyaltyAdjustmentForRobbery( pSoldier ) == TRUE ) + { + // implememnt actual tactical reaction for theft..shoot robber, yell out, etc } -*/ + + // reset who owns object + Object.fFlags &= ~( OBJECT_OWNED_BY_CIVILIAN ); + } + } + */ RemoveItemFromPool( sGridNo, iItemIndex, pSoldier->bLevel ); if ( !AutoPlaceObject( pSoldier, &(gWorldItems[ iItemIndex ].o ), TRUE ) ) @@ -1902,8 +1913,8 @@ void SoldierGetItemFromWorld( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT16 sGr // OK partner......look for any hidden items! if ( pSoldier->bTeam == gbPlayerNum && LookForHiddenItems( sGridNo, pSoldier->bLevel, TRUE, 0 ) ) { - // WISDOM GAIN (5): Found a hidden object - StatChange( pSoldier, WISDOMAMT, 5, FALSE ); + // WISDOM GAIN (5): Found a hidden object + StatChange( pSoldier, WISDOMAMT, 5, FALSE ); // We've found something! TacticalCharacterDialogue( pSoldier, (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ) ); @@ -2117,7 +2128,7 @@ OBJECTTYPE* InternalAddItemToPool( INT16 *psGridNo, OBJECTTYPE *pObject, INT8 bV LEVELNODE *pNode; BOOLEAN fForceOnGround = FALSE; BOOLEAN fObjectInOpenable = FALSE; - INT8 bTerrainID; + INT8 bTerrainID; Assert( pObject->ubNumberOfObjects <= MAX_OBJECTS_PER_SLOT); @@ -2127,7 +2138,7 @@ OBJECTTYPE* InternalAddItemToPool( INT16 *psGridNo, OBJECTTYPE *pObject, INT8 bV // Display warning..... ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Error: Item %d was given invalid grid location %d for item pool. Please Report.", pObject->usItem, (*psGridNo) ); - (*psGridNo) = sNewGridNo = gMapInformation.sCenterGridNo; + (*psGridNo) = sNewGridNo = gMapInformation.sCenterGridNo; //return( NULL ); } @@ -2137,9 +2148,9 @@ OBJECTTYPE* InternalAddItemToPool( INT16 *psGridNo, OBJECTTYPE *pObject, INT8 bV // IF SO, DONT'T ADD! bTerrainID = GetTerrainType( *psGridNo ); - if ( bTerrainID == DEEP_WATER || bTerrainID == LOW_WATER || bTerrainID == MED_WATER ) - { -// if ( Item[ pObject->usItem ].fFlags & ITEM_SINKS ) + if ( bTerrainID == DEEP_WATER || bTerrainID == LOW_WATER || bTerrainID == MED_WATER ) + { + // if ( Item[ pObject->usItem ].fFlags & ITEM_SINKS ) if ( Item[ pObject->usItem ].sinks ) { return( NULL ); @@ -2181,10 +2192,10 @@ OBJECTTYPE* InternalAddItemToPool( INT16 *psGridNo, OBJECTTYPE *pObject, INT8 bV // Adjust the item's gridno to the base of struct..... pBase = FindBaseStructure( pStructure ); - + // Get LEVELNODE for struct and remove! sNewGridNo = pBase->sGridNo; - + // Check for openable flag.... if ( pStructure->fFlags & STRUCTURE_OPENABLE ) { @@ -2220,35 +2231,35 @@ OBJECTTYPE* InternalAddItemToPool( INT16 *psGridNo, OBJECTTYPE *pObject, INT8 bV // Find most dence area... if ( StructureDensity( pStructure, &ubLevel0, &ubLevel1, &ubLevel2, &ubLevel3 ) ) { - if ( ubLevel3 == 0 && ubLevel2 == 0 && ubLevel1 == 0 && ubLevel0 == 0 ) - { - bRenderZHeightAboveLevel = 0; - } - else if ( ubLevel3 >= ubLevel0 && ubLevel3 >= ubLevel2 && ubLevel3 >= ubLevel1 ) - { - bRenderZHeightAboveLevel = CONVERT_INDEX_TO_PIXELS( 4 ); - } - else if ( ubLevel2 >= ubLevel0 && ubLevel2 >= ubLevel1 && ubLevel2 >= ubLevel3 ) - { - bRenderZHeightAboveLevel = CONVERT_INDEX_TO_PIXELS( 3 ); - } - else if ( ubLevel1 >= ubLevel0 && ubLevel1 >= ubLevel2 && ubLevel1 >= ubLevel3 ) - { - bRenderZHeightAboveLevel = CONVERT_INDEX_TO_PIXELS( 2 ); - } - else if ( ubLevel0 >= ubLevel1 && ubLevel0 >= ubLevel2 && ubLevel0 >= ubLevel3 ) - { - bRenderZHeightAboveLevel = CONVERT_INDEX_TO_PIXELS( 1 ); - } + if ( ubLevel3 == 0 && ubLevel2 == 0 && ubLevel1 == 0 && ubLevel0 == 0 ) + { + bRenderZHeightAboveLevel = 0; + } + else if ( ubLevel3 >= ubLevel0 && ubLevel3 >= ubLevel2 && ubLevel3 >= ubLevel1 ) + { + bRenderZHeightAboveLevel = CONVERT_INDEX_TO_PIXELS( 4 ); + } + else if ( ubLevel2 >= ubLevel0 && ubLevel2 >= ubLevel1 && ubLevel2 >= ubLevel3 ) + { + bRenderZHeightAboveLevel = CONVERT_INDEX_TO_PIXELS( 3 ); + } + else if ( ubLevel1 >= ubLevel0 && ubLevel1 >= ubLevel2 && ubLevel1 >= ubLevel3 ) + { + bRenderZHeightAboveLevel = CONVERT_INDEX_TO_PIXELS( 2 ); + } + else if ( ubLevel0 >= ubLevel1 && ubLevel0 >= ubLevel2 && ubLevel0 >= ubLevel3 ) + { + bRenderZHeightAboveLevel = CONVERT_INDEX_TO_PIXELS( 1 ); + } } - + // Set flag indicating it has an item on top! pStructure->fFlags |= STRUCTURE_HASITEMONTOP; break; } } - + pStructure = FindNextStructure( pStructure, STRUCTURE_BLOCKSMOVES ); } } @@ -2279,13 +2290,13 @@ OBJECTTYPE* InternalAddItemToPool( INT16 *psGridNo, OBJECTTYPE *pObject, INT8 bV { switch( pObject->bActionValue ) { - case ACTION_ITEM_SMALL_PIT: - case ACTION_ITEM_LARGE_PIT: - // mark as known about by civs and creatures - gpWorldLevelData[ sNewGridNo ].uiFlags |= MAPELEMENT_ENEMY_MINE_PRESENT; - break; - default: - break; + case ACTION_ITEM_SMALL_PIT: + case ACTION_ITEM_LARGE_PIT: + // mark as known about by civs and creatures + gpWorldLevelData[ sNewGridNo ].uiFlags |= MAPELEMENT_ENEMY_MINE_PRESENT; + break; + default: + break; } } @@ -2386,7 +2397,7 @@ OBJECTTYPE* InternalAddItemToPool( INT16 *psGridNo, OBJECTTYPE *pObject, INT8 bV { *piItemIndex = iWorldItem; } - + return( &(gWorldItems[ iWorldItem ].o ) ); } @@ -2400,7 +2411,7 @@ BOOLEAN ItemExistsAtLocation( INT16 sGridNo, INT32 iItemIndex, UINT8 ubLevel ) // Check for an existing pool on the object layer if ( GetItemPool( sGridNo, &pItemPool, ubLevel ) ) { - // LOOP THROUGH LIST TO FIND NODE WE WANT + // LOOP THROUGH LIST TO FIND NODE WE WANT pItemPoolTemp = pItemPool; while( pItemPoolTemp != NULL ) { @@ -2425,7 +2436,7 @@ BOOLEAN ItemTypeExistsAtLocation( INT16 sGridNo, UINT16 usItem, UINT8 ubLevel, I // Check for an existing pool on the object layer if ( GetItemPool( sGridNo, &pItemPool, ubLevel ) ) { - // LOOP THROUGH LIST TO FIND ITEM WE WANT + // LOOP THROUGH LIST TO FIND ITEM WE WANT pItemPoolTemp = pItemPool; while( pItemPoolTemp != NULL ) { @@ -2454,7 +2465,7 @@ BOOLEAN MarblesExistAtLocation( INT16 sGridNo, UINT8 ubLevel, INT32 * piItemInde // Check for an existing pool on the object layer if ( GetItemPool( sGridNo, &pItemPool, ubLevel ) ) { - // LOOP THROUGH LIST TO FIND ITEM WE WANT + // LOOP THROUGH LIST TO FIND ITEM WE WANT pItemPoolTemp = pItemPool; while( pItemPoolTemp != NULL ) { @@ -2484,7 +2495,7 @@ INT32 GetItemOfClassTypeInPool( INT16 sGridNo, UINT32 uiItemClass, UINT8 ubLevel // Check for an existing pool on the object layer if ( GetItemPool( sGridNo, &pItemPool, ubLevel ) ) { - // LOOP THROUGH LIST TO FIND NODE WE WANT + // LOOP THROUGH LIST TO FIND NODE WE WANT pItemPoolTemp = pItemPool; while( pItemPoolTemp != NULL ) { @@ -2509,7 +2520,7 @@ ITEM_POOL * GetItemPoolForIndex( INT16 sGridNo, INT32 iItemIndex, UINT8 ubLevel // Check for an existing pool on the object layer if ( GetItemPool( sGridNo, &pItemPool, ubLevel ) ) { - // LOOP THROUGH LIST TO FIND NODE WE WANT + // LOOP THROUGH LIST TO FIND NODE WE WANT pItemPoolTemp = pItemPool; while( pItemPoolTemp != NULL ) { @@ -2576,7 +2587,7 @@ BOOLEAN LookForHiddenItems( INT16 sGridNo, INT8 ubLevel, BOOLEAN fSetLocator, IN if ( gWorldItems[ pItemPool->iItemIndex ].bVisible == HIDDEN_ITEM && gWorldItems[ pItemPool->iItemIndex ].o.usItem != OWNERSHIP ) { fFound = TRUE; - + gWorldItems[ pItemPool->iItemIndex ].bVisible = INVISIBLE; } @@ -2777,34 +2788,34 @@ BOOLEAN SetItemPoolVisibilityOn( ITEM_POOL *pItemPool, INT8 bAllGreaterThan, BOO /* if ( gWorldItems[ pItemPoolTemp->iItemIndex ].o.usItem == ACTION_ITEM ) { - pObj = &(gWorldItems[ pItemPoolTemp->iItemIndex ].o); - switch( pObj->bActionValue ) - { - case ACTION_ITEM_SMALL_PIT: - case ACTION_ITEM_LARGE_PIT: - if (pObj->bDetonatorType == 0) - { - // randomly set to active or destroy the item! - if (Random( 100 ) < 65) - { - ArmBomb( pObj, 0 ); // will be set to pressure type so freq is irrelevant - gWorldItems[ pItemPoolTemp->iItemIndex ].usFlags |= WORLD_ITEM_ARMED_BOMB; - AddBombToWorld( pItemPoolTemp->iItemIndex ); - } - else - { - // get pointer to the next element NOW - pItemPoolTemp = pItemPoolTemp->pNext; - // set flag so we don't traverse an additional time - fDeleted = TRUE; - // remove item from pool - RemoveItemFromPool( pItemPool->sGridNo, pItemPool->iItemIndex, pItemPool->ubLevel ); - } - } - break; - default: - break; - } + pObj = &(gWorldItems[ pItemPoolTemp->iItemIndex ].o); + switch( pObj->bActionValue ) + { + case ACTION_ITEM_SMALL_PIT: + case ACTION_ITEM_LARGE_PIT: + if (pObj->bDetonatorType == 0) + { + // randomly set to active or destroy the item! + if (Random( 100 ) < 65) + { + ArmBomb( pObj, 0 ); // will be set to pressure type so freq is irrelevant + gWorldItems[ pItemPoolTemp->iItemIndex ].usFlags |= WORLD_ITEM_ARMED_BOMB; + AddBombToWorld( pItemPoolTemp->iItemIndex ); + } + else + { + // get pointer to the next element NOW + pItemPoolTemp = pItemPoolTemp->pNext; + // set flag so we don't traverse an additional time + fDeleted = TRUE; + // remove item from pool + RemoveItemFromPool( pItemPool->sGridNo, pItemPool->iItemIndex, pItemPool->ubLevel ); + } + } + break; + default: + break; + } } */ @@ -2929,7 +2940,7 @@ BOOLEAN RemoveItemFromPool( INT16 sGridNo, INT32 iItemIndex, UINT8 ubLevel ) { // REMOVE FROM LIST - + // LOOP THROUGH LIST TO FIND NODE WE WANT pItemPoolTemp = pItemPool; while( pItemPoolTemp != NULL ) @@ -3014,7 +3025,7 @@ BOOLEAN RemoveItemFromPool( INT16 sGridNo, INT32 iItemIndex, UINT8 ubLevel ) if ( !GetItemPool( pItemPoolTemp->sGridNo, &pTempPool, pItemPoolTemp->ubLevel ) ) { pStructure = FindStructure( pItemPoolTemp->sGridNo , STRUCTURE_HASITEMONTOP ); - + if ( pStructure != NULL ) { // Remove... @@ -3032,7 +3043,7 @@ BOOLEAN RemoveItemFromPool( INT16 sGridNo, INT32 iItemIndex, UINT8 ubLevel ) MemFree( pItemPoolTemp ); RemoveItemFromWorld( iItemIndex ); - + return( TRUE ); } @@ -3189,7 +3200,7 @@ BOOLEAN ItemPoolOKForDisplay( ITEM_POOL *pItemPool, INT8 bZLevel ) // If -1, it means find all if ( pItemPool->bRenderZHeightAboveLevel != bZLevel && bZLevel != -1 ) - { + { return( FALSE ); } @@ -3214,7 +3225,7 @@ BOOLEAN ItemPoolOKForPickup( SOLDIERTYPE * pSoldier, ITEM_POOL *pItemPool, INT8 // If -1, it means find all if ( pItemPool->bRenderZHeightAboveLevel != bZLevel && bZLevel != -1 ) - { + { return( FALSE ); } @@ -3307,10 +3318,10 @@ BOOLEAN DrawItemPoolList( ITEM_POOL *pItemPool, INT16 sGridNo, UINT8 bCommand, I { cnt++; } - + bNumItemsListed = (INT8)cnt; - + //RENDER LIST! // Determine max length pTempItemPool = pItemPool; @@ -3457,11 +3468,11 @@ BOOLEAN DrawItemPoolList( ITEM_POOL *pItemPool, INT16 sGridNo, UINT8 bCommand, I } if ( fDoBack ) { - if ( cnt == ( bNumItemsListed - 1) ) + if ( cnt == ( bNumItemsListed - 1) ) + { + // Set string + if ( cnt == gbCurrentItemSel ) { - // Set string - if ( cnt == gbCurrentItemSel ) - { SetFontForeground( FONT_MCOLOR_LTGRAY ); } else @@ -3472,7 +3483,7 @@ BOOLEAN DrawItemPoolList( ITEM_POOL *pItemPool, INT16 sGridNo, UINT8 bCommand, I gprintfdirty( sFontX, sY, pStr ); mprintf( sFontX, sY, pStr ); } - } + } return( fSelectionDone ); @@ -3518,7 +3529,7 @@ INT8 GetListMouseHotSpot( INT16 sLargestLineWidth, INT8 bNumItemsListed, INT16 s // OFFSET START gbCurrentItemSel += bCurStart; - + return( gbCurrentItemSel ); } @@ -3577,7 +3588,7 @@ INT32 GetFreeFlashItemSlot(void) void RecountFlashItemSlots(void) { -INT32 uiCount; + INT32 uiCount; for(uiCount=guiNumFlashItemSlots-1; (uiCount >=0) ; uiCount--) { @@ -3652,100 +3663,100 @@ void HandleFlashingItems( ) if ( COUNTERDONE( CYCLERENDERITEMCOLOR ) ) { - RESETCOUNTER( CYCLERENDERITEMCOLOR ); + RESETCOUNTER( CYCLERENDERITEMCOLOR ); - for ( cnt = 0; cnt < guiNumFlashItemSlots; cnt++ ) + for ( cnt = 0; cnt < guiNumFlashItemSlots; cnt++ ) + { + pLocator = &( FlashItemSlots[ cnt ] ); + + if ( pLocator->fAllocated ) { - pLocator = &( FlashItemSlots[ cnt ] ); + fDoLocator = TRUE; - if ( pLocator->fAllocated ) + if ( ( pLocator->ubFlags & ITEM_LOCATOR_LOCKED ) ) + { + if ( gTacticalStatus.fLockItemLocators == FALSE ) { - fDoLocator = TRUE; + // Turn off! + pLocator->ubFlags &= (~ITEM_LOCATOR_LOCKED); + } + else + { + fDoLocator = FALSE; + } + } - if ( ( pLocator->ubFlags & ITEM_LOCATOR_LOCKED ) ) + if ( fDoLocator ) + { + pItemPool = pLocator->pItemPool; + + // Update radio locator + { + UINT32 uiClock; + + uiClock = GetJA2Clock( ); + + // Update frame values! + if ( ( uiClock - pLocator->uiLastFrameUpdate ) > 80 ) { - if ( gTacticalStatus.fLockItemLocators == FALSE ) + pLocator->uiLastFrameUpdate = uiClock; + + // Update frame + pLocator->bRadioFrame++; + + if ( pLocator->bRadioFrame == 5 ) { - // Turn off! - pLocator->ubFlags &= (~ITEM_LOCATOR_LOCKED); - } - else - { - fDoLocator = FALSE; - } - } - - if ( fDoLocator ) - { - pItemPool = pLocator->pItemPool; - - // Update radio locator - { - UINT32 uiClock; - - uiClock = GetJA2Clock( ); - - // Update frame values! - if ( ( uiClock - pLocator->uiLastFrameUpdate ) > 80 ) - { - pLocator->uiLastFrameUpdate = uiClock; - - // Update frame - pLocator->bRadioFrame++; - - if ( pLocator->bRadioFrame == 5 ) - { - pLocator->bRadioFrame = 0; - } - } - } - - // UPDATE FLASH COLOR VALUE - pItemPool->bFlashColor--; - - if ( pItemPool->ubLevel == 0 ) - { - pObject = gpWorldLevelData[ pItemPool->sGridNo ].pStructHead; - } - else - { - pObject = gpWorldLevelData[ pItemPool->sGridNo ].pOnRoofHead; - } - - // LOOP THORUGH OBJECT LAYER - while( pObject != NULL ) - { - if ( pObject->uiFlags & LEVELNODE_ITEM ) - { - if ( pItemPool->bFlashColor == 1 ) - { - //pObject->uiFlags &= (~LEVELNODE_DYNAMIC); - //pObject->uiFlags |= ( LEVELNODE_LASTDYNAMIC ); - } - else - { - //pObject->uiFlags |= LEVELNODE_DYNAMIC; - } - - } - - pObject = pObject->pNext; - } - - if ( pItemPool->bFlashColor == 1 ) - { - pItemPool->bFlashColor = 0; - - // REMOVE TIMER! - RemoveFlashItemSlot( pItemPool ); - - SetRenderFlags( RENDER_FLAG_FULL ); + pLocator->bRadioFrame = 0; } } } - } - RecountFlashItemSlots( ); + // UPDATE FLASH COLOR VALUE + pItemPool->bFlashColor--; + + if ( pItemPool->ubLevel == 0 ) + { + pObject = gpWorldLevelData[ pItemPool->sGridNo ].pStructHead; + } + else + { + pObject = gpWorldLevelData[ pItemPool->sGridNo ].pOnRoofHead; + } + + // LOOP THORUGH OBJECT LAYER + while( pObject != NULL ) + { + if ( pObject->uiFlags & LEVELNODE_ITEM ) + { + if ( pItemPool->bFlashColor == 1 ) + { + //pObject->uiFlags &= (~LEVELNODE_DYNAMIC); + //pObject->uiFlags |= ( LEVELNODE_LASTDYNAMIC ); + } + else + { + //pObject->uiFlags |= LEVELNODE_DYNAMIC; + } + + } + + pObject = pObject->pNext; + } + + if ( pItemPool->bFlashColor == 1 ) + { + pItemPool->bFlashColor = 0; + + // REMOVE TIMER! + RemoveFlashItemSlot( pItemPool ); + + SetRenderFlags( RENDER_FLAG_FULL ); + } + } + } + } + + RecountFlashItemSlots( ); } @@ -3914,19 +3925,19 @@ void SoldierGiveItemFromAnimation( SOLDIERTYPE *pSoldier ) bInvPos = pSoldier->bPendingActionData5; usItemNum = TempObject.usItem; - // ATE: OK, check if we have an item in the cursor from - // this soldier and from this inv slot, if so, delete!!!!!!! - if ( gpItemPointer != NULL ) - { - if ( pSoldier->ubID == gpItemPointerSoldier->ubID ) - { - if ( bInvPos == gbItemPointerSrcSlot && usItemNum == gpItemPointer->usItem ) - { - // Remove!!! - EndItemPointer( ); - } - } - } + // ATE: OK, check if we have an item in the cursor from + // this soldier and from this inv slot, if so, delete!!!!!!! + if ( gpItemPointer != NULL ) + { + if ( pSoldier->ubID == gpItemPointerSoldier->ubID ) + { + if ( bInvPos == gbItemPointerSrcSlot && usItemNum == gpItemPointer->usItem ) + { + // Remove!!! + EndItemPointer( ); + } + } + } sGridNo = pSoldier->sPendingActionData2; ubDirection = pSoldier->bPendingActionData3; @@ -3948,9 +3959,9 @@ void SoldierGiveItemFromAnimation( SOLDIERTYPE *pSoldier ) /* if( pTSoldier->ubProfile == MICKY ) { - //and the items are alcohol, dont enter the shopkeeper - if( GetArmsDealerItemTypeFromItemNumber( TempObject.usItem ) == ARMS_DEALER_ALCOHOL ) - return; + //and the items are alcohol, dont enter the shopkeeper + if( GetArmsDealerItemTypeFromItemNumber( TempObject.usItem ) == ARMS_DEALER_ALCOHOL ) + return; } */ @@ -3963,8 +3974,8 @@ void SoldierGiveItemFromAnimation( SOLDIERTYPE *pSoldier ) /* else if ( NPCWillingToAcceptItem( pTSoldier->ubProfile, pSoldier->ubProfile, &TempObject ) ) { - TriggerNPCWithGivenApproach( pTSoldier->ubProfile, APPROACH_GIVINGITEM, TRUE ); - return; + TriggerNPCWithGivenApproach( pTSoldier->ubProfile, APPROACH_GIVINGITEM, TRUE ); + return; }*/ else if ( !NPCWillingToAcceptItem( pTSoldier->ubProfile, pSoldier->ubProfile, &TempObject ) ) { @@ -3972,18 +3983,18 @@ void SoldierGiveItemFromAnimation( SOLDIERTYPE *pSoldier ) //Enter the shopkeeper interface EnterShopKeeperInterfaceScreen( pTSoldier->ubProfile ); -// removed the if, because if the player picked up an item straight from the ground or money strait from the money -// interface, the item would NOT have a bInvPos, therefore it would not get added to the dealer, and would get deleted -// if ( bInvPos != NO_SLOT ) + // removed the if, because if the player picked up an item straight from the ground or money strait from the money + // interface, the item would NOT have a bInvPos, therefore it would not get added to the dealer, and would get deleted + // if ( bInvPos != NO_SLOT ) { // MUST send in NO_SLOT, as the SKI wille expect it to exist in inv if not.... AddItemToPlayersOfferAreaAfterShopKeeperOpen( &TempObject, NO_SLOT ); -/* -Changed because if the player gave 1 item from a pile, the rest of the items in the piule would disappear + /* + Changed because if the player gave 1 item from a pile, the rest of the items in the piule would disappear // OK, r emove the item, as the SKI will give it back once done DeleteObj( &( pSoldier->inv[ bInvPos ] ) ); -*/ + */ if ( bInvPos != NO_SLOT ) @@ -4028,7 +4039,7 @@ Changed because if the player gave 1 item from a pile, the rest of the items in DeleteObj( &( pSoldier->inv[ bInvPos ] ) ); DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); } - + AddItemToPool( pSoldier->sGridNo, &TempObject, 1, pSoldier->bLevel, 0 , -1 ); // We could not place it! @@ -4105,7 +4116,7 @@ INT16 AdjustGridNoForItemPlacement( SOLDIERTYPE *pSoldier, INT16 sGridNo ) INT16 sAdjustedGridNo; UINT8 ubTargetID; - + sActionGridNo = sGridNo; // Check structure database @@ -4145,7 +4156,7 @@ INT16 AdjustGridNoForItemPlacement( SOLDIERTYPE *pSoldier, INT16 sGridNo ) return( sActionGridNo ); } - + void StartBombMessageBox( SOLDIERTYPE * pSoldier, INT16 sGridNo ) { @@ -4163,13 +4174,13 @@ void StartBombMessageBox( SOLDIERTYPE * pSoldier, INT16 sGridNo ) /* switch( pSoldier->inv[HANDPOS].ubLocationID ) { - // check to make sure the appropriate sector is loaded + // check to make sure the appropriate sector is loaded } SetOffBombsByFrequency( pSoldier->ubID, pSoldier->inv[HANDPOS].bFrequency ); */ - - // PLay sound.... - PlayJA2Sample( USE_STATUE_REMOTE, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); + + // PLay sound.... + PlayJA2Sample( USE_STATUE_REMOTE, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); // Check what sector we are in.... @@ -4277,13 +4288,13 @@ BOOLEAN HandItemWorks( SOLDIERTYPE *pSoldier, INT8 bSlot ) { BOOLEAN fItemJustBroke = FALSE, fItemWorks = TRUE; OBJECTTYPE * pObj; - + pObj = &( pSoldier->inv[ bSlot ] ); // if the item can be damaged, than we must check that it's in good enough // shape to be usable, and doesn't break during use. // Exception: land mines. You can bury them broken, they just won't blow! -// if ( (Item[ pObj->usItem ].fFlags & ITEM_DAMAGEABLE) && (pObj->usItem != MINE) && (Item[ pObj->usItem ].usItemClass != IC_MEDKIT) && pObj->usItem != GAS_CAN ) + // if ( (Item[ pObj->usItem ].fFlags & ITEM_DAMAGEABLE) && (pObj->usItem != MINE) && (Item[ pObj->usItem ].usItemClass != IC_MEDKIT) && pObj->usItem != GAS_CAN ) if ( (Item[ pObj->usItem ].damageable ) && (!Item[pObj->usItem].mine ) && (Item[ pObj->usItem ].usItemClass != IC_MEDKIT) && !Item[pObj->usItem].gascan ) { // if it's still usable, check whether it breaks @@ -4378,7 +4389,7 @@ BOOLEAN ContinuePastBoobyTrap( SOLDIERTYPE * pSoldier, INT16 sGridNo, INT8 bLeve pObj = &(gWorldItems[ iItemIndex ].o); - (*pfSaidQuote) = FALSE; + (*pfSaidQuote) = FALSE; if (pObj->bTrap > 0) { @@ -4405,7 +4416,7 @@ BOOLEAN ContinuePastBoobyTrap( SOLDIERTYPE * pSoldier, INT16 sGridNo, INT8 bLeve gpBoobyTrapSoldier = pSoldier; gpBoobyTrapItemPool = GetItemPoolForIndex( sGridNo, iItemIndex, pSoldier->bLevel ); gsBoobyTrapGridNo = sGridNo; - gbBoobyTrapLevel = pSoldier->bLevel; + gbBoobyTrapLevel = pSoldier->bLevel; gfDisarmingBuriedBomb = FALSE; gbTrapDifficulty = bTrapDifficulty; @@ -4413,7 +4424,7 @@ BOOLEAN ContinuePastBoobyTrap( SOLDIERTYPE * pSoldier, INT16 sGridNo, INT8 bLeve SetStopTimeQuoteCallback( BoobyTrapDialogueCallBack ); TacticalCharacterDialogue( pSoldier, QUOTE_BOOBYTRAP_ITEM ); - (*pfSaidQuote) = TRUE; + (*pfSaidQuote) = TRUE; return( FALSE ); } @@ -4491,7 +4502,7 @@ void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue ) // Snap: make it easier to disarm our own traps. // If we succede - we get exp, but if we fail - we pay fair and square! - + // NB owner grossness... bombs 'owned' by the enemy are stored with side value 1 in // the map. So if we want to detect a bomb placed by the player, owner is > 1, and // owner - 2 gives the ID of the character who planted it @@ -4512,7 +4523,7 @@ void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue ) { iCheckResult = SkillCheck( gpBoobyTrapSoldier, DISARM_TRAP_CHECK, 0 ); } - + if (iCheckResult >= 0) { @@ -4586,7 +4597,7 @@ void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue ) else { // oops! trap goes off - StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (INT8) (3 * gbTrapDifficulty ), FROM_FAILURE ); + StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (INT8) (3 * gbTrapDifficulty ), FROM_FAILURE ); DoMercBattleSound( gpBoobyTrapSoldier, BATTLE_SOUND_CURSE1 ); @@ -4633,7 +4644,7 @@ void BoobyTrapInMapScreenMessageBoxCallBack( UINT8 ubExitValue ) if (iCheckResult >= 0) { // disarmed a boobytrap! - StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (UINT16) (6 * gbTrapDifficulty), FALSE ); + StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (UINT16) (6 * gbTrapDifficulty), FALSE ); // have merc say this is good @@ -4679,10 +4690,10 @@ void BoobyTrapInMapScreenMessageBoxCallBack( UINT8 ubExitValue ) else { // oops! trap goes off - StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (INT8) (3 * gbTrapDifficulty ), FROM_FAILURE ); + StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (INT8) (3 * gbTrapDifficulty ), FROM_FAILURE ); DoMercBattleSound( gpBoobyTrapSoldier, BATTLE_SOUND_CURSE1 ); - + if (gfDisarmingBuriedBomb) { SetOffBombsInGridNo( gpBoobyTrapSoldier->ubID, gsBoobyTrapGridNo, TRUE, gbBoobyTrapLevel ); @@ -4709,7 +4720,7 @@ void SwitchMessageBoxCallBack( UINT8 ubExitValue ) { if ( ubExitValue == MSG_BOX_RETURN_YES ) { - // Message that switch is activated... + // Message that switch is activated... ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 60 ] ); SetOffBombsByFrequency( gpTempSoldier->ubID, bTempFrequency ); @@ -4726,7 +4737,7 @@ BOOLEAN NearbyGroundSeemsWrong( SOLDIERTYPE * pSoldier, INT16 sGridNo, BOOLEAN f UINT32 uiWorldBombIndex; OBJECTTYPE * pObj; BOOLEAN fMining, fFoundMetal = FALSE; -// ITEM_POOL * pItemPool; + // ITEM_POOL * pItemPool; UINT8 ubMovementCost; ubDetectLevel = 0; @@ -4743,20 +4754,20 @@ BOOLEAN NearbyGroundSeemsWrong( SOLDIERTYPE * pSoldier, INT16 sGridNo, BOOLEAN f /* if (pSoldier->bStealthMode) { - ubDetectLevel++; + ubDetectLevel++; } switch (pSoldier->usAnimState) { - case CRAWLING: - ubDetectLevel += 2; - break; + case CRAWLING: + ubDetectLevel += 2; + break; - case SWATTING: - ubDetectLevel++; - break; + case SWATTING: + ubDetectLevel++; + break; - default: - break; + default: + break; } */ } @@ -4798,7 +4809,7 @@ BOOLEAN NearbyGroundSeemsWrong( SOLDIERTYPE * pSoldier, INT16 sGridNo, BOOLEAN f // if this sNextGridNo isn't out of bounds... but it never can be pMapElement = &(gpWorldLevelData[sNextGridNo]); - + if (pMapElement->uiFlags & fCheckFlag) { // already know there's a mine there @@ -4824,7 +4835,7 @@ BOOLEAN NearbyGroundSeemsWrong( SOLDIERTYPE * pSoldier, INT16 sGridNo, BOOLEAN f { if (pSoldier->uiStatusFlags & SOLDIER_PC ) { - // detected exposives buried nearby... + // detected exposives buried nearby... StatChange( pSoldier, EXPLODEAMT, (UINT16) (pObj->bTrap), FALSE ); StatChange( pSoldier, WISDOMAMT, (UINT16) (pObj->bTrap), FALSE ); @@ -4843,39 +4854,39 @@ BOOLEAN NearbyGroundSeemsWrong( SOLDIERTYPE * pSoldier, INT16 sGridNo, BOOLEAN f // also check for metal items if using a metal detector if (fMining) { - // add blue flags where we find metallic objects hidden - GetItemPool( sNextGridNo, &pItemPool, pSoldier->bLevel ); - while( pItemPool ) - { - if ( pItemPool->bVisible == BURIED || (pItemPool->bVisible != TRUE && gWorldItems[ pItemPool->iItemIndex ].o.bTrap > 0 ) ) - { - pObj = &( gWorldItems[ pItemPool->iItemIndex ].o ); - if ( pObj->usItem == ACTION_ITEM && pObj-> ) - { - switch( pObj->bActionValue ) - { - case ACTION_ITEM_BLOW_UP: - case ACTION_ITEM_LOCAL_ALARM: - case ACTION_ITEM_GLOBAL_ALARM: - // add blue flag - AddBlueFlag( sNextGridNo, pSoldier->bLevel ); - fFoundMetal = TRUE; - break; - default: - break; + // add blue flags where we find metallic objects hidden + GetItemPool( sNextGridNo, &pItemPool, pSoldier->bLevel ); + while( pItemPool ) + { + if ( pItemPool->bVisible == BURIED || (pItemPool->bVisible != TRUE && gWorldItems[ pItemPool->iItemIndex ].o.bTrap > 0 ) ) + { + pObj = &( gWorldItems[ pItemPool->iItemIndex ].o ); + if ( pObj->usItem == ACTION_ITEM && pObj-> ) + { + switch( pObj->bActionValue ) + { + case ACTION_ITEM_BLOW_UP: + case ACTION_ITEM_LOCAL_ALARM: + case ACTION_ITEM_GLOBAL_ALARM: + // add blue flag + AddBlueFlag( sNextGridNo, pSoldier->bLevel ); + fFoundMetal = TRUE; + break; + default: + break; - } - } - else if (Item[ pObj->usItem ].fFlags & ITEM_METAL) - { - // add blue flag - AddBlueFlag( sNextGridNo, pSoldier->bLevel ); - fFoundMetal = TRUE; - break; - } - } - pItemPool = pItemPool->pNext; - } + } + } + else if (Item[ pObj->usItem ].fFlags & ITEM_METAL) + { + // add blue flag + AddBlueFlag( sNextGridNo, pSoldier->bLevel ); + fFoundMetal = TRUE; + break; + } + } + pItemPool = pItemPool->pNext; + } } */ @@ -4896,8 +4907,8 @@ void MineSpottedDialogueCallBack( void ) { ITEM_POOL * pItemPool; - // ATE: REALLY IMPORTANT - ALL CALLBACK ITEMS SHOULD UNLOCK - gTacticalStatus.fLockItemLocators = FALSE; + // ATE: REALLY IMPORTANT - ALL CALLBACK ITEMS SHOULD UNLOCK + gTacticalStatus.fLockItemLocators = FALSE; GetItemPool( gsBoobyTrapGridNo, &pItemPool, gbBoobyTrapLevel ); @@ -4939,7 +4950,7 @@ void AddBlueFlag( INT16 sGridNo ,INT8 bLevel ) ApplyMapChangesToMapTempFile( TRUE ); gpWorldLevelData[ sGridNo ].uiFlags |= MAPELEMENT_PLAYER_MINE_PRESENT; - pNode = AddStructToTail( sGridNo, BLUEFLAG_GRAPHIC ); + pNode = AddStructToTail( sGridNo, BLUEFLAG_GRAPHIC ); if ( pNode ) { @@ -4956,14 +4967,14 @@ void RemoveBlueFlag( INT16 sGridNo, INT8 bLevel ) ApplyMapChangesToMapTempFile( TRUE ); gpWorldLevelData[sGridNo].uiFlags &= ~(MAPELEMENT_PLAYER_MINE_PRESENT); - if ( bLevel == 0 ) - { - RemoveStruct( sGridNo, BLUEFLAG_GRAPHIC ); - } - else - { - RemoveOnRoof( sGridNo, BLUEFLAG_GRAPHIC ); - } + if ( bLevel == 0 ) + { + RemoveStruct( sGridNo, BLUEFLAG_GRAPHIC ); + } + else + { + RemoveOnRoof( sGridNo, BLUEFLAG_GRAPHIC ); + } ApplyMapChangesToMapTempFile( FALSE ); RecompileLocalMovementCostsFromRadius( sGridNo, bLevel ); @@ -4976,35 +4987,35 @@ void MakeNPCGrumpyForMinorOffense( SOLDIERTYPE * pSoldier, SOLDIERTYPE *pOffendi switch( pSoldier->ubProfile ) { - case FREDO: - case FRANZ: - case HERVE: - case PETER: - case ALBERTO: - case CARLO: - case MANNY: - case GABBY: - case ARNIE: - case HOWARD: - case SAM: - case FATHER: - case TINA: - case ARMAND: - case WALTER: - gMercProfiles[ pSoldier->ubProfile ].ubMiscFlags3 |= PROFILE_MISC_FLAG3_NPC_PISSED_OFF; - TriggerNPCWithIHateYouQuote( pSoldier->ubProfile ); - break; - default: - // trigger NPCs with quote if available - AddToShouldBecomeHostileOrSayQuoteList( pSoldier->ubID ); - break; + case FREDO: + case FRANZ: + case HERVE: + case PETER: + case ALBERTO: + case CARLO: + case MANNY: + case GABBY: + case ARNIE: + case HOWARD: + case SAM: + case FATHER: + case TINA: + case ARMAND: + case WALTER: + gMercProfiles[ pSoldier->ubProfile ].ubMiscFlags3 |= PROFILE_MISC_FLAG3_NPC_PISSED_OFF; + TriggerNPCWithIHateYouQuote( pSoldier->ubProfile ); + break; + default: + // trigger NPCs with quote if available + AddToShouldBecomeHostileOrSayQuoteList( pSoldier->ubID ); + break; } - if ( pOffendingSoldier ) - { - pSoldier->bNextAction = AI_ACTION_CHANGE_FACING; - pSoldier->usNextActionData = atan8( pSoldier->sX, pSoldier->sY, pOffendingSoldier->sX, pOffendingSoldier->sY ); - } + if ( pOffendingSoldier ) + { + pSoldier->bNextAction = AI_ACTION_CHANGE_FACING; + pSoldier->usNextActionData = atan8( pSoldier->sX, pSoldier->sY, pOffendingSoldier->sX, pOffendingSoldier->sY ); + } } @@ -5258,7 +5269,7 @@ INT16 FindNearestAvailableGridNoForItem( INT16 sSweetGridNo, INT8 ubRadius ) //Now, find out which of these gridnos are reachable //(use the fake soldier and the pathing settings) FindBestPath( &soldier, NOWHERE, 0, WALKING, COPYREACHABLE, 0 ); - + uiLowestRange = 999999; for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ ) @@ -5299,41 +5310,41 @@ INT16 FindNearestAvailableGridNoForItem( INT16 sSweetGridNo, INT8 ubRadius ) BOOLEAN CanPlayerUseRocketRifle( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay ) { if ( Item[pSoldier->inv[ pSoldier->ubAttackingHand ].usItem].fingerprintid ) - { - // check imprint ID - // NB not-imprinted value is NO_PROFILE - // imprinted value is profile for mercs & NPCs and NO_PROFILE + 1 for generic dudes - if (pSoldier->ubProfile != NO_PROFILE) - { - if ( pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID != pSoldier->ubProfile ) - { - // NOT a virgin gun... - if ( pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID != NO_PROFILE ) - { - // access denied! - if (pSoldier->bTeam == gbPlayerNum) - { - PlayJA2Sample( RG_ID_INVALID, RATE_11025, HIGHVOLUME, 1, MIDDLE ); - - if ( fDisplay ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, L"\"%s\"", TacticalStr[ GUN_NOGOOD_FINGERPRINT ] ); - } - } - return( FALSE ); - } - } - } - } - return( TRUE ); + { + // check imprint ID + // NB not-imprinted value is NO_PROFILE + // imprinted value is profile for mercs & NPCs and NO_PROFILE + 1 for generic dudes + if (pSoldier->ubProfile != NO_PROFILE) + { + if ( pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID != pSoldier->ubProfile ) + { + // NOT a virgin gun... + if ( pSoldier->inv[ pSoldier->ubAttackingHand ].ubImprintID != NO_PROFILE ) + { + // access denied! + if (pSoldier->bTeam == gbPlayerNum) + { + PlayJA2Sample( RG_ID_INVALID, RATE_11025, HIGHVOLUME, 1, MIDDLE ); + + if ( fDisplay ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, L"\"%s\"", TacticalStr[ GUN_NOGOOD_FINGERPRINT ] ); + } + } + return( FALSE ); + } + } + } + } + return( TRUE ); } /** - * jackaians: pretty bad function. Create an artificial ItemPool, where - * iItemIndex is not the index in the world, but is used to store the index - * of the opponent's slots. - * if only one item, return in ubIndexRet the item's index - */ +* jackaians: pretty bad function. Create an artificial ItemPool, where +* iItemIndex is not the index in the world, but is used to store the index +* of the opponent's slots. +* if only one item, return in ubIndexRet the item's index +*/ UINT8 StealItems(SOLDIERTYPE* pSoldier,SOLDIERTYPE* pOpponent, UINT8* ubIndexRet) { UINT8 ubCount=0; @@ -5362,25 +5373,25 @@ UINT8 StealItems(SOLDIERTYPE* pSoldier,SOLDIERTYPE* pOpponent, UINT8* ubIndexRet // Check, if we can steal the item switch (i) { - case HANDPOS: - case SECONDHANDPOS: - case BIGPOCK1POS: - case BIGPOCK2POS: - case BIGPOCK3POS: - case BIGPOCK4POS: - case SMALLPOCK1POS: - case SMALLPOCK2POS: - case SMALLPOCK3POS: - case SMALLPOCK4POS: - case SMALLPOCK5POS: - case SMALLPOCK6POS: - case SMALLPOCK7POS: - case SMALLPOCK8POS: - fStealItem = TRUE; - break; - default: - fStealItem = FALSE; - break; + case HANDPOS: + case SECONDHANDPOS: + case BIGPOCK1POS: + case BIGPOCK2POS: + case BIGPOCK3POS: + case BIGPOCK4POS: + case SMALLPOCK1POS: + case SMALLPOCK2POS: + case SMALLPOCK3POS: + case SMALLPOCK4POS: + case SMALLPOCK5POS: + case SMALLPOCK6POS: + case SMALLPOCK7POS: + case SMALLPOCK8POS: + fStealItem = TRUE; + break; + default: + fStealItem = FALSE; + break; } } @@ -5430,9 +5441,9 @@ UINT8 StealItems(SOLDIERTYPE* pSoldier,SOLDIERTYPE* pOpponent, UINT8* ubIndexRet /** - * jackaians: function copied from SoldierGetItemFromWorld - * check user's choices and try to place them in his slots - */ +* jackaians: function copied from SoldierGetItemFromWorld +* check user's choices and try to place them in his slots +*/ void SoldierStealItemFromSoldier( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent,ITEM_POOL *pItemPool, INT32 iItemIndex, INT16 sGridNo, INT8 bZLevel, BOOLEAN *pfSelectionList ) { ITEM_POOL *pTempItemPool; @@ -5450,31 +5461,31 @@ void SoldierStealItemFromSoldier( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, while( pTempItemPool ) { - fPickup = TRUE; - if ( iItemIndex == ITEM_PICKUP_SELECTION ) + fPickup = TRUE; + if ( iItemIndex == ITEM_PICKUP_SELECTION ) + { + if ( !pfSelectionList[ cnt ] ) { - if ( !pfSelectionList[ cnt ] ) - { - fPickup = FALSE; - } + fPickup = FALSE; } - // Increment counter... - cnt++; - if ( fPickup ) + } + // Increment counter... + cnt++; + if ( fPickup ) + { + // Make copy of item + memcpy( &Object, pOpponent->inv+pTempItemPool->iItemIndex, sizeof( OBJECTTYPE ) ); + if ( ItemIsCool( &Object ) ) { - // Make copy of item - memcpy( &Object, pOpponent->inv+pTempItemPool->iItemIndex, sizeof( OBJECTTYPE ) ); - if ( ItemIsCool( &Object ) ) - { - fShouldSayCoolQuote = TRUE; - } - if ( !AutoPlaceObject( pSoldier, &Object, TRUE ) ) - { - AddItemToPool( pSoldier->sGridNo, &Object, 1, pSoldier->bLevel, 0, -1 ); - } - DeleteObj(pOpponent->inv+pTempItemPool->iItemIndex); + fShouldSayCoolQuote = TRUE; } - pTempItemPool = pTempItemPool->pNext; + if ( !AutoPlaceObject( pSoldier, &Object, TRUE ) ) + { + AddItemToPool( pSoldier->sGridNo, &Object, 1, pSoldier->bLevel, 0, -1 ); + } + DeleteObj(pOpponent->inv+pTempItemPool->iItemIndex); + } + pTempItemPool = pTempItemPool->pNext; } } // OK, check if potentially a good candidate for cool quote @@ -5503,4 +5514,4 @@ void SoldierStealItemFromSoldier( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, gpTempSoldier = pSoldier; gsTempGridno = sGridNo; SetCustomizableTimerCallbackAndDelay( 1000, CheckForPickedOwnership, TRUE ); -} \ No newline at end of file +} diff --git a/Tactical/Handle UI.cpp b/Tactical/Handle UI.cpp index c17062b5..4f61868f 100644 --- a/Tactical/Handle UI.cpp +++ b/Tactical/Handle UI.cpp @@ -3,6 +3,7 @@ #include "BuildDefines.h" #else + #include "builddefines.h" #include #include #include "wcheck.h" @@ -72,6 +73,18 @@ #include "render dirty.h" #include "GameSettings.h" #include "los.h" + #include "Campaign Types.h" + #include "Queen Command.h" + #include "Options Screen.h" + #include "SaveLoadGame.h" + #include "Spread Burst.h" + #include "ai.h" + #include "Game Clock.h" + #include "civ quotes.h" + #include "Militia Control.h" + #include "qarray.h" + #include "environment.h" + #include "Map Information.h" #endif @@ -1028,7 +1041,7 @@ UINT32 UIHandleExit( UI_EVENT *pUIEvent ) UINT32 UIHandleNewMerc( UI_EVENT *pUIEvent ) { static UINT8 ubTemp = 3; - INT16 usMapPos; + UINT16 usMapPos; static INT32 iSoldierCount=0; MERC_HIRE_STRUCT HireMercStruct; INT8 bReturnCode; @@ -1223,8 +1236,8 @@ UINT32 UIHandleTestHit( UI_EVENT *pUIEvent ) } } - gTacticalStatus.ubAttackBusyCount++; - + // gTacticalStatus.ubAttackBusyCount++; + DebugAttackBusy( "Testing a hit.\n" ); EVENT_SoldierGotHit( pSoldier, 1, bDamage, 10, pSoldier->bDirection, 320, NOBODY , FIRE_WEAPON_NO_SPECIAL, pSoldier->bAimShotLocation, 0, NOWHERE ); // callahan update end - put everything as it was } @@ -6387,4 +6400,4 @@ BOOLEAN IsValidJumpLocation( SOLDIERTYPE *pSoldier, INT16 sGridNo, BOOLEAN fChec } return( FALSE ); -} \ No newline at end of file +} diff --git a/Tactical/Interface Control.cpp b/Tactical/Interface Control.cpp index ec302ffc..73d1ad8e 100644 --- a/Tactical/Interface Control.cpp +++ b/Tactical/Interface Control.cpp @@ -46,6 +46,9 @@ #include "spread burst.h" #include "squads.h" #include "line.h" + #include "Militia Control.h" + #include "Map Screen Interface.h" + #include "civ quotes.h" #endif /* I deleted here declaration of clock coords for tactical screen i will declare them diff --git a/Tactical/Interface Cursors.cpp b/Tactical/Interface Cursors.cpp index 4161b30c..552d3fc2 100644 --- a/Tactical/Interface Cursors.cpp +++ b/Tactical/Interface Cursors.cpp @@ -21,6 +21,7 @@ #include "sys globals.h" #include "overhead.h" #include "interface items.h" + #include "GameSettings.h" #endif #define DISPLAY_AP_INDEX MOCKFLOOR1 @@ -262,7 +263,7 @@ BOOLEAN DrawUICursor( ) return( TRUE ); } - if (GetMouseMapPos( (INT16 *)&usMapPos) ) + if (GetMouseMapPos( &usMapPos) ) { gusCurMousePos = usMapPos; diff --git a/Tactical/Interface Dialogue.cpp b/Tactical/Interface Dialogue.cpp index a41e4e22..4789557d 100644 --- a/Tactical/Interface Dialogue.cpp +++ b/Tactical/Interface Dialogue.cpp @@ -3,6 +3,7 @@ #include "Tactical All.h" #include "PreBattle Interface.h" #else + #include "builddefines.h" #include #include "sgp.h" #include "soldier control.h" @@ -64,6 +65,18 @@ #include "Soldier create.h" #include "SkillCheck.h" #include "Sound Control.h" + #include "opplist.h" + #include "PreBattle Interface.h" + #include "history.h" + #include "Keys.h" + #include "Morale.h" + #include "personnel.h" + #include "Map Screen Interface.h" + #include "Queen Command.h" + #include "Campaign.h" + #include "BobbyRMailOrder.h" + #include "end game.h" + #include "Map Screen Helicopter.h" #endif INT16 sBasementEnterGridNos[ ] = { 13362, 13363, 13364, 13365, 13525, 13524 }; diff --git a/Tactical/Interface Items.cpp b/Tactical/Interface Items.cpp index 2bb44cdf..44b7b009 100644 --- a/Tactical/Interface Items.cpp +++ b/Tactical/Interface Items.cpp @@ -2,6 +2,7 @@ #include "Tactical All.h" #include "language defines.h" #else + #include "builddefines.h" #include #include #include @@ -65,6 +66,13 @@ #include "MessageBoxScreen.h" #include "Language Defines.h" #include "GameSettings.h" + #include "Map Screen Interface Map Inventory.h" + #include "Quests.h" + #include "Map Screen Interface.h" + #include "Campaign Types.h" + #include "opplist.h" + #include "los.h" + #include "Map Screen Interface Map.h" #endif #define ITEMDESC_FONT BLOCKFONT2 @@ -558,7 +566,7 @@ MOUSE_REGION gSMInvCamoRegion; INT8 gbCompatibleAmmo[ NUM_INV_SLOTS ]; INT8 gbInvalidPlacementSlot[ NUM_INV_SLOTS ]; UINT16 us16BPPItemCyclePlacedItemColors[ 20 ]; -// Kaiden: Vehicle Inventory change - Increase this from 4-2 to 5-2 +// Kaiden: Vehicle Inventory change - Increase this from 4-2 to 5-2 UINT32 guiBodyInvVO[ 5 ][ 2 ]; UINT32 guiGoldKeyVO; INT8 gbCompatibleApplyItem = FALSE; @@ -891,17 +899,17 @@ BOOLEAN InitInvSlotInterface( INV_REGION_DESC *pRegionDesc , INV_REGION_DESC *pC FilenameForBPP("INTERFACE\\inventory_figure_female_H.sti", VObjectDesc.ImageFile); CHECKF( AddVideoObject( &VObjectDesc, &(guiBodyInvVO[ 3 ][ 1 ] ) ) ); - // 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_h.sti", -VObjectDesc.ImageFile); + // 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_h.sti", +VObjectDesc.ImageFile); CHECKF( AddVideoObject( &VObjectDesc, &(guiBodyInvVO[ 4 ][ 1 ] ) ) ); // add gold key graphic @@ -1007,7 +1015,7 @@ void ShutdownInvSlotInterface( ) { UINT32 cnt; - // Kaiden: Vehicle Inventory change - Added 4-0 and 4-1 + // Kaiden: Vehicle Inventory change - Added 4-0 and 4-1 // to be deleted as well. // Remove all body type panels @@ -1042,12 +1050,12 @@ void RenderInvBodyPanel( SOLDIERTYPE *pSoldier, INT16 sX, INT16 sY ) // Blit body inv, based on body type INT8 bSubImageIndex = gbCompatibleApplyItem; - // Kaiden: Vehicle Inventory change - Added IF Test, Else function call was - // the original statement - if ( (gGameExternalOptions.fVehicleInventory) && (pSoldier->uiStatusFlags & SOLDIER_VEHICLE) ) - { - BltVideoObjectFromIndex( guiSAVEBUFFER, guiBodyInvVO[4][0], 0, sX, sY, VO_BLT_SRCTRANSPARENCY, NULL ); - } + // Kaiden: Vehicle Inventory change - Added IF Test, Else function call was + // the original statement + if ( (gGameExternalOptions.fVehicleInventory) && (pSoldier->uiStatusFlags & SOLDIER_VEHICLE) ) + { + BltVideoObjectFromIndex( guiSAVEBUFFER, guiBodyInvVO[4][0], 0, sX, sY, VO_BLT_SRCTRANSPARENCY, NULL ); + } else { BltVideoObjectFromIndex( guiSAVEBUFFER, guiBodyInvVO[ pSoldier->ubBodyType ][ bSubImageIndex ], 0, sX, sY, VO_BLT_SRCTRANSPARENCY, NULL ); @@ -4487,7 +4495,7 @@ void DrawItemTileCursor( ) INT16 sDist; INT8 bLevel; - if (GetMouseMapPos( (INT16 *)&usMapPos) ) + if (GetMouseMapPos( &usMapPos) ) { if ( gfUIFullTargetFound ) { @@ -5125,8 +5133,8 @@ BOOLEAN HandleItemPointerClick( UINT16 usMapPos ) if (gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND) { - pSoldier->usPendingAnimation = PASS_OBJECT; - } + pSoldier->usPendingAnimation = PASS_OBJECT; + } } // WANNE: Also turn merc if he is crouched and he received the passed item @@ -5137,9 +5145,9 @@ BOOLEAN HandleItemPointerClick( UINT16 usMapPos ) if (gAnimControl[ gpItemPointerSoldier->usAnimState ].ubEndHeight == ANIM_STAND) { - gpItemPointerSoldier->usPendingAnimation = PASS_OBJECT; - } + gpItemPointerSoldier->usPendingAnimation = PASS_OBJECT; } + } } return( TRUE ); @@ -5234,8 +5242,9 @@ BOOLEAN HandleItemPointerClick( UINT16 usMapPos ) gpItemPointerSoldier->fTurningUntilDone = TRUE; // Increment attacker count... - gTacticalStatus.ubAttackBusyCount++; - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("INcremtning ABC: Throw item to %d", gTacticalStatus.ubAttackBusyCount) ); + // gTacticalStatus.ubAttackBusyCount++; + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Incremtning ABC: Throw item to %d", gTacticalStatus.ubAttackBusyCount) ); + DebugAttackBusy( "Incrementing ABC: Throw item\n" ); // Given our gridno, throw grenate! @@ -8158,4 +8167,4 @@ void DeletePool(ITEM_POOL *pItemPool) pItemPool=pItemPool->pNext; MemFree(pItemPoolToDelete); } -} \ No newline at end of file +} diff --git a/Tactical/Interface Panels.cpp b/Tactical/Interface Panels.cpp index e5b7da11..3e207ec5 100644 --- a/Tactical/Interface Panels.cpp +++ b/Tactical/Interface Panels.cpp @@ -2,6 +2,7 @@ #ifdef PRECOMPILEDHEADERS #include "Tactical All.h" #else + #include "builddefines.h" #include #include #include @@ -70,6 +71,8 @@ #include "LaptopSave.h" #include "Cursor Control.h" #include "MessageBoxScreen.h" + #include "wordwrap.h" + #include "Boxing.h" #endif /* diff --git a/Tactical/Interface Utils.cpp b/Tactical/Interface Utils.cpp index 3b3ef492..c593d58f 100644 --- a/Tactical/Interface Utils.cpp +++ b/Tactical/Interface Utils.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Tactical All.h" #else + #include "builddefines.h" #include #include #include "sgp.h" @@ -17,6 +18,8 @@ #include "Overhead.h" #include "Soldier macros.h" #include "line.h" + #include "WCheck.h" + #include "Vehicles.h" #endif #define LIFE_BAR_SHADOW FROMRGB( 108, 12, 12 ) diff --git a/Tactical/Interface.cpp b/Tactical/Interface.cpp index c231c610..b063cda4 100644 --- a/Tactical/Interface.cpp +++ b/Tactical/Interface.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Tactical All.h" #else + #include "builddefines.h" #include #include #include @@ -53,6 +54,8 @@ #include "Vehicles.h" #include "messageboxscreen.h" #include "gamesettings.h" + #include "Squads.h" + #include "message.h" #endif //const UINT32 INTERFACE_START_X = 0; @@ -1497,7 +1500,7 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID ) GetSoldier( &pSoldier, usSoldierID ); - if ( pSoldier->bVisible == -1 && !(gTacticalStatus.uiFlags&SHOW_ALL_MERCS) ) + if ( !pSoldier || (pSoldier->bVisible == -1 && !(gTacticalStatus.uiFlags&SHOW_ALL_MERCS) ) ) { return; } diff --git a/Tactical/Inventory Choosing.cpp b/Tactical/Inventory Choosing.cpp index 5ed2d197..5f477af8 100644 --- a/Tactical/Inventory Choosing.cpp +++ b/Tactical/Inventory Choosing.cpp @@ -10,6 +10,13 @@ #include "Strategic Status.h" #include "Campaign.h" #include "GameSettings.h" + #include "AIInternals.h" + #include "strategicmap.h" + #include "Auto Resolve.h" + #include "Map Screen Interface Map.h" + #include "EnemyItemDrops.h" + #include "strategic.h" + #include "Game Clock.h" #endif /* @@ -558,6 +565,11 @@ void GenerateRandomEquipment( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass, INT8 case IC_LAUNCHER: pItem->ubGunState |= GS_CARTRIDGE_IN_CHAMBER; fGrenadeLauncher = FALSE; + if (fMortar || fRPG) + { + bGrenadeClass = 0; + bGrenades = 0; + } fMortar = FALSE; fRPG = FALSE; break; diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index 3e043efd..a5af06b3 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -36,6 +36,20 @@ #include "Interface Control.h" #include "ShopKeeper Interface.h" #include "Cursors.h" + + #include "GameSettings.h" + #include "environment.h" + #include "Auto Resolve.h" + #include "Interface Items.h" + #include "Campaign Types.h" + #include "history.h" + #include "Game Clock.h" + #include "strategicmap.h" + #include "Inventory Choosing.h" + #include "Soldier macros.h" + #include "Smell.h" + #include "lighting.h" + #include "utilities.h" #endif #define ANY_MAGSIZE 255 @@ -1607,7 +1621,8 @@ INT8 FindThrowableGrenade( SOLDIERTYPE * pSoldier ) for (bLoop = 0; bLoop < NUM_INV_SLOTS; bLoop++) { - if ( (Item[ pSoldier->inv[ bLoop ].usItem ].usItemClass & IC_GRENADE) && !GLGrenadeInSlot( pSoldier, bLoop ) ) + if ( (Item[ pSoldier->inv[ bLoop ].usItem ].usItemClass & IC_GRENADE) && // Try this check instead, to avoid tossing RPG rounds !GLGrenadeInSlot( pSoldier, bLoop ) && + GetLauncherFromLaunchable( pSoldier->inv[ bLoop ].usItem) == NOTHING ) { return( bLoop ); } @@ -6565,7 +6580,7 @@ INT16 GetRateOfFireBonus( OBJECTTYPE * pObj ) } bns = BonusReduceMore( Item[pObj->usItem].rateoffirebonus, pObj->bStatus[0] ); - bns += Item[pObj->usGunAmmoItem].rateoffirebonus; + bns += Item[pObj->usGunAmmoItem].rateoffirebonus ; for (bLoop = 0; bLoop < MAX_ATTACHMENTS; bLoop++) { diff --git a/Tactical/Keys.cpp b/Tactical/Keys.cpp index 365c5fc6..1a12c3ce 100644 --- a/Tactical/Keys.cpp +++ b/Tactical/Keys.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Tactical All.h" #else + #include "builddefines.h" #include #include @@ -33,6 +34,10 @@ #include "worlddef.h" #include "campaign.h" #include "sound control.h" + #include "Interface.h" + #include "Game Clock.h" + #include "handle doors.h" + #include "Map Screen Interface.h" #endif @@ -662,9 +667,10 @@ void HandleDoorTrap( SOLDIERTYPE * pSoldier, DOOR * pDoor ) // Set attacker's ID pSoldier->ubAttackerID = pSoldier->ubID; // Increment being attacked count - pSoldier->bBeingAttackedCount++; - gTacticalStatus.ubAttackBusyCount++; + // pSoldier->bBeingAttackedCount++; + // gTacticalStatus.ubAttackBusyCount++; DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Trap gone off %d", gTacticalStatus.ubAttackBusyCount) ); + DebugAttackBusy( "!!!!!!! Trap gone off\n" ); SoldierTakeDamage( pSoldier, 0, (UINT16) (10 + PreRandom( 10 )), (UINT16) ((3 + PreRandom( 3 ) * 1000)), TAKE_DAMAGE_ELECTRICITY, NOBODY, pDoor->sGridNo, 0, TRUE ); break; @@ -676,9 +682,10 @@ void HandleDoorTrap( SOLDIERTYPE * pSoldier, DOOR * pDoor ) // Set attacker's ID pSoldier->ubAttackerID = pSoldier->ubID; // Increment being attacked count - pSoldier->bBeingAttackedCount++; - gTacticalStatus.ubAttackBusyCount++; + // pSoldier->bBeingAttackedCount++; + // gTacticalStatus.ubAttackBusyCount++; DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Trap gone off %d", gTacticalStatus.ubAttackBusyCount) ); + DebugAttackBusy( "!!!!!!! Trap gone off\n" ); SoldierTakeDamage( pSoldier, 0, (UINT16) (20 + PreRandom( 20 )), (UINT16) ((6 + PreRandom( 6 ) * 1000)), TAKE_DAMAGE_ELECTRICITY, NOBODY, pDoor->sGridNo, 0, TRUE ); break; diff --git a/Tactical/LOS.cpp b/Tactical/LOS.cpp index 0d74992f..b1ce5e9c 100644 --- a/Tactical/LOS.cpp +++ b/Tactical/LOS.cpp @@ -1,37 +1,45 @@ #ifdef PRECOMPILEDHEADERS - #include "Tactical All.h" +#include "Tactical All.h" #else - #include +#include "builddefines.h" +#include - #include - #include - #include "wcheck.h" - #include "Isometric Utils.h" - #include "debug.h" - #include "los.h" - #include "animation control.h" - #include "Random.h" - #include "soldier control.h" - #include "Event Pump.h" - #include "overhead.h" - #include "weapons.h" +#include +#include +#include "wcheck.h" +#include "Isometric Utils.h" +#include "debug.h" +#include "los.h" +#include "animation control.h" +#include "Random.h" +#include "soldier control.h" +#include "Event Pump.h" +#include "overhead.h" +#include "weapons.h" - #include "opplist.h" - #include "soldier control.h" - #include "bullets.h" +#include "opplist.h" +#include "soldier control.h" +#include "bullets.h" - #include "phys math.h" - #include "items.h" - #include "Soldier Profile.h" - #include "worldman.h" - #include "rotting corpses.h" - #include "GameSettings.h" - #include "keys.h" - #include "message.h" - #include "Structure Wrap.h" - #include "campaign.h" - #include "environment.h" - #include "Pathai.h" +#include "phys math.h" +#include "items.h" +#include "Soldier Profile.h" +#include "worldman.h" +#include "rotting corpses.h" +#include "GameSettings.h" +#include "keys.h" +#include "message.h" +#include "Structure Wrap.h" +#include "campaign.h" +#include "environment.h" +#include "Pathai.h" +#include "Soldier macros.h" +#include "strategicmap.h" +#include "Interface.h" +#include "points.h" +#include "Smell.h" +#include "Text.h" +#include "Quests.h" #endif #define STEPS_FOR_BULLET_MOVE_TRAILS 10 @@ -58,32 +66,32 @@ static FIXEDPT gqStandardWindowTopHeight = INT32_TO_FIXEDPT( WINDOW_TOP_HEIGHT_U UINT32 FPMult32(UINT32 uiA, UINT32 uiB) { -UINT32 uiResult; + UINT32 uiResult; __asm { // Load the 32-bit registers with the two values mov eax, uiA - mov ebx, uiB + mov ebx, uiB - // Multiply them - // Top 32 bits (whole portion) goes into edx - // Bottom 32 bits (fractional portion) goes into eax - imul ebx + // Multiply them + // Top 32 bits (whole portion) goes into edx + // Bottom 32 bits (fractional portion) goes into eax + imul ebx - // Shift the fractional portion back to (lower) 16 bits - shr eax, 16 - // Shift the whole portion to 16 bits, in the upper word - shl edx, 16 + // Shift the fractional portion back to (lower) 16 bits + shr eax, 16 + // Shift the whole portion to 16 bits, in the upper word + shl edx, 16 - // At this point, we have edx xxxx0000 and eax 0000xxxx - // Combine the two words into a dword - or eax, edx + // At this point, we have edx xxxx0000 and eax 0000xxxx + // Combine the two words into a dword + or eax, edx - // Put the result into a returnable variable - mov uiResult, eax - } + // Put the result into a returnable variable + mov uiResult, eax + } - return(uiResult); + return(uiResult); } @@ -127,7 +135,7 @@ static DOUBLE ddShotgunSpread[3][BUCKSHOT_SHOTS][2] = { -0.080, +0.080}, { +0.080, -0.080}, { +0.080, +0.080} - }, + }, }; @@ -148,12 +156,12 @@ static UINT8 gubTreeSightReduction[ANIM_STAND + 1] = static UINT32 guiStructureHitChance[ MAX_DIST_FOR_LESS_THAN_MAX_CHANCE_TO_HIT_STRUCTURE + 1] = { - 0, // 0 tiles - 0, - 0, - 2, - 4, - 7, // 5 tiles + 0, // 0 tiles + 0, + 0, + 2, + 4, + 7, // 5 tiles 10, 14, 18, @@ -289,36 +297,36 @@ BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX switch ( bLOSIndexX ) { + case 0: + if ( bLOSIndexY == 4 ) + { + bLocation = LOC_0_4; + } + break; + case 3: + if ( bLOSIndexY == 4 ) + { + bLocation = LOC_3_4; + } + break; + case 4: + switch( bLOSIndexY ) + { case 0: - if ( bLOSIndexY == 4 ) - { - bLocation = LOC_0_4; - } + bLocation = LOC_4_0; break; case 3: - if ( bLOSIndexY == 4 ) - { - bLocation = LOC_3_4; - } + bLocation = LOC_4_3; break; case 4: - switch( bLOSIndexY ) - { - case 0: - bLocation = LOC_4_0; - break; - case 3: - bLocation = LOC_4_3; - break; - case 4: - bLocation = LOC_4_4; - break; - default: - break; - } + bLocation = LOC_4_4; break; default: break; + } + break; + default: + break; } if ( bLocation == LOC_OTHER ) @@ -347,12 +355,12 @@ BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX if ( fTopRight ) { if (!WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( SOUTH )) ) && - !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo) ) && - !OpenRightOrientedDoorWithDoorOnRightOfEdgeExists( (INT16) (iGridNo + DirectionInc( SOUTH )) ) ) + !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo) ) && + !OpenRightOrientedDoorWithDoorOnRightOfEdgeExists( (INT16) (iGridNo + DirectionInc( SOUTH )) ) ) { return( FALSE ); } - + } } @@ -361,8 +369,8 @@ BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX if ( fTopLeft ) { if ( !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( WEST )) ) && - !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( SOUTHWEST ) ) ) && - !OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( (INT16) (iGridNo + DirectionInc( WEST )) ) ) + !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( SOUTHWEST ) ) ) && + !OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( (INT16) (iGridNo + DirectionInc( WEST )) ) ) { return( FALSE ); } @@ -376,8 +384,8 @@ BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX if ( fTopLeft ) { if ( !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( EAST )) ) && - !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo) ) && - !OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( (INT16) (iGridNo + DirectionInc( EAST )) ) ) + !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo) ) && + !OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( (INT16) (iGridNo + DirectionInc( EAST )) ) ) { return( FALSE ); } @@ -396,8 +404,8 @@ BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX else if ( fTopRight ) { if ( !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( NORTHEAST )) ) && - !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( NORTH ) ) ) && - !OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( (INT16) (iGridNo + DirectionInc( NORTHEAST )) ) ) + !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( NORTH ) ) ) && + !OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( (INT16) (iGridNo + DirectionInc( NORTHEAST )) ) ) { return( FALSE ); } @@ -424,7 +432,7 @@ BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX if ( fTopRight ) { if (!WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( NORTH )) ) && - !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( NORTH )) ) ) + !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( NORTH )) ) ) { return( FALSE ); } @@ -446,7 +454,7 @@ BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX if ( fTopLeft ) { if (!WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( WEST )) ) && - !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( WEST )) ) ) + !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( WEST )) ) ) { return( FALSE ); } @@ -460,10 +468,10 @@ BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX if ( (bLocation == LOC_3_4 && fTopLeft) || (bLocation == LOC_4_3 && fTopRight) || (bLocation == LOC_4_4) ) { if ( !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( EAST ) ) ) && - !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( SOUTH ) ) ) && - !OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( (INT16) (iGridNo + DirectionInc( EAST ) ) ) && - !OpenRightOrientedDoorWithDoorOnRightOfEdgeExists( (INT16) (iGridNo + DirectionInc( SOUTH ) ) ) - ) + !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( SOUTH ) ) ) && + !OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( (INT16) (iGridNo + DirectionInc( EAST ) ) ) && + !OpenRightOrientedDoorWithDoorOnRightOfEdgeExists( (INT16) (iGridNo + DirectionInc( SOUTH ) ) ) + ) { return( FALSE ); } @@ -472,9 +480,9 @@ BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX } -/* + /* -*/ + */ @@ -488,124 +496,124 @@ BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX // N-S at west corner: (0, 4), (4, 3) // E-W at south corner: (4, 4), (3, 4), (4, 3) (completely new) -/* + /* // possibly shooting at corner in which case we should let it pass if ( bLOSIndexX == 0) { - if ( bLOSIndexY == (PROFILE_Y_SIZE - 1)) - { - // maybe looking E-W at (screenwise) north corner of building, or through open door - if ( ( ddHorizAngle > (0) && ddHorizAngle < (PI * 1 / 2) ) || ( ddHorizAngle < (-PI * 1 / 2) && ddHorizAngle > ( -PI ) ) ) - { - // if door is normal and OPEN and inside type then we let E-W pass - if ( (pStructure->fFlags & STRUCTURE_DOOR) && (pStructure->fFlags & STRUCTURE_OPEN) ) - { - if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == INSIDE_TOP_RIGHT ) - { - fResolveHit = FALSE; - } - } + if ( bLOSIndexY == (PROFILE_Y_SIZE - 1)) + { + // maybe looking E-W at (screenwise) north corner of building, or through open door + if ( ( ddHorizAngle > (0) && ddHorizAngle < (PI * 1 / 2) ) || ( ddHorizAngle < (-PI * 1 / 2) && ddHorizAngle > ( -PI ) ) ) + { + // if door is normal and OPEN and inside type then we let E-W pass + if ( (pStructure->fFlags & STRUCTURE_DOOR) && (pStructure->fFlags & STRUCTURE_OPEN) ) + { + if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == INSIDE_TOP_RIGHT ) + { + fResolveHit = FALSE; + } + } - // if wall orientation is top-left, then check W of this location - // if no wall of same orientation there, let bullet through - if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT ) - { - if (!WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( WEST )) ) && - !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( WEST )) ) ) - { - fResolveHit = FALSE; - } - } - } - else if ( ( ddHorizAngle < (0) && ddHorizAngle > ( -PI * 1 / 2) ) || ( ddHorizAngle > ( PI * 1 / 2 ) && ddHorizAngle < (PI) ) ) - { - // maybe looking N-S at (screenwise) west corner of building + // if wall orientation is top-left, then check W of this location + // if no wall of same orientation there, let bullet through + if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT ) + { + if (!WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( WEST )) ) && + !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( WEST )) ) ) + { + fResolveHit = FALSE; + } + } + } + else if ( ( ddHorizAngle < (0) && ddHorizAngle > ( -PI * 1 / 2) ) || ( ddHorizAngle > ( PI * 1 / 2 ) && ddHorizAngle < (PI) ) ) + { + // maybe looking N-S at (screenwise) west corner of building - // if wall orientation is top-left, then check W of this location - // if no wall of same orientation there, let bullet through - if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT ) - { - if ( !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( WEST )) ) && - !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( SOUTHWEST ) ) ) && - !OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( (INT16) (iGridNo + DirectionInc( WEST )) ) ) - { - fResolveHit = FALSE; - } - } + // if wall orientation is top-left, then check W of this location + // if no wall of same orientation there, let bullet through + if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT ) + { + if ( !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( WEST )) ) && + !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( SOUTHWEST ) ) ) && + !OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( (INT16) (iGridNo + DirectionInc( WEST )) ) ) + { + fResolveHit = FALSE; + } + } - } + } - } + } } else if (bLOSIndexX == (PROFILE_X_SIZE - 1)) { - if (bLOSIndexY == 0) - { - // maybe looking E-W at (screenwise) north corner of building - if ( ( ddHorizAngle > (0) && ddHorizAngle < (PI * 1 / 2) ) || ( ddHorizAngle < (-PI * 1 / 2) && ddHorizAngle > ( -PI ) ) ) - { - // if wall orientation is top-right, then check N of this location - // if no wall of same orientation there, let bullet through - if ( pStructure->ubWallOrientation == INSIDE_TOP_RIGHT || pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT ) - { - if (!WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( NORTH )) ) && - !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( NORTH )) ) ) - { - fResolveHit = FALSE; - } - } - } - else - { - // if door is normal and OPEN and outside type then we let N-S pass - if ( (pStructure->fFlags & STRUCTURE_DOOR) && (pStructure->fFlags & STRUCTURE_OPEN) ) - { - if ( pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT ) - { - fResolveHit = FALSE; - } - } - } - } - else if ( bLOSIndexY == (PROFILE_Y_SIZE - 1) || bLOSIndexY == (PROFILE_Y_SIZE - 2) ) - { - // maybe (SCREENWISE) west or east corner of building and looking N - if ( ( ddHorizAngle < (0) && ddHorizAngle > ( -PI * 1 / 2) ) || ( ddHorizAngle > ( PI * 1 / 2 ) && ddHorizAngle < (PI) ) ) - { - // if wall orientation is top-right, then check S of this location - // if wall orientation is top-left, then check E of this location - // if no wall of same orientation there, let bullet through - if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT ) - { - if ( !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( EAST )) ) && - !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo) ) && - !OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( (INT16) (iGridNo + DirectionInc( EAST )) ) ) - { - fResolveHit = FALSE; - } - } - else if ( pStructure->ubWallOrientation == INSIDE_TOP_RIGHT || pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT ) - { - if (!WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( SOUTH )) ) && - !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo) ) && - !OpenRightOrientedDoorWithDoorOnRightOfEdgeExists( (INT16) (iGridNo + DirectionInc( SOUTH )) ) ) - { - fResolveHit = FALSE; - } - - } - } - // the following only at 4,4 - else if ( bLOSIndexY == (PROFILE_Y_SIZE - 1) ) - { - if ( pStructure->ubWallOrientation == NO_ORIENTATION) - { - // very top north corner of building, and going (screenwise) west or east - fResolveHit = FALSE; - } - } - } + if (bLOSIndexY == 0) + { + // maybe looking E-W at (screenwise) north corner of building + if ( ( ddHorizAngle > (0) && ddHorizAngle < (PI * 1 / 2) ) || ( ddHorizAngle < (-PI * 1 / 2) && ddHorizAngle > ( -PI ) ) ) + { + // if wall orientation is top-right, then check N of this location + // if no wall of same orientation there, let bullet through + if ( pStructure->ubWallOrientation == INSIDE_TOP_RIGHT || pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT ) + { + if (!WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( NORTH )) ) && + !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( NORTH )) ) ) + { + fResolveHit = FALSE; + } + } + } + else + { + // if door is normal and OPEN and outside type then we let N-S pass + if ( (pStructure->fFlags & STRUCTURE_DOOR) && (pStructure->fFlags & STRUCTURE_OPEN) ) + { + if ( pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT ) + { + fResolveHit = FALSE; + } + } + } + } + else if ( bLOSIndexY == (PROFILE_Y_SIZE - 1) || bLOSIndexY == (PROFILE_Y_SIZE - 2) ) + { + // maybe (SCREENWISE) west or east corner of building and looking N + if ( ( ddHorizAngle < (0) && ddHorizAngle > ( -PI * 1 / 2) ) || ( ddHorizAngle > ( PI * 1 / 2 ) && ddHorizAngle < (PI) ) ) + { + // if wall orientation is top-right, then check S of this location + // if wall orientation is top-left, then check E of this location + // if no wall of same orientation there, let bullet through + if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT ) + { + if ( !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo + DirectionInc( EAST )) ) && + !WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo) ) && + !OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( (INT16) (iGridNo + DirectionInc( EAST )) ) ) + { + fResolveHit = FALSE; + } + } + else if ( pStructure->ubWallOrientation == INSIDE_TOP_RIGHT || pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT ) + { + if (!WallOrClosedDoorExistsOfTopRightOrientation( (INT16) (iGridNo + DirectionInc( SOUTH )) ) && + !WallOrClosedDoorExistsOfTopLeftOrientation( (INT16) (iGridNo) ) && + !OpenRightOrientedDoorWithDoorOnRightOfEdgeExists( (INT16) (iGridNo + DirectionInc( SOUTH )) ) ) + { + fResolveHit = FALSE; + } + + } + } + // the following only at 4,4 + else if ( bLOSIndexY == (PROFILE_Y_SIZE - 1) ) + { + if ( pStructure->ubWallOrientation == NO_ORIENTATION) + { + // very top north corner of building, and going (screenwise) west or east + fResolveHit = FALSE; + } + } + } } */ @@ -615,23 +623,23 @@ BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX /* - * - * The line of sight code is now used to simulate smelling through the air (for monsters); - * It obeys the following rules: - * - ignores trees and vegetation - * - ignores people - * - should always start off with head height for both source and target, so that lying down makes no difference - * - stop at closed windows - * - stop for other obstacles - * - * Just for reference, normal sight obeys the following rules: - * - trees & vegetation reduce the maximum sighting distance - * - ignores people - * - starts at height relative to stance - * - ignores windows - * - stops at other obstacles - * - */ +* +* The line of sight code is now used to simulate smelling through the air (for monsters); +* It obeys the following rules: +* - ignores trees and vegetation +* - ignores people +* - should always start off with head height for both source and target, so that lying down makes no difference +* - stop at closed windows +* - stop for other obstacles +* +* Just for reference, normal sight obeys the following rules: +* - trees & vegetation reduce the maximum sighting distance +* - ignores people +* - starts at height relative to stance +* - ignores windows +* - stops at other obstacles +* +*/ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, FLOAT dEndY, FLOAT dEndZ, UINT8 ubTileSightLimit, UINT8 ubTreeSightReduction, INT8 bAware, INT32 bCamouflage, BOOLEAN fSmell, INT16 * psWindowGridNo ) { // Parameters... @@ -667,7 +675,7 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, INT32 iEndCubesAboveLevelZ; INT32 iStartCubesZ; INT32 iEndCubesZ; - + INT16 sDesiredLevel; @@ -737,10 +745,10 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, dStartX = (FLOAT) (((INT32)dStartX) / 10) * 10 + 5; dStartY = (FLOAT) (((INT32)dStartY) / 10) * 10 + 5; - + dEndX = (FLOAT) (((INT32)dEndX) / 10) * 10 + 5; dEndY = (FLOAT) (((INT32)dEndY) / 10) * 10 + 5; - + dDeltaX = dEndX - dStartX; dDeltaY = dEndY - dStartY; dDeltaZ = dEndZ - dStartZ; @@ -767,18 +775,18 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, ddHorizAngle = atan2( dDeltaY, dDeltaX ); - #ifdef LOS_DEBUG - memset( &gLOSTestResults, 0, sizeof( LOSResults ) ); - gLOSTestResults.fLOSTestPerformed = TRUE; - gLOSTestResults.iStartX = (INT32) dStartX; - gLOSTestResults.iStartY = (INT32) dStartY; - gLOSTestResults.iStartZ = (INT32) dStartZ; - gLOSTestResults.iEndX = (INT32) dEndX; - gLOSTestResults.iEndY = (INT32) dEndY; - gLOSTestResults.iEndZ = (INT32) dEndZ; - gLOSTestResults.iMaxDistance = (INT32) iSightLimit; - gLOSTestResults.iDistance = (INT32) dDistance; - #endif +#ifdef LOS_DEBUG + memset( &gLOSTestResults, 0, sizeof( LOSResults ) ); + gLOSTestResults.fLOSTestPerformed = TRUE; + gLOSTestResults.iStartX = (INT32) dStartX; + gLOSTestResults.iStartY = (INT32) dStartY; + gLOSTestResults.iStartZ = (INT32) dStartZ; + gLOSTestResults.iEndX = (INT32) dEndX; + gLOSTestResults.iEndY = (INT32) dEndY; + gLOSTestResults.iEndZ = (INT32) dEndZ; + gLOSTestResults.iMaxDistance = (INT32) iSightLimit; + gLOSTestResults.iDistance = (INT32) dDistance; +#endif qIncrX = FloatToFixed( dDeltaX / (FLOAT)iDistance ); qIncrY = FloatToFixed( dDeltaY / (FLOAT)iDistance ); @@ -864,7 +872,7 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, // first move will be 1 step // plus a fractional part equal to half of the difference between the delta and // the increment times the distance - + qCurrX = FloatToFixed( dStartX ) + qIncrX + ( FloatToFixed( dDeltaX ) - qIncrX * iDistance ) / 2; qCurrY = FloatToFixed( dStartY ) + qIncrY + ( FloatToFixed( dDeltaY ) - qIncrY * iDistance ) / 2; qCurrZ = FloatToFixed( dStartZ ) + qIncrZ + ( FloatToFixed( dDeltaZ ) - qIncrZ * iDistance ) / 2; @@ -919,20 +927,20 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, if (iCurrAboveLevelZ < 0) { // ground is in the way! - #ifdef LOS_DEBUG - gLOSTestResults.iStoppedX = FIXEDPT_TO_INT32( qCurrX ); - gLOSTestResults.iStoppedY = FIXEDPT_TO_INT32( qCurrY ); - gLOSTestResults.iStoppedZ = FIXEDPT_TO_INT32( qCurrZ ); - // subtract one to compensate for rounding up when negative - gLOSTestResults.iCurrCubesZ = 0; - #endif +#ifdef LOS_DEBUG + gLOSTestResults.iStoppedX = FIXEDPT_TO_INT32( qCurrX ); + gLOSTestResults.iStoppedY = FIXEDPT_TO_INT32( qCurrY ); + gLOSTestResults.iStoppedZ = FIXEDPT_TO_INT32( qCurrZ ); + // subtract one to compensate for rounding up when negative + gLOSTestResults.iCurrCubesZ = 0; +#endif return( 0 ); } // check for the existence of structures pStructure = pMapElement->pStructureHead; if (pStructure == NULL) { // no structures in this tile, AND THAT INCLUDES ROOFS! :-) - + // new system; figure out how many steps until we cross the next edge // and then fast forward that many steps. @@ -974,37 +982,37 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, iStepsToTravel = __min( iStepsToTravelX, iStepsToTravelY ) + 1; -/* + /* if (qIncrX > 0) { - qDistToTravelX = INT32_TO_FIXEDPT( CELL_X_SIZE ) - (qCurrX % INT32_TO_FIXEDPT( CELL_X_SIZE )); - iStepsToTravelX = qDistToTravelX / qIncrX; + qDistToTravelX = INT32_TO_FIXEDPT( CELL_X_SIZE ) - (qCurrX % INT32_TO_FIXEDPT( CELL_X_SIZE )); + iStepsToTravelX = qDistToTravelX / qIncrX; } else if (qIncrX < 0) { - qDistToTravelX = qCurrX % INT32_TO_FIXEDPT( CELL_X_SIZE ); - iStepsToTravelX = qDistToTravelX / (-qIncrX); + qDistToTravelX = qCurrX % INT32_TO_FIXEDPT( CELL_X_SIZE ); + iStepsToTravelX = qDistToTravelX / (-qIncrX); } else { - // make sure we don't consider X a limit :-) - iStepsToTravelX = 1000000; + // make sure we don't consider X a limit :-) + iStepsToTravelX = 1000000; } if (qIncrY > 0) { - qDistToTravelY = INT32_TO_FIXEDPT( CELL_Y_SIZE ) - (qCurrY % INT32_TO_FIXEDPT( CELL_Y_SIZE )); - iStepsToTravelY = qDistToTravelY / qIncrY; + qDistToTravelY = INT32_TO_FIXEDPT( CELL_Y_SIZE ) - (qCurrY % INT32_TO_FIXEDPT( CELL_Y_SIZE )); + iStepsToTravelY = qDistToTravelY / qIncrY; } else if (qIncrY < 0) { - qDistToTravelY = qCurrY % INT32_TO_FIXEDPT( CELL_Y_SIZE ); - iStepsToTravelY = qDistToTravelY / (-qIncrY); + qDistToTravelY = qCurrY % INT32_TO_FIXEDPT( CELL_Y_SIZE ); + iStepsToTravelY = qDistToTravelY / (-qIncrY); } else { - // make sure we don't consider Y a limit :-) - iStepsToTravelY = 1000000; + // make sure we don't consider Y a limit :-) + iStepsToTravelY = 1000000; } // add 1 to the # of steps to travel to go INTO the next tile @@ -1021,13 +1029,13 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, if (qCurrZ < qLandHeight && iLoop < iDistance) { // ground is in the way! - #ifdef LOS_DEBUG - gLOSTestResults.iStoppedX = FIXEDPT_TO_INT32( qCurrX ); - gLOSTestResults.iStoppedY = FIXEDPT_TO_INT32( qCurrY ); - gLOSTestResults.iStoppedZ = FIXEDPT_TO_INT32( qCurrZ ); - // subtract one to compensate for rounding up when negative - gLOSTestResults.iCurrCubesZ = CONVERT_HEIGHTUNITS_TO_INDEX( iCurrCubesAboveLevelZ ) - 1; - #endif +#ifdef LOS_DEBUG + gLOSTestResults.iStoppedX = FIXEDPT_TO_INT32( qCurrX ); + gLOSTestResults.iStoppedY = FIXEDPT_TO_INT32( qCurrY ); + gLOSTestResults.iStoppedZ = FIXEDPT_TO_INT32( qCurrZ ); + // subtract one to compensate for rounding up when negative + gLOSTestResults.iCurrCubesZ = CONVERT_HEIGHTUNITS_TO_INDEX( iCurrCubesAboveLevelZ ) - 1; +#endif return( 0 ); } @@ -1138,20 +1146,20 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, { DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("LineOfSightTest: couldn't see thru wall, thermal = %d",fSmell)); // out of visual range - #ifdef LOS_DEBUG - gLOSTestResults.fOutOfRange = TRUE; - gLOSTestResults.iCurrCubesZ = iCurrCubesZ; - #endif +#ifdef LOS_DEBUG + gLOSTestResults.fOutOfRange = TRUE; + gLOSTestResults.iCurrCubesZ = iCurrCubesZ; +#endif return( 0 ); } - + /* // smell-line stopped by obstacle! #ifdef LOS_DEBUG - gLOSTestResults.iStoppedX = FIXEDPT_TO_INT32( qCurrX ); - gLOSTestResults.iStoppedY = FIXEDPT_TO_INT32( qCurrY ); - gLOSTestResults.iStoppedZ = FIXEDPT_TO_INT32( qCurrZ ); - gLOSTestResults.iCurrCubesZ = iCurrCubesAboveLevelZ; + gLOSTestResults.iStoppedX = FIXEDPT_TO_INT32( qCurrX ); + gLOSTestResults.iStoppedY = FIXEDPT_TO_INT32( qCurrY ); + gLOSTestResults.iStoppedZ = FIXEDPT_TO_INT32( qCurrZ ); + gLOSTestResults.iCurrCubesZ = iCurrCubesAboveLevelZ; #endif return( 0 ); */ @@ -1175,17 +1183,17 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, // use standard value iAdjSightLimit -= ubTreeSightReduction; } - #ifdef LOS_DEBUG - gLOSTestResults.ubTreeSpotsHit++; - gLOSTestResults.iMaxDistance = iSightLimit; - #endif +#ifdef LOS_DEBUG + gLOSTestResults.ubTreeSpotsHit++; + gLOSTestResults.iMaxDistance = iSightLimit; +#endif if (iDistance > iAdjSightLimit) { // out of visual range - #ifdef LOS_DEBUG - gLOSTestResults.fOutOfRange = TRUE; - gLOSTestResults.iCurrCubesZ = iCurrCubesZ; - #endif +#ifdef LOS_DEBUG + gLOSTestResults.fOutOfRange = TRUE; + gLOSTestResults.iCurrCubesZ = iCurrCubesZ; +#endif return( 0 ); } } @@ -1251,12 +1259,12 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, if (fResolveHit) { // hit the obstacle! - #ifdef LOS_DEBUG - gLOSTestResults.iStoppedX = FIXEDPT_TO_INT32( qCurrX ); - gLOSTestResults.iStoppedY = FIXEDPT_TO_INT32( qCurrY ); - gLOSTestResults.iStoppedZ = FIXEDPT_TO_INT32( qCurrZ ); - gLOSTestResults.iCurrCubesZ = iCurrCubesAboveLevelZ; - #endif +#ifdef LOS_DEBUG + gLOSTestResults.iStoppedX = FIXEDPT_TO_INT32( qCurrX ); + gLOSTestResults.iStoppedY = FIXEDPT_TO_INT32( qCurrY ); + gLOSTestResults.iStoppedZ = FIXEDPT_TO_INT32( qCurrZ ); + gLOSTestResults.iCurrCubesZ = iCurrCubesAboveLevelZ; +#endif return( 0 ); } } @@ -1300,13 +1308,13 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, // couple of iterations. } while( (bLOSIndexX == bOldLOSIndexX) && (bLOSIndexY == bOldLOSIndexY) && (iCurrCubesZ == iOldCubesZ)); - iCurrTileX = FIXEDPT_TO_TILE_NUM( qCurrX ); + iCurrTileX = FIXEDPT_TO_TILE_NUM( qCurrX ); iCurrTileY = FIXEDPT_TO_TILE_NUM( qCurrY ); } } while( (iCurrTileX == iOldTileX) && (iCurrTileY == iOldTileY) && (iLoop < iDistance)); // leaving a tile, check to see if it had gas in it -// if ( pMapElement->ubExtFlags[0] & (MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS) ) + // if ( pMapElement->ubExtFlags[0] & (MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS) ) if ( pMapElement->ubExtFlags[0] & (MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS | MAPELEMENT_EXT_BURNABLEGAS) ) { if ( (pMapElement->ubExtFlags[0] & MAPELEMENT_EXT_SMOKE) && !fSmell ) @@ -1324,10 +1332,10 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, /* else { - // losing 1/3rd results in chances to hit which are WAY too low when firing from out of - // two tiles of smoke... changing this to a 1/6 penalty - - iAdjSightLimit -= iSightLimit / 6; + // losing 1/3rd results in chances to hit which are WAY too low when firing from out of + // two tiles of smoke... changing this to a 1/6 penalty + + iAdjSightLimit -= iSightLimit / 6; } */ } @@ -1348,9 +1356,9 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, // unless the distance is integral, after the loop there will be a // fractional amount of distance remaining which is unchecked // but we shouldn't(?) need to check it because the target is there! - #ifdef LOS_DEBUG - gLOSTestResults.fLOSClear = TRUE; - #endif +#ifdef LOS_DEBUG + gLOSTestResults.fLOSClear = TRUE; +#endif // this somewhat complicated formula does the following: // it starts with the distance to the target // it adds the difference between the original and adjusted sight limit, = the amount of cover @@ -1398,121 +1406,121 @@ BOOLEAN CalculateSoldierZPos( SOLDIERTYPE * pSoldier, UINT8 ubPosType, FLOAT * p ubHeight = gAnimControl[ pSoldier->usAnimState ].ubEndHeight; } - + switch( ubPosType ) { - case LOS_POS: - switch ( ubHeight ) - { - case ANIM_STAND: - *pdZPos = STANDING_LOS_POS; - break; - case ANIM_CROUCH: - *pdZPos = CROUCHED_LOS_POS; - break; - case ANIM_PRONE: - *pdZPos = PRONE_LOS_POS; - break; - default: - return( FALSE ); - } + case LOS_POS: + switch ( ubHeight ) + { + case ANIM_STAND: + *pdZPos = STANDING_LOS_POS; break; - case FIRING_POS: - switch ( ubHeight ) - { - case ANIM_STAND: - *pdZPos = STANDING_FIRING_POS; - break; - case ANIM_CROUCH: - *pdZPos = CROUCHED_FIRING_POS; - break; - case ANIM_PRONE: - *pdZPos = PRONE_FIRING_POS; - break; - default: - return( FALSE ); - } + case ANIM_CROUCH: + *pdZPos = CROUCHED_LOS_POS; break; - case TARGET_POS: - switch ( ubHeight ) - { - case ANIM_STAND: - *pdZPos = STANDING_TARGET_POS; - break; - case ANIM_CROUCH: - *pdZPos = CROUCHED_TARGET_POS; - break; - case ANIM_PRONE: - *pdZPos = PRONE_TARGET_POS; - break; - default: - return( FALSE ); - } + case ANIM_PRONE: + *pdZPos = PRONE_LOS_POS; break; - case HEAD_TARGET_POS: - switch ( ubHeight ) - { - case ANIM_STAND: - *pdZPos = STANDING_HEAD_TARGET_POS; - break; - case ANIM_CROUCH: - *pdZPos = CROUCHED_HEAD_TARGET_POS; - break; - case ANIM_PRONE: - *pdZPos = PRONE_HEAD_TARGET_POS; - break; - default: - return( FALSE ); - } + default: + return( FALSE ); + } + break; + case FIRING_POS: + switch ( ubHeight ) + { + case ANIM_STAND: + *pdZPos = STANDING_FIRING_POS; break; - case TORSO_TARGET_POS: - switch ( ubHeight ) - { - case ANIM_STAND: - *pdZPos = STANDING_TORSO_TARGET_POS; - break; - case ANIM_CROUCH: - *pdZPos = CROUCHED_TORSO_TARGET_POS; - break; - case ANIM_PRONE: - *pdZPos = PRONE_TORSO_TARGET_POS; - break; - default: - return( FALSE ); - } + case ANIM_CROUCH: + *pdZPos = CROUCHED_FIRING_POS; break; - case LEGS_TARGET_POS: - switch ( ubHeight ) - { - case ANIM_STAND: - *pdZPos = STANDING_LEGS_TARGET_POS; - break; - case ANIM_CROUCH: - *pdZPos = CROUCHED_LEGS_TARGET_POS; - break; - case ANIM_PRONE: - *pdZPos = PRONE_LEGS_TARGET_POS; - break; - default: - return( FALSE ); - } + case ANIM_PRONE: + *pdZPos = PRONE_FIRING_POS; break; - case HEIGHT: - switch ( ubHeight ) - { - case ANIM_STAND: - *pdZPos = STANDING_HEIGHT; - break; - case ANIM_CROUCH: - *pdZPos = CROUCHED_HEIGHT; - break; - case ANIM_PRONE: - *pdZPos = PRONE_HEIGHT; - break; - default: - return( FALSE ); - } + default: + return( FALSE ); + } + break; + case TARGET_POS: + switch ( ubHeight ) + { + case ANIM_STAND: + *pdZPos = STANDING_TARGET_POS; break; + case ANIM_CROUCH: + *pdZPos = CROUCHED_TARGET_POS; + break; + case ANIM_PRONE: + *pdZPos = PRONE_TARGET_POS; + break; + default: + return( FALSE ); + } + break; + case HEAD_TARGET_POS: + switch ( ubHeight ) + { + case ANIM_STAND: + *pdZPos = STANDING_HEAD_TARGET_POS; + break; + case ANIM_CROUCH: + *pdZPos = CROUCHED_HEAD_TARGET_POS; + break; + case ANIM_PRONE: + *pdZPos = PRONE_HEAD_TARGET_POS; + break; + default: + return( FALSE ); + } + break; + case TORSO_TARGET_POS: + switch ( ubHeight ) + { + case ANIM_STAND: + *pdZPos = STANDING_TORSO_TARGET_POS; + break; + case ANIM_CROUCH: + *pdZPos = CROUCHED_TORSO_TARGET_POS; + break; + case ANIM_PRONE: + *pdZPos = PRONE_TORSO_TARGET_POS; + break; + default: + return( FALSE ); + } + break; + case LEGS_TARGET_POS: + switch ( ubHeight ) + { + case ANIM_STAND: + *pdZPos = STANDING_LEGS_TARGET_POS; + break; + case ANIM_CROUCH: + *pdZPos = CROUCHED_LEGS_TARGET_POS; + break; + case ANIM_PRONE: + *pdZPos = PRONE_LEGS_TARGET_POS; + break; + default: + return( FALSE ); + } + break; + case HEIGHT: + switch ( ubHeight ) + { + case ANIM_STAND: + *pdZPos = STANDING_HEIGHT; + break; + case ANIM_CROUCH: + *pdZPos = CROUCHED_HEIGHT; + break; + case ANIM_PRONE: + *pdZPos = PRONE_HEIGHT; + break; + default: + return( FALSE ); + } + break; } if ( pSoldier->ubBodyType == HATKIDCIV || pSoldier->ubBodyType == KIDCIV ) { @@ -1599,7 +1607,7 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE INT16 sDistance; sDistance = PythSpacesAway( pStartSoldier->sGridNo, pEndSoldier->sGridNo ); - + if ( sDistance <= 8 ) { // blind spot? @@ -1641,28 +1649,28 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE // reduce visibility by up to a third for camouflage! switch( pEndSoldier->bOverTerrainType ) { - case LOW_GRASS: - case HIGH_GRASS: // jungle camo bonus - iTemp -= iTemp * (jungle * bEffectiveCamo / 3 / totalCamo) / 100; - break; - case FLAT_FLOOR: // flat floor = indoors - case PAVED_ROAD: // urban camo bonus - iTemp -= iTemp * (urban * bEffectiveCamo / 3 / totalCamo) / 100; - break; - case DIRT_ROAD: // desert camo bonus - case TRAIN_TRACKS: - iTemp -= iTemp * (desert * bEffectiveCamo / 3 / totalCamo) / 100; - break; + case LOW_GRASS: + case HIGH_GRASS: // jungle camo bonus + iTemp -= iTemp * (jungle * bEffectiveCamo / 3 / totalCamo) / 100; + break; + case FLAT_FLOOR: // flat floor = indoors + case PAVED_ROAD: // urban camo bonus + iTemp -= iTemp * (urban * bEffectiveCamo / 3 / totalCamo) / 100; + break; + case DIRT_ROAD: // desert camo bonus + case TRAIN_TRACKS: + iTemp -= iTemp * (desert * bEffectiveCamo / 3 / totalCamo) / 100; + break; //case ??? : // snow camo bonus // iTemp -= iTemp * (snow * bEffectiveCamo / 3 / totalCamo) / 100; // break; - case FLAT_GROUND: - //in this case both desert and jungle can work: - iTemp -= iTemp * (jungle * bEffectiveCamo / 3 / totalCamo) / 100; - iTemp -= iTemp * (desert * bEffectiveCamo / 3 / totalCamo) / 100; - break; - default: - break; + case FLAT_GROUND: + //in this case both desert and jungle can work: + iTemp -= iTemp * (jungle * bEffectiveCamo / 3 / totalCamo) / 100; + iTemp -= iTemp * (desert * bEffectiveCamo / 3 / totalCamo) / 100; + break; + default: + break; } ubTileSightLimit = (UINT8) iTemp; } @@ -1737,8 +1745,8 @@ BOOLEAN SoldierToSoldierLineOfSightTimingTest( SOLDIERTYPE * pStartSoldier, SOLD UINT32 uiLoop; UINT32 uiStartTime, uiEndTime; - FILE *OutFile; - + FILE *OutFile; + uiStartTime = GetJA2Clock(); for (uiLoop = 0; uiLoop < uiLoopLimit; uiLoop++) { @@ -1747,10 +1755,10 @@ BOOLEAN SoldierToSoldierLineOfSightTimingTest( SOLDIERTYPE * pStartSoldier, SOLD uiEndTime = GetJA2Clock(); if ((OutFile = fopen("Timing.txt", "a+t")) != NULL) { - #ifdef _DEBUG +#ifdef _DEBUG fprintf(OutFile, "DEBUG: " ); - #endif - fprintf(OutFile, String( "Time for %d calls is %d milliseconds\n", uiLoopLimit, uiEndTime - uiStartTime)); +#endif + fprintf(OutFile, String( "Time for %d calls is %d milliseconds\n", uiLoopLimit, uiEndTime - uiStartTime)); fclose(OutFile); } return( TRUE ); @@ -1820,18 +1828,18 @@ INT32 SoldierToBodyPartLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGrid switch( ubAimLocation ) { - case AIM_SHOT_HEAD: - ubPosType = HEAD_TARGET_POS; - break; - case AIM_SHOT_TORSO: - ubPosType = TORSO_TARGET_POS; - break; - case AIM_SHOT_LEGS: - ubPosType = LEGS_TARGET_POS; - break; - default: - ubPosType = TARGET_POS; - break; + case AIM_SHOT_HEAD: + ubPosType = HEAD_TARGET_POS; + break; + case AIM_SHOT_TORSO: + ubPosType = TORSO_TARGET_POS; + break; + case AIM_SHOT_LEGS: + ubPosType = LEGS_TARGET_POS; + break; + default: + ubPosType = TARGET_POS; + break; } fOk = CalculateSoldierZPos( pEndSoldier, ubPosType, &dEndZPos ); @@ -1861,17 +1869,17 @@ INT32 SoldierToVirtualSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 // manually calculate destination Z position. switch( bStance ) { - case ANIM_STAND: - dEndZPos = STANDING_LOS_POS; - break; - case ANIM_CROUCH: - dEndZPos = CROUCHED_LOS_POS; - break; - case ANIM_PRONE: - dEndZPos = PRONE_LOS_POS; - break; - default: - return( FALSE ); + case ANIM_STAND: + dEndZPos = STANDING_LOS_POS; + break; + case ANIM_CROUCH: + dEndZPos = CROUCHED_LOS_POS; + break; + case ANIM_PRONE: + dEndZPos = PRONE_LOS_POS; + break; + default: + return( FALSE ); } dEndZPos += CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[sGridNo].sHeight ); if (bLevel > 0) @@ -1897,7 +1905,7 @@ INT32 LocationToLocationLineOfSightTest( INT16 sStartGridNo, INT8 bStartLevel, I FLOAT dStartZPos, dEndZPos; INT16 sStartXPos, sStartYPos, sEndXPos, sEndYPos; UINT8 ubStartID; - + ubStartID = WhoIsThere2( sStartGridNo, bStartLevel ); if ( ubStartID != NOBODY ) { @@ -1927,11 +1935,11 @@ INT32 LocationToLocationLineOfSightTest( INT16 sStartGridNo, INT8 bStartLevel, I /* INT32 BulletImpactReducedByRange( INT32 iImpact, INT32 iDistanceTravelled, INT32 iRange ) { - // for now, don't reduce, because did weird stuff to AI! - return( iImpact ); +// for now, don't reduce, because did weird stuff to AI! +return( iImpact ); - // only start reducing impact at distances greater than one range - //return( __max( 1, iImpact * ( 100 - ( PERCENT_BULLET_SLOWED_BY_RANGE * iDistanceTravelled ) / iRange ) / 100 ) ); +// only start reducing impact at distances greater than one range +//return( __max( 1, iImpact * ( 100 - ( PERCENT_BULLET_SLOWED_BY_RANGE * iDistanceTravelled ) / iRange ) / 100 ) ); } */ @@ -1954,13 +1962,13 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend INT8 bHeadSlot = NO_SLOT; OBJECTTYPE Object; SOLDIERTYPE * pTarget; - INT16 sNewGridNo; - BOOLEAN fCanSpewBlood = FALSE; - INT8 bSpewBloodLevel; + INT16 sNewGridNo; + BOOLEAN fCanSpewBlood = FALSE; + INT8 bSpewBloodLevel; // structure IDs for mercs match their merc IDs pTarget = MercPtrs[ pStructure->usStructureID ]; - + if (pBullet->usFlags & BULLET_FLAG_KNIFE) { // Place knife on guy.... @@ -1970,7 +1978,7 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend if (bSlot == NO_SLOT) { // Add item - + CreateItem( pBullet->fromItem, (INT8) pBullet->ubItemStatus, &Object ); AddItemToPool( pTarget->sGridNo, &Object, -1 , pTarget->bLevel, 0, 0 ); @@ -2007,7 +2015,7 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend else { // Determine where the person was hit... - + if ( CREATURE_OR_BLOODCAT( pTarget ) ) { ubHitLocation = AIM_SHOT_TORSO; @@ -2048,7 +2056,10 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend { switch (gAnimControl[ pTarget->usAnimState ].ubEndHeight) { - case ANIM_STAND: + case ANIM_STAND: + // Fall through to crouch if in shallow or medium water + if ( pTarget->bOverTerrainType != LOW_WATER && pTarget->bOverTerrainType != MED_WATER ) + { dZPosRelToMerc = FixedToFloat( pBullet->qCurrZ ) - CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[pBullet->sGridNo].sHeight ); if ( dZPosRelToMerc > HEIGHT_UNITS ) { @@ -2067,29 +2078,30 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend ubHitLocation = AIM_SHOT_TORSO; } break; - case ANIM_CROUCH: - dZPosRelToMerc = FixedToFloat( pBullet->qCurrZ ) - CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[pBullet->sGridNo].sHeight ); - if ( dZPosRelToMerc > HEIGHT_UNITS ) - { - dZPosRelToMerc -= HEIGHT_UNITS; - } - if (dZPosRelToMerc > CROUCHED_HEAD_BOTTOM_POS) - { - ubHitLocation = AIM_SHOT_HEAD; - } - else if ( dZPosRelToMerc < CROUCHED_TORSO_BOTTOM_POS ) - { - // prevent targets in water from being hit in legs - ubHitLocation = AIM_SHOT_LEGS; - } - else - { - ubHitLocation = AIM_SHOT_TORSO; - } - break; - case ANIM_PRONE: + } + case ANIM_CROUCH: + dZPosRelToMerc = FixedToFloat( pBullet->qCurrZ ) - CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[pBullet->sGridNo].sHeight ); + if ( dZPosRelToMerc > HEIGHT_UNITS ) + { + dZPosRelToMerc -= HEIGHT_UNITS; + } + if (dZPosRelToMerc > CROUCHED_HEAD_BOTTOM_POS) + { + ubHitLocation = AIM_SHOT_HEAD; + } + else if ( dZPosRelToMerc < CROUCHED_TORSO_BOTTOM_POS ) + { + // prevent targets in water from being hit in legs + ubHitLocation = AIM_SHOT_LEGS; + } + else + { ubHitLocation = AIM_SHOT_TORSO; - break; + } + break; + case ANIM_PRONE: + ubHitLocation = AIM_SHOT_TORSO; + break; } } @@ -2106,7 +2118,7 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend { // lucky bastard was facing away! } -// else if ( ( (pTarget->inv[HEAD1POS].usItem == NIGHTGOGGLES) || (pTarget->inv[HEAD1POS].usItem == SUNGOGGLES) || (pTarget->inv[HEAD1POS].usItem == GASMASK) ) && ( PreRandom( 100 ) < (UINT32) (pTarget->inv[HEAD1POS].bStatus[ 0 ]) ) ) + // else if ( ( (pTarget->inv[HEAD1POS].usItem == NIGHTGOGGLES) || (pTarget->inv[HEAD1POS].usItem == SUNGOGGLES) || (pTarget->inv[HEAD1POS].usItem == GASMASK) ) && ( PreRandom( 100 ) < (UINT32) (pTarget->inv[HEAD1POS].bStatus[ 0 ]) ) ) else if ( ( (pTarget->inv[HEAD1POS].usItem != NONE) ) && ( PreRandom( 100 ) < (UINT32) (pTarget->inv[HEAD1POS].bStatus[ 0 ]) ) ) { // lucky bastard was wearing protective stuff @@ -2128,7 +2140,7 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend } // Determine damage, checking guy's armour, etc - sRange = (INT16)GetRangeInCellCoordsFromGridNoDiff( pFirer->sGridNo, pTarget->sGridNo ); + sRange = (INT16)GetRangeInCellCoordsFromGridNoDiff( pFirer->sGridNo, pTarget->sGridNo ); if ( gTacticalStatus.uiFlags & GODMODE && !(pFirer->uiStatusFlags & SOLDIER_PC)) { // in god mode, and firer is computer controlled @@ -2183,7 +2195,7 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend iImpact = 0; } iDamage = BulletImpact( pFirer, pTarget, ubHitLocation, iImpact, sHitBy, &ubSpecial ); - + // accidentally shot pTarget->fIntendedTarget = FALSE; } @@ -2238,7 +2250,7 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend // get touchy pFirer->ubTargetID = pTarget->ubID; } - + } @@ -2301,55 +2313,56 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend } } + if ( gTacticalStatus.ubCurrentTeam != OUR_TEAM && pTarget->bTeam == gbPlayerNum ) + { + // someone has been hit so no close-call quotes + gTacticalStatus.fSomeoneHit = TRUE; + } + + // handle hit! Handle damage before deleting the bullet though + WeaponHit( SWeaponHit.usSoldierID, SWeaponHit.usWeaponIndex, SWeaponHit.sDamage, SWeaponHit.sBreathLoss, SWeaponHit.usDirection, SWeaponHit.sXPos, SWeaponHit.sYPos, SWeaponHit.sZPos, SWeaponHit.sRange, SWeaponHit.ubAttackerID, SWeaponHit.fHit, SWeaponHit.ubSpecial, SWeaponHit.ubLocation ); + if (fStopped) { RemoveBullet( pBullet->iBullet ); } - else - { - // ATE: I'm in enemy territory again, evil CC's world :) - // This looks like the place I should add code to spew blood on the ground - // The algorithm I'm going to use is given the current gridno of bullet, - // get a new gridno based on direction it was moving. Check to see if we're not - // going through walls, etc by testing for a path, unless on the roof, in which case it would always - // be legal, but the bLevel May change... - sNewGridNo = NewGridNo( (INT16)pBullet->sGridNo, DirectionInc( gOppositeDirection[ SWeaponHit.usDirection ] ) ); + else + { + // ATE: I'm in enemy territory again, evil CC's world :) + // This looks like the place I should add code to spew blood on the ground + // The algorithm I'm going to use is given the current gridno of bullet, + // get a new gridno based on direction it was moving. Check to see if we're not + // going through walls, etc by testing for a path, unless on the roof, in which case it would always + // be legal, but the bLevel May change... + sNewGridNo = NewGridNo( (INT16)pBullet->sGridNo, DirectionInc( gOppositeDirection[ SWeaponHit.usDirection ] ) ); - bSpewBloodLevel = MercPtrs[ SWeaponHit.usSoldierID ]->bLevel; - fCanSpewBlood = TRUE; + bSpewBloodLevel = MercPtrs[ SWeaponHit.usSoldierID ]->bLevel; + fCanSpewBlood = TRUE; - // If on anything other than bLevel of 0, we can pretty much freely spew blood - if ( bSpewBloodLevel == 0 ) - { - if ( gubWorldMovementCosts[ sNewGridNo ][ gOppositeDirection[ SWeaponHit.usDirection ] ][ 0 ] >= TRAVELCOST_BLOCKED ) - { - fCanSpewBlood = FALSE; - } - } - else - { - // If a roof does not exist here, make level = 0 - if ( !IsRoofPresentAtGridno( sNewGridNo ) ) - { - bSpewBloodLevel = 0; - } - } + // If on anything other than bLevel of 0, we can pretty much freely spew blood + if ( bSpewBloodLevel == 0 ) + { + if ( gubWorldMovementCosts[ sNewGridNo ][ gOppositeDirection[ SWeaponHit.usDirection ] ][ 0 ] >= TRAVELCOST_BLOCKED ) + { + fCanSpewBlood = FALSE; + } + } + else + { + // If a roof does not exist here, make level = 0 + if ( !IsRoofPresentAtGridno( sNewGridNo ) ) + { + bSpewBloodLevel = 0; + } + } - if ( fCanSpewBlood ) - { - // Drop blood dude! + if ( fCanSpewBlood ) + { + // Drop blood dude! InternalDropBlood( sNewGridNo, bSpewBloodLevel, 0, (UINT8)(MAXBLOODQUANTITY), 1 ); - } - } + } + } - if ( gTacticalStatus.ubCurrentTeam != OUR_TEAM && pTarget->bTeam == gbPlayerNum ) - { - // someone has been hit so no close-call quotes - gTacticalStatus.fSomeoneHit = TRUE; - } - - // handle hit! - WeaponHit( SWeaponHit.usSoldierID, SWeaponHit.usWeaponIndex, SWeaponHit.sDamage, SWeaponHit.sBreathLoss, SWeaponHit.usDirection, SWeaponHit.sXPos, SWeaponHit.sYPos, SWeaponHit.sZPos, SWeaponHit.sRange, SWeaponHit.ubAttackerID, SWeaponHit.fHit, SWeaponHit.ubSpecial, SWeaponHit.ubLocation ); return( fStopped ); } @@ -2420,11 +2433,11 @@ INT32 StructureResistanceIncreasedByRange( INT32 iImpactReduction, INT32 iGunRan /* if ( iDistance > iGunRange ) { - return( iImpactReduction * ( 100 + PERCENT_BULLET_SLOWED_BY_RANGE * (iDistance - iGunRange) / iGunRange ) / 100 ); + return( iImpactReduction * ( 100 + PERCENT_BULLET_SLOWED_BY_RANGE * (iDistance - iGunRange) / iGunRange ) / 100 ); } else { - return( iImpactReduction ); + return( iImpactReduction ); } */ } @@ -2451,13 +2464,13 @@ INT32 HandleBulletStructureInteraction( BULLET * pBullet, STRUCTURE * pStructure } //else if ( pBullet->usFlags & BULLET_FLAG_SMALL_MISSILE ) //{ - // stops if using HE ammo + // stops if using HE ammo else if ( AmmoTypes[pBullet->pFirer->inv[ pBullet->pFirer->ubAttackingHand ].ubGunAmmoType].highExplosive && !AmmoTypes[pBullet->pFirer->inv[ pBullet->pFirer->ubAttackingHand ].ubGunAmmoType].antiTank ) { *pfHit = TRUE; return( 0 ); } -// } + // } // ATE: Alrighty, check for shooting door locks... // First check this is a type of struct that can handle locks... @@ -2466,7 +2479,7 @@ INT32 HandleBulletStructureInteraction( BULLET * pBullet, STRUCTURE * pStructure // lookup lock table to see if we have a lock, // and then remove lock if enough damage done.... pDoor = FindDoorInfoAtGridNo( pBullet->sGridNo ); - + // Does it have a lock? INT16 lockBustingPower = AmmoTypes[pBullet->pFirer->inv[ pBullet->pFirer->ubAttackingHand ].ubGunAmmoType].lockBustingPower; @@ -2585,12 +2598,12 @@ INT32 CTGTHandleBulletStructureInteraction( BULLET * pBullet, STRUCTURE * pStruc } //else if ( pBullet->usFlags & BULLET_FLAG_SMALL_MISSILE ) //{ - // stops if using HE ammo + // stops if using HE ammo else if ( AmmoTypes[pBullet->pFirer->inv[ pBullet->pFirer->ubAttackingHand ].ubGunAmmoType].highExplosive && !AmmoTypes[pBullet->pFirer->inv[ pBullet->pFirer->ubAttackingHand ].ubGunAmmoType].antiTank ) { return( pBullet->iImpact ); } -// } + // } else if ( pStructure->fFlags & STRUCTURE_PERSON ) { if ( pStructure->usStructureID != pBullet->ubFirerID && pStructure->usStructureID != pBullet->ubTargetID ) @@ -2716,7 +2729,7 @@ UINT8 CalcChanceToGetThrough( BULLET * pBullet ) return( 0 ); } iCurrCubesAboveLevelZ = CONVERT_HEIGHTUNITS_TO_INDEX( iCurrAboveLevelZ ); - + //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToGetThrough: while pStructure")); while( pStructure ) { @@ -2791,10 +2804,10 @@ UINT8 CalcChanceToGetThrough( BULLET * pBullet ) // (buckshot), if they are the intended target, or beyond the range of automatic friendly fire hits // OR a 1 in 30 chance occurs if (gAnimControl[ MercPtrs[pStructure->usStructureID]->usAnimState ].ubEndHeight == ANIM_STAND && - ( (pBullet->fAimed && pBullet->iLoop > MIN_DIST_FOR_HIT_FRIENDS) || - (!pBullet->fAimed && pBullet->iLoop > MIN_DIST_FOR_HIT_FRIENDS_UNAIMED) - ) - ) + ( (pBullet->fAimed && pBullet->iLoop > MIN_DIST_FOR_HIT_FRIENDS) || + (!pBullet->fAimed && pBullet->iLoop > MIN_DIST_FOR_HIT_FRIENDS_UNAIMED) + ) + ) { // could hit this person! gpLocalStructure[iNumLocalStructures] = pStructure; @@ -2842,7 +2855,7 @@ UINT8 CalcChanceToGetThrough( BULLET * pBullet ) } pStructure = pStructure->pNext; } - + // record old tile location for loop purposes iOldTileX = pBullet->iCurrTileX; iOldTileY = pBullet->iCurrTileY; @@ -2916,7 +2929,7 @@ UINT8 CalcChanceToGetThrough( BULLET * pBullet ) if (pBullet->qCurrZ < qLandHeight && pBullet->iLoop < pBullet->iDistanceLimit) { // ground is in the way! - //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("ChanceChanceToGetThrough done ground in way" )); + //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("ChanceChanceToGetThrough done ground in way" )); return( 0 ); } @@ -3054,7 +3067,7 @@ UINT8 CalcChanceToGetThrough( BULLET * pBullet ) return( 0 ); } - + //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToGetThrough check for bullet drop")); pBullet->sGridNo = MAPROWCOLTOPOS( pBullet->iCurrTileY , pBullet->iCurrTileX ); @@ -3152,18 +3165,18 @@ UINT8 SoldierToSoldierBodyPartChanceToGetThrough( SOLDIERTYPE * pStartSoldier, S CHECKF( pEndSoldier ); switch( ubAimLocation ) { - case AIM_SHOT_HEAD: - ubPosType = HEAD_TARGET_POS; - break; - case AIM_SHOT_TORSO: - ubPosType = TORSO_TARGET_POS; - break; - case AIM_SHOT_LEGS: - ubPosType = LEGS_TARGET_POS; - break; - default: - ubPosType = TARGET_POS; - break; + case AIM_SHOT_HEAD: + ubPosType = HEAD_TARGET_POS; + break; + case AIM_SHOT_TORSO: + ubPosType = TORSO_TARGET_POS; + break; + case AIM_SHOT_LEGS: + ubPosType = LEGS_TARGET_POS; + break; + default: + ubPosType = TARGET_POS; + break; } fOk = CalculateSoldierZPos( pEndSoldier, ubPosType, &dEndZPos ); @@ -3376,7 +3389,7 @@ void CalculateFiringIncrements( DOUBLE ddHorizAngle, DOUBLE ddVerticAngle, DOUBL // to miss a target at 1 tile is about 30 degrees off, at 5 tiles, 6 degrees off // at 15 tiles, 2 degrees off. Thus 30 degrees divided by the # of tiles distance. ddMinimumMiss = MIN_AIMING_SCREWUP / (dd2DDistance / CELL_X_SIZE ); - + if (ddMinimumMiss > ddMaximumMiss) { ddMinimumMiss = ddMaximumMiss; @@ -3410,7 +3423,7 @@ void CalculateFiringIncrements( DOUBLE ddHorizAngle, DOUBLE ddVerticAngle, DOUBL pBullet->qIncrX = FloatToFixed( (FLOAT) cos( ddHorizAngle ) ); pBullet->qIncrY = FloatToFixed( (FLOAT) sin( ddHorizAngle ) ); - + // this is the same as multiplying the X and Y increments by the projection of the line in // 3-space onto the horizontal plane, without reducing the X/Y increments and thus slowing // the LOS code @@ -3448,15 +3461,15 @@ INT8 FireBullet( SOLDIERTYPE * pFirer, BULLET * pBullet, BOOLEAN fFake ) //} //else //{ - pBullet->uiLastUpdate = 0; - pBullet->ubTilesPerUpdate = 1; + pBullet->uiLastUpdate = 0; + pBullet->ubTilesPerUpdate = 1; //} // increment shots fired if shooter has a merc profile - if( ( pFirer->ubProfile != NO_PROFILE ) && ( pFirer->bTeam == 0 ) ) + if( ( pFirer->ubProfile != NO_PROFILE ) && ( pFirer->bTeam == 0 ) ) { - // another shot fired - gMercProfiles[ pFirer->ubProfile ].usShotsFired++; + // another shot fired + gMercProfiles[ pFirer->ubProfile ].usShotsFired++; } if ( Item[ pFirer->usAttackingWeapon ].usItemClass == IC_THROWING_KNIFE ) @@ -3474,7 +3487,7 @@ INT8 FireBullet( SOLDIERTYPE * pFirer, BULLET * pBullet, BOOLEAN fFake ) //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("FireBullet: move bullet")); MoveBullet( pBullet->iBullet ); - //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("FireBullet done")); + //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("FireBullet done")); return( TRUE ); } @@ -3483,18 +3496,18 @@ INT8 FireBullet( SOLDIERTYPE * pFirer, BULLET * pBullet, BOOLEAN fFake ) /* DOUBLE CalculateVerticalAngle( SOLDIERTYPE * pFirer, SOLDIERTYPE * pTarget ) { - DOUBLE dStartZ, dEndZ; +DOUBLE dStartZ, dEndZ; - CalculateSoldierZPos( pFirer, FIRING_POS, &dStartZ ); - CalculateSoldierZPos( pTarget, TARGET_POS, &dEndZ ); +CalculateSoldierZPos( pFirer, FIRING_POS, &dStartZ ); +CalculateSoldierZPos( pTarget, TARGET_POS, &dEndZ ); - dDeltaX = (FLOAT) CenterX( pTarget->sGridNo ) - (FLOAT) CenterX( pFirer->sGridNo ); - dDeltaY = (FLOAT) CenterY( pTarget->sGridNo ) - (FLOAT) CenterY( pFirer->sGridNo ); - dDeltaZ = dEndZ - dStartZ; +dDeltaX = (FLOAT) CenterX( pTarget->sGridNo ) - (FLOAT) CenterX( pFirer->sGridNo ); +dDeltaY = (FLOAT) CenterY( pTarget->sGridNo ) - (FLOAT) CenterY( pFirer->sGridNo ); +dDeltaZ = dEndZ - dStartZ; - d2DDistance = Distance2D( dDeltaX, dDeltaY ); +d2DDistance = Distance2D( dDeltaX, dDeltaY ); - ddOrigHorizAngle = atan2( dDeltaY, dDeltaX ); +ddOrigHorizAngle = atan2( dDeltaY, dDeltaX ); } */ @@ -3534,7 +3547,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA UINT8 ubSpreadIndex = 0; UINT16 usBulletFlags = 0; - //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("FireBulletGivenTarget")); + //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("FireBulletGivenTarget")); CalculateSoldierZPos( pFirer, FIRING_POS, &dStartZ ); @@ -3552,7 +3565,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA d2DDistance = Distance2D( dDeltaX, dDeltaY ); //d2DDistance = Distance2D( dDeltaX, dDeltaY ); - + iDistance = (INT32) d2DDistance; if ( d2DDistance != iDistance ) @@ -3600,7 +3613,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA } ubImpact =(UINT8) GetDamage(&pFirer->inv[pFirer->ubAttackingHand]); -// if (!fFake) + // if (!fFake) { if (fBuckshot) { @@ -3624,7 +3637,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA usBulletFlags |= BULLET_FLAG_BUCKSHOT; } -// ubImpact = AMMO_DAMAGE_ADJUSTMENT_BUCKSHOT( ubImpact ); + // ubImpact = AMMO_DAMAGE_ADJUSTMENT_BUCKSHOT( ubImpact ); ubImpact = (UINT8) (ubImpact * AmmoTypes[pFirer->inv[pFirer->ubAttackingHand].ubGunAmmoType].multipleBulletDamageMultiplier / max(1,AmmoTypes[pFirer->inv[pFirer->ubAttackingHand].ubGunAmmoType].multipleBulletDamageDivisor) ); } } @@ -3689,7 +3702,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA { // temporarily set bullet's sHitBy value to 0 to get unadjusted angles pBullet->sHitBy = 0; - + ddHorizAngle = ddAdjustedHorizAngle + ddShotgunSpread[ubSpreadIndex][ubLoop][0]; ddVerticAngle = ddAdjustedVerticAngle + ddShotgunSpread[ubSpreadIndex][ubLoop][1]; @@ -3729,9 +3742,9 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA pBullet->qCurrY += ( FloatToFixed( dDeltaY ) - pBullet->qIncrY * iDistance ) / 2; pBullet->qCurrZ += ( FloatToFixed( dDeltaZ ) - pBullet->qIncrZ * iDistance ) / 2; } - + pBullet->iImpact = ubImpact; - + pBullet->iRange = GunRange( &(pFirer->inv[pFirer->ubAttackingHand]) ); pBullet->sTargetGridNo = ((INT32)dEndX) / CELL_X_SIZE + ((INT32)dEndY) / CELL_Y_SIZE * WORLD_COLS; @@ -3749,16 +3762,16 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA } else { - if (ubLoop + 1 > pFirer->bBulletsLeft) - { - // this is an error!! - ubLoop = ubLoop; - } + // if (ubLoop + 1 > pFirer->bBulletsLeft) + // { + // // this is an error!! + // ubLoop = ubLoop; + // } FireBullet( pFirer, pBullet, FALSE ); } } - //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("FireBulletGivenTargetDone")); + //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("FireBulletGivenTargetDone")); return( TRUE ); } @@ -3852,7 +3865,7 @@ void MoveBullet( INT32 iBullet ) } pBullet->uiLastUpdate = uiTime; - + do { // check a particular tile @@ -3962,9 +3975,9 @@ void MoveBullet( INT32 iBullet ) /* if ( !( (pStructure->pDBStructureRef->pDBStructure->ubDensity < 100 || iCurrCubesAboveLevelZ == (StructureHeight( pStructure ) - 1) ) ) && (PreRandom( 100 ) >= uiChanceOfHit) ) { - gpLocalStructure[iNumLocalStructures] = pStructure; - gubLocalStructureNumTimesHit[iNumLocalStructures] = 0; - iNumLocalStructures++; + gpLocalStructure[iNumLocalStructures] = pStructure; + gubLocalStructureNumTimesHit[iNumLocalStructures] = 0; + iNumLocalStructures++; } */ } @@ -4023,12 +4036,12 @@ void MoveBullet( INT32 iBullet ) } } else if ( MercPtrs[ pStructure->usStructureID ]->bVisible == TRUE && - gAnimControl[ MercPtrs[pStructure->usStructureID]->usAnimState ].ubEndHeight == ANIM_STAND && - ( (pBullet->fAimed && pBullet->iLoop > MIN_DIST_FOR_HIT_FRIENDS) || - (!pBullet->fAimed && pBullet->iLoop > MIN_DIST_FOR_HIT_FRIENDS_UNAIMED) || - PreRandom( 100 ) < MIN_CHANCE_TO_ACCIDENTALLY_HIT_SOMEONE - ) - ) + gAnimControl[ MercPtrs[pStructure->usStructureID]->usAnimState ].ubEndHeight == ANIM_STAND && + ( (pBullet->fAimed && pBullet->iLoop > MIN_DIST_FOR_HIT_FRIENDS) || + (!pBullet->fAimed && pBullet->iLoop > MIN_DIST_FOR_HIT_FRIENDS_UNAIMED) || + PreRandom( 100 ) < MIN_CHANCE_TO_ACCIDENTALLY_HIT_SOMEONE + ) + ) { // could hit this person! gpLocalStructure[iNumLocalStructures] = pStructure; @@ -4053,24 +4066,24 @@ void MoveBullet( INT32 iBullet ) // bullet goes whizzing by this guy! switch ( gAnimControl[ MercPtrs[pStructure->usStructureID]->usAnimState ].ubEndHeight ) { - case ANIM_PRONE: - // two 1/4 chances of avoiding suppression pt - one below - if (PreRandom( 4 ) == 0) - { - break; - } - // else fall through - case ANIM_CROUCH: - // 1/4 chance of avoiding suppression pt - if (PreRandom( 4 ) == 0) - { - break; - } - // else fall through - default: - MercPtrs[pStructure->usStructureID]->ubSuppressionPoints++; - MercPtrs[pStructure->usStructureID]->ubSuppressorID = pBullet->pFirer->ubID; + case ANIM_PRONE: + // two 1/4 chances of avoiding suppression pt - one below + if (PreRandom( 4 ) == 0) + { break; + } + // else fall through + case ANIM_CROUCH: + // 1/4 chance of avoiding suppression pt + if (PreRandom( 4 ) == 0) + { + break; + } + // else fall through + default: + MercPtrs[pStructure->usStructureID]->ubSuppressionPoints++; + MercPtrs[pStructure->usStructureID]->ubSuppressorID = pBullet->pFirer->ubID; + break; } } } @@ -4121,13 +4134,13 @@ void MoveBullet( INT32 iBullet ) /* if (iCurrCubesAboveLevelZ < STRUCTURE_ON_GROUND_MAX) { - // check objects on the ground - sDesiredLevel = 0; + // check objects on the ground + sDesiredLevel = 0; } else { - // check objects on roofs - sDesiredLevel = 1; + // check objects on roofs + sDesiredLevel = 1; } */ @@ -4148,32 +4161,32 @@ void MoveBullet( INT32 iBullet ) // bullet goes whizzing by this guy! switch ( gAnimControl[ pTarget->usAnimState ].ubEndHeight ) { - case ANIM_PRONE: - // two 1/4 chances of avoiding suppression pt - one below - if (PreRandom( 4 ) == 0) - { - break; - } - // else fall through - case ANIM_CROUCH: - // 1/4 chance of avoiding suppression pt - if (PreRandom( 4 ) == 0) - { - break; - } - // else fall through - default: - pTarget->ubSuppressionPoints++; - pTarget->ubSuppressorID = pBullet->pFirer->ubID; + case ANIM_PRONE: + // two 1/4 chances of avoiding suppression pt - one below + if (PreRandom( 4 ) == 0) + { break; + } + // else fall through + case ANIM_CROUCH: + // 1/4 chance of avoiding suppression pt + if (PreRandom( 4 ) == 0) + { + break; + } + // else fall through + default: + pTarget->ubSuppressionPoints++; + pTarget->ubSuppressorID = pBullet->pFirer->ubID; + break; } } -/* + /* // this could be a close call if ( pTarget->bTeam == gbPlayerNum && pBullet->pFirer->bTeam != gbPlayerNum ) { - pTarget->fCloseCall = TRUE; + pTarget->fCloseCall = TRUE; } */ @@ -4183,7 +4196,7 @@ void MoveBullet( INT32 iBullet ) } } } - + // record old tile location for loop purposes iOldTileX = pBullet->iCurrTileX; iOldTileY = pBullet->iCurrTileY; @@ -4289,7 +4302,7 @@ void MoveBullet( INT32 iBullet ) qCurrX = pBullet->qCurrX + pBullet->qIncrX * i; qCurrY = pBullet->qCurrY + pBullet->qIncrY * i; qCurrZ = pBullet->qCurrZ + pBullet->qIncrZ * i; - + AddMissileTrail( pBullet, qCurrX, qCurrY, qCurrZ ); } } @@ -4475,12 +4488,13 @@ void MoveBullet( INT32 iBullet ) { // ATE: In enemy territory here... ;) // Now that we have hit a corpse, make the bugger twich! - RemoveBullet( pBullet->iBullet ); - + CorpseHit( (INT16)pBullet->sGridNo, pStructure->usStructureID ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., CORPSE HIT") ); - FreeUpAttacker( pBullet->pFirer->ubID ); + // Moved here to keep ABC >0 as long as possible + RemoveBullet( iBullet ); + // ReduceAttackBusyCount( ); return; } else if ( iRemainingImpact <= 0 ) @@ -4529,9 +4543,9 @@ void MoveBullet( INT32 iBullet ) /* else { - // ATE: Found this: Should we be calling this because if we do, it will - // delete a bullet that was not supposed to be deleted.... - //BulletHitStructure( pBullet, 0, 0, pBullet->pFirer, pBullet->qCurrX, pBullet->qCurrY, pBullet->qCurrZ ); + // ATE: Found this: Should we be calling this because if we do, it will + // delete a bullet that was not supposed to be deleted.... + //BulletHitStructure( pBullet, 0, 0, pBullet->pFirer, pBullet->qCurrX, pBullet->qCurrY, pBullet->qCurrZ ); } */ } @@ -4579,10 +4593,10 @@ void MoveBullet( INT32 iBullet ) BulletMissed( pBullet, pBullet->pFirer ); return; } - + pBullet->sGridNo = MAPROWCOLTOPOS( pBullet->iCurrTileY , pBullet->iCurrTileX ); uiTileInc++; - + if ( (pBullet->iLoop > pBullet->iRange * 2) ) { // beyond max effective range, bullet starts to drop! @@ -4649,12 +4663,12 @@ INT32 CheckForCollision( FLOAT dX, FLOAT dY, FLOAT dZ, FLOAT dDeltaX, FLOAT dDel // Check if gridno is in bounds.... if ( !GridNoOnVisibleWorldTile( (INT16) (sX + sY * WORLD_COLS) ) ) { - // return( COLLISION_NONE ); + // return( COLLISION_NONE ); } if ( sX < 0 || sX > WORLD_COLS || sY < 0 || sY > WORLD_COLS ) { -// return( COLLISION_NONE ); + // return( COLLISION_NONE ); } // check a particular tile @@ -4704,7 +4718,7 @@ INT32 CheckForCollision( FLOAT dX, FLOAT dY, FLOAT dZ, FLOAT dDeltaX, FLOAT dDel { pTarget = NULL; } - + // record old tile location for loop purposes // check for collision with the ground @@ -4725,7 +4739,7 @@ INT32 CheckForCollision( FLOAT dX, FLOAT dY, FLOAT dZ, FLOAT dDeltaX, FLOAT dDel pStructure = pMapElement->pStructureHead; if (pStructure == NULL) { // no structures in this tile - + // we can go as far as we like vertically (so long as we don't hit // the ground), but want to stop when we get to the next tile or // the end of the LOS path @@ -4777,8 +4791,8 @@ INT32 CheckForCollision( FLOAT dX, FLOAT dY, FLOAT dZ, FLOAT dDeltaX, FLOAT dDel // check to see if we hit someone //if (pTarget && Distance2D( dX - dTargetX, dY - dTargetY ) < HIT_DISTANCE ) //{ - // well, we're in the right area; it's possible that - // we're firing over or under them though + // well, we're in the right area; it's possible that + // we're firing over or under them though // if ( dZ < dTargetZMax && dZ > dTargetZMin) // { // return( COLLISION_MERC ); @@ -4833,7 +4847,7 @@ INT32 CheckForCollision( FLOAT dX, FLOAT dY, FLOAT dZ, FLOAT dDeltaX, FLOAT dDel if (((*(pStructure->pShape))[bLOSIndexX][bLOSIndexY] & AtHeight[iCurrCubesAboveLevelZ]) > 0) { *pusStructureID = pStructure->usStructureID; - + if (pStructure->fFlags & STRUCTURE_WALLNWINDOW && dZ >= WINDOW_BOTTOM_HEIGHT_UNITS && dZ <= WINDOW_TOP_HEIGHT_UNITS) { if (pStructure->ubWallOrientation == INSIDE_TOP_RIGHT || pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT) @@ -4949,15 +4963,15 @@ INT32 CheckForCollision( FLOAT dX, FLOAT dY, FLOAT dZ, FLOAT dDeltaX, FLOAT dDel } } } - + // Check armour rating..... // ATE; not if small vegitation.... if ( pStructure->pDBStructureRef->pDBStructure->ubArmour != MATERIAL_LIGHT_VEGETATION ) { - if ( !(pStructure->fFlags & STRUCTURE_CORPSE ) ) - { - return( COLLISION_STRUCTURE ); - } + if ( !(pStructure->fFlags & STRUCTURE_CORPSE ) ) + { + return( COLLISION_STRUCTURE ); + } } } } @@ -4970,13 +4984,13 @@ INT32 CheckForCollision( FLOAT dX, FLOAT dY, FLOAT dZ, FLOAT dDeltaX, FLOAT dDel // check to see if we hit someone //if (pTarget && Distance2D( dX - dTargetX, dY - dTargetY ) < HIT_DISTANCE ) //{ - // well, we're in the right area; it's possible that - // we're firing over or under them though + // well, we're in the right area; it's possible that + // we're firing over or under them though // if ( dZ < dTargetZMax && dZ > dTargetZMin) - // { - // return( COLLISION_MERC ); - // } - // } + // { + // return( COLLISION_MERC ); + // } + // } } @@ -4998,7 +5012,7 @@ BOOLEAN CalculateLOSNormal( STRUCTURE *pStructure, INT8 bLOSX, INT8 bLOSY, INT8 INT8 bNumNormals = 0; BOOLEAN fParimeter; - + vector_3 vZ, vTemp2, vNormal, vAveNormal, vTemp, vIncident; vZ.x = 0; @@ -5058,7 +5072,7 @@ BOOLEAN CalculateLOSNormal( STRUCTURE *pStructure, INT8 bLOSX, INT8 bLOSY, INT8 { if (((*(pStructure->pShape))[tX][tY] & AtHeight[ bLOSZ ]) > 0) { - + } else { @@ -5129,7 +5143,7 @@ BOOLEAN CalculateLOSNormal( STRUCTURE *pStructure, INT8 bLOSX, INT8 bLOSY, INT8 //if ( VDotProduct( &vNormal, &vIncident ) > 0 ) { bNumNormals++; - + //Average normal! vTemp = VAdd( &vNormal, &vAveNormal ); vAveNormal = VSetEqual( &vTemp ); @@ -5138,7 +5152,7 @@ BOOLEAN CalculateLOSNormal( STRUCTURE *pStructure, INT8 bLOSX, INT8 bLOSY, INT8 vAveNormal = VGetNormal( &vAveNormal ); } - + } } } @@ -5163,7 +5177,7 @@ BOOLEAN CalculateLOSNormal( STRUCTURE *pStructure, INT8 bLOSX, INT8 bLOSY, INT8 { *pdNormalX = vAveNormal.x; *pdNormalY = vAveNormal.y; - + // OK done, now determine direction if ( dDeltaX > 0 ) diff --git a/Tactical/Map Information.cpp b/Tactical/Map Information.cpp index a98c7072..45c9dec5 100644 --- a/Tactical/Map Information.cpp +++ b/Tactical/Map Information.cpp @@ -20,6 +20,9 @@ #include "sys globals.h" #include "message.h" #include "weapons.h" + #include "environment.h" + #include "lighting.h" + #include "Animated ProgressBar.h" #endif //Don't mess with this value, unless you want to force update all maps in the game! diff --git a/Tactical/Merc Entering.cpp b/Tactical/Merc Entering.cpp index d66ec3a3..d8634410 100644 --- a/Tactical/Merc Entering.cpp +++ b/Tactical/Merc Entering.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Tactical All.h" #else + #include "builddefines.h" #include #include #include "wcheck.h" @@ -29,6 +30,14 @@ #include "english.h" #include "cursors.h" #include "cursor control.h" + #include "Merc Hiring.h" + #include "Font Control.h" + #include "message.h" + #include "Text.h" + #include "strategic turns.h" + #include "ai.h" + #include "Dialogue Control.h" + #include "Music Control.h" #endif #define MAX_MERC_IN_HELI 20 diff --git a/Tactical/Merc Hiring.cpp b/Tactical/Merc Hiring.cpp index 46306be2..408169c0 100644 --- a/Tactical/Merc Hiring.cpp +++ b/Tactical/Merc Hiring.cpp @@ -2,6 +2,7 @@ #include "Tactical All.h" #include "strategic.h" #else + #include "builddefines.h" #include #include #include "wcheck.h" @@ -51,6 +52,12 @@ #include "jascreens.h" #include "text.h" #include "Merc Contract.h" + #include "LaptopSave.h" + #include "personnel.h" + #include "Auto Resolve.h" + #include "Map Screen Interface Bottom.h" + #include "Quests.h" + #include "GameSettings.h" #endif #define MIN_FLIGHT_PREP_TIME 6 diff --git a/Tactical/Militia Control.cpp b/Tactical/Militia Control.cpp index 5939fdde..9361df92 100644 --- a/Tactical/Militia Control.cpp +++ b/Tactical/Militia Control.cpp @@ -10,6 +10,26 @@ #include "Overhead.h" #include "strategicmap.h" #include "PreBattle Interface.h" + #include "Map Screen Interface.h" + #include "Queen Command.h" + #include "strategic.h" + #include "popupbox.h" + #include "interface control.h" + #include "Map Screen Interface Map.h" + #include "renderworld.h" + #include "Text.h" + #include "utilities.h" + #include "Interface.h" + #include "GameSettings.h" + #include "Input.h" + #include "opplist.h" + #include "los.h" + #include "Items.h" + #include "Animation Control.h" + #include "points.h" + #include "Campaign.h" + #include "ai.h" + #include "Isometric Utils.h" #endif #include "MilitiaSquads.h" diff --git a/Tactical/Morale.cpp b/Tactical/Morale.cpp index b41e8cdf..6824d046 100644 --- a/Tactical/Morale.cpp +++ b/Tactical/Morale.cpp @@ -15,6 +15,11 @@ #include "drugs and alcohol.h" #include "StrategicMap.h" #include "Debug.h" + #include "Squads.h" + #include "ai.h" + #include "Campaign.h" + #include "mapscreen.h" + #include "Soldier macros.h" #endif #define MORALE_MOD_MAX 50 // morale *mod* range is -50 to 50, if you change this, check the decay formulas! diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index bca13688..8b214bad 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -1,104 +1,118 @@ #ifdef PRECOMPILEDHEADERS - #include "Tactical All.h" - #include "PreBattle Interface.h" - #include "creature spreading.h" +#include "Tactical All.h" +#include "PreBattle Interface.h" +#include "creature spreading.h" #else - #include - #include - #include "wcheck.h" - #include "stdlib.h" - #include "debug.h" - #include "math.h" - #include "worlddef.h" - #include "worldman.h" - #include "renderworld.h" - #include "Assignments.h" - #include "Soldier Control.h" - #include "Animation Control.h" - #include "Animation Data.h" - #include "Isometric Utils.h" - #include "Event Pump.h" - #include "Timer Control.h" - #include "Render Fun.h" - #include "Render Dirty.h" - #include "mousesystem.h" - #include "interface.h" - #include "sysutil.h" - #include "FileMan.h" - #include "points.h" - #include "Random.h" - #include "ai.h" - #include "Interactive Tiles.h" - #include "soldier ani.h" - #include "english.h" - #include "overhead.h" - #include "opplist.h" - #include "Sound Control.h" - #include "Font Control.h" - #include "lighting.h" - #include "pathai.h" - #include "screenids.h" - #include "interface cursors.h" - #include "weapons.h" - #include "rotting corpses.h" - #include "lighting.h" - #include "Handle UI Plan.h" - #include "structure.h" - #include "interface panels.h" - #include "message.h" - #include "items.h" - #include "Soldier Profile.h" - #include "fov.h" - #include "Soldier macros.h" - #include "EditorMercs.h" - #include "soldier tile.h" - #ifdef NETWORKED - #include "Networking.h" - #include "NetworkEvent.h" - #endif - #include "structure wrap.h" - #include "tile animation.h" - #include "Strategic Merc Handler.h" - #include "strategic turns.h" - #include "Squads.h" - #include "Morale.h" - #include "Campaign.h" - #include "music control.h" - #include "faces.h" - #include "dialogue control.h" - #include "Queen Command.h" - #include "Quests.h" - #include "NPC.h" - #include "strategicmap.h" - #include "soldier profile.h" - #include "soldier functions.h" - #include "auto bandage.h" - #include "Game Event Hook.h" - #include "Explosion Control.h" - #include "SkillCheck.h" - #include "World Items.h" - #include "smell.h" - #include "Player Command.h" - #include "GameSettings.h" - #include "messageboxscreen.h" - #include "Game Clock.h" - #include "Strategic Town Loyalty.h" - #include "Strategic Mines.h" - #include "interface items.h" - #include "text.h" - #include "keys.h" - #include "Boxing.h" - #include "Town Militia.h" - #include "meanwhile.h" - #include "Map Screen Helicopter.h" - #include "interface control.h" - #include "exit grids.h" - #include "fade screen.h" - #include "Game Init.h" - #include "jascreens.h" - #include "strategic.h" - #include "arms dealer init.h" +#include +#include +#include "wcheck.h" +#include "stdlib.h" +#include "debug.h" +#include "math.h" +#include "worlddef.h" +#include "worldman.h" +#include "renderworld.h" +#include "Assignments.h" +#include "Soldier Control.h" +#include "Animation Control.h" +#include "Animation Data.h" +#include "Isometric Utils.h" +#include "Event Pump.h" +#include "Timer Control.h" +#include "Render Fun.h" +#include "Render Dirty.h" +#include "mousesystem.h" +#include "interface.h" +#include "sysutil.h" +#include "FileMan.h" +#include "points.h" +#include "Random.h" +#include "ai.h" +#include "Interactive Tiles.h" +#include "soldier ani.h" +#include "english.h" +#include "overhead.h" +#include "opplist.h" +#include "Sound Control.h" +#include "Font Control.h" +#include "lighting.h" +#include "pathai.h" +#include "screenids.h" +#include "interface cursors.h" +#include "weapons.h" +#include "rotting corpses.h" +#include "lighting.h" +#include "Handle UI Plan.h" +#include "structure.h" +#include "interface panels.h" +#include "message.h" +#include "items.h" +#include "Soldier Profile.h" +#include "fov.h" +#include "Soldier macros.h" +#include "EditorMercs.h" +#include "soldier tile.h" +#ifdef NETWORKED +#include "Networking.h" +#include "NetworkEvent.h" #endif +#include "structure wrap.h" +#include "tile animation.h" +#include "Strategic Merc Handler.h" +#include "strategic turns.h" +#include "Squads.h" +#include "Morale.h" +#include "Campaign.h" +#include "music control.h" +#include "faces.h" +#include "dialogue control.h" +#include "Queen Command.h" +#include "Quests.h" +#include "NPC.h" +#include "strategicmap.h" +#include "soldier profile.h" +#include "soldier functions.h" +#include "auto bandage.h" +#include "Game Event Hook.h" +#include "Explosion Control.h" +#include "SkillCheck.h" +#include "World Items.h" +#include "smell.h" +#include "Player Command.h" +#include "GameSettings.h" +#include "messageboxscreen.h" +#include "Game Clock.h" +#include "Strategic Town Loyalty.h" +#include "Strategic Mines.h" +#include "interface items.h" +#include "text.h" +#include "keys.h" +#include "Boxing.h" +#include "Town Militia.h" +#include "meanwhile.h" +#include "Map Screen Helicopter.h" +#include "interface control.h" +#include "exit grids.h" +#include "fade screen.h" +#include "Game Init.h" +#include "jascreens.h" +#include "strategic.h" +#include "arms dealer init.h" +#include "interface utils.h" +#include "Air Raid.h" +#include "civ quotes.h" +#include "drugs and alcohol.h" +#include "history.h" +#include "los.h" +#include "interface dialogue.h" +#include "Strategic AI.h" +#include "end game.h" +#include "Strategic Status.h" +#include "PreBattle Interface.h" +#include "Militia Control.h" +#endif + +extern void HandleBestSightingPositionInRealtime(); extern UINT8 gubAICounter; @@ -183,7 +197,7 @@ CHAR8 gzLevelFilenames[ ][ 50 ] = "LindaRTCave2.dat" }; - + INT8 ubLevelMoveLink[ 10 ] = { @@ -671,14 +685,14 @@ BOOLEAN InitOverhead( ) { gTacticalStatus.sPanicTriggerGridNo[ cnt ] = NOWHERE; } -/* for ( cnt = 0; cnt < NUM_TOPTIONS; cnt++ ) + /* for ( cnt = 0; cnt < NUM_TOPTIONS; cnt++ ) { - gGameSettings.fOptions[ cnt ] = 1; + gGameSettings.fOptions[ cnt ] = 1; } gGameSettings.fOptions[ TOPTION_RTCONFIRM ] = 0; gGameSettings.fOptions[ TOPTION_HIDE_BULLETS ] = 0; -*/ + */ gTacticalStatus.bRealtimeSpeed = MAX_REALTIME_SPEED_VAL / 2; gfInAirRaid = FALSE; @@ -691,7 +705,7 @@ BOOLEAN InitOverhead( ) InitCivQuoteSystem( ); - ZeroAnimSurfaceCounts( ); + ZeroAnimSurfaceCounts( ); return( TRUE ); } @@ -796,7 +810,7 @@ BOOLEAN NextAIToHandle( UINT32 uiCurrAISlot ) return( FALSE ); } } - + // reset awayAISlotToHandle, but DON'T loop again, away slots not that important guiAIAwaySlotToHandle = RESET_HANDLE_OF_OFF_MAP_MERCS; } @@ -848,18 +862,18 @@ BOOLEAN ExecuteOverhead( ) FLOAT dXPos , dYPos; FLOAT dAngle; BOOLEAN fKeepMoving; - INT8 bShadeLevel; + INT8 bShadeLevel; BOOLEAN fNoAPsForPendingAction; INT16 sGridNo; STRUCTURE *pStructure; BOOLEAN fHandleAI = FALSE; - + // Diagnostic Stuff static INT32 iTimerTest = 0; static INT32 iTimerVal = 0; - + gfMovingAnimation = FALSE; if(GetSoldier(&pSoldier, gusSelectedSoldier)) @@ -888,7 +902,7 @@ BOOLEAN ExecuteOverhead( ) // BOMBS!!! HandleExplosionQueue(); - HandleCreatureTenseQuote( ); + HandleCreatureTenseQuote( ); CheckHostileOrSayQuoteList(); @@ -906,7 +920,7 @@ BOOLEAN ExecuteOverhead( ) { if ((iTimerVal - giRTAILastUpdateTime ) > RT_DELAY_BETWEEN_AI_HANDLING) { - giRTAILastUpdateTime = iTimerVal; + giRTAILastUpdateTime = iTimerVal; // figure out which AI guy to handle this time around, // starting with the slot AFTER the current AI guy fHandleAI = NextAIToHandle( guiAISlotToHandle ); @@ -977,7 +991,7 @@ BOOLEAN ExecuteOverhead( ) { pSoldier->fBeginFade = FALSE; pSoldier->bVisible = -1; - + // Set levelnode shade level.... if ( pSoldier->pLevelNode ) { @@ -1110,9 +1124,9 @@ BOOLEAN ExecuteOverhead( ) // Check for TIMING delay here only if in Realtime if( gTacticalStatus.uiFlags & REALTIME) if ( pSoldier->fIsSoldierMoving ) - CheckForSlowSoldier( pSoldier ); + CheckForSlowSoldier( pSoldier ); #endif - + // Check if we need to look for items if ( pSoldier->uiStatusFlags & SOLDIER_LOOKFOR_ITEMS ) { @@ -1180,7 +1194,7 @@ BOOLEAN ExecuteOverhead( ) else { //OK, we're at the MIDDLE of a new tile... - HandleAtNewGridNo( pSoldier, &fKeepMoving ); + HandleAtNewGridNo( pSoldier, &fKeepMoving ); } if ( gTacticalStatus.bBoxingState != NOT_BOXING && (gTacticalStatus.bBoxingState == BOXING_WAITING_FOR_PLAYER || gTacticalStatus.bBoxingState == PRE_BOXING || gTacticalStatus.bBoxingState == BOXING) ) @@ -1191,289 +1205,289 @@ BOOLEAN ExecuteOverhead( ) // Are we at our final destination? if ( pSoldier->sFinalDestination == pSoldier->sGridNo ) { - // Cancel path.... - pSoldier->usPathIndex = pSoldier->usPathDataSize = 0; + // Cancel path.... + pSoldier->usPathIndex = pSoldier->usPathDataSize = 0; - // Cancel reverse - pSoldier->bReverse = FALSE; + // Cancel reverse + pSoldier->bReverse = FALSE; - // OK, if we are the selected soldier, refresh some UI stuff - if ( pSoldier->ubID == (UINT8)gusSelectedSoldier ) - { - gfUIRefreshArrows = TRUE; - } + // OK, if we are the selected soldier, refresh some UI stuff + if ( pSoldier->ubID == (UINT8)gusSelectedSoldier ) + { + gfUIRefreshArrows = TRUE; + } - // ATE: Play landing sound..... - if ( pSoldier->usAnimState == JUMP_OVER_BLOCKING_PERSON ) - { - PlaySoldierFootstepSound( pSoldier ); - } + // ATE: Play landing sound..... + if ( pSoldier->usAnimState == JUMP_OVER_BLOCKING_PERSON ) + { + PlaySoldierFootstepSound( pSoldier ); + } - // If we are a robot, play stop sound... - if ( pSoldier->uiStatusFlags & SOLDIER_ROBOT ) - { - PlaySoldierJA2Sample( pSoldier->ubID, ROBOT_STOP, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - } + // If we are a robot, play stop sound... + if ( pSoldier->uiStatusFlags & SOLDIER_ROBOT ) + { + PlaySoldierJA2Sample( pSoldier->ubID, ROBOT_STOP, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + } - // Update to middle if we're on destination - dXPos = pSoldier->sDestXPos; - dYPos = pSoldier->sDestYPos; - EVENT_SetSoldierPosition( pSoldier, dXPos, dYPos ); + // Update to middle if we're on destination + dXPos = pSoldier->sDestXPos; + dYPos = pSoldier->sDestYPos; + EVENT_SetSoldierPosition( pSoldier, dXPos, dYPos ); #ifdef NETWORKED - // DEF: Test Code - StopSoldierMovementTime(pSoldier); + // DEF: Test Code + StopSoldierMovementTime(pSoldier); #endif - // Handle New sight - //HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO ); + // Handle New sight + //HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO ); - // CHECK IF WE HAVE A PENDING ANIMATION - if ( pSoldier->usPendingAnimation != NO_PENDING_ANIMATION ) + // CHECK IF WE HAVE A PENDING ANIMATION + if ( pSoldier->usPendingAnimation != NO_PENDING_ANIMATION ) + { + ChangeSoldierState( pSoldier, pSoldier->usPendingAnimation, 0 , FALSE ); + pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; + + if ( pSoldier->ubPendingDirection != NO_PENDING_DIRECTION ) { - ChangeSoldierState( pSoldier, pSoldier->usPendingAnimation, 0 , FALSE ); - pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; - - if ( pSoldier->ubPendingDirection != NO_PENDING_DIRECTION ) - { - EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->ubPendingDirection ); - pSoldier->ubPendingDirection = NO_PENDING_DIRECTION; - } - + EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->ubPendingDirection ); + pSoldier->ubPendingDirection = NO_PENDING_DIRECTION; } - // CHECK IF WE HAVE A PENDING ACTION - if ( pSoldier->ubWaitActionToDo ) + } + + // CHECK IF WE HAVE A PENDING ACTION + if ( pSoldier->ubWaitActionToDo ) + { + if ( pSoldier->ubWaitActionToDo == 2 ) { - if ( pSoldier->ubWaitActionToDo == 2 ) + pSoldier->ubWaitActionToDo = 1; + + if ( gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALKOFF_SCREEN ) { - pSoldier->ubWaitActionToDo = 1; - - if ( gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALKOFF_SCREEN ) - { - // ATE wanted this line here... - pSoldier->usPathIndex--; - AdjustSoldierPathToGoOffEdge( pSoldier, pSoldier->sGridNo, (UINT8)pSoldier->uiPendingActionData1 ); - continue; - } + // ATE wanted this line here... + pSoldier->usPathIndex--; + AdjustSoldierPathToGoOffEdge( pSoldier, pSoldier->sGridNo, (UINT8)pSoldier->uiPendingActionData1 ); + continue; } - else if ( pSoldier->ubWaitActionToDo == 1 ) - { - pSoldier->ubWaitActionToDo = 0; - - gbNumMercsUntilWaitingOver--; - - SoldierGotoStationaryStance( pSoldier ); - - // If we are at an exit-grid, make disappear..... - if ( gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALK_TO_GRIDNO ) - { - // Remove! - RemoveSoldierFromTacticalSector( pSoldier, TRUE ); - } - } - } - else if ( pSoldier->ubPendingAction != NO_PENDING_ACTION ) + } + else if ( pSoldier->ubWaitActionToDo == 1 ) { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("We are inside the IF PENDING Animation with soldier #%d", pSoldier->ubID) ); + pSoldier->ubWaitActionToDo = 0; - if ( pSoldier->ubPendingAction == MERC_OPENDOOR || pSoldier->ubPendingAction == MERC_OPENSTRUCT ) + gbNumMercsUntilWaitingOver--; + + SoldierGotoStationaryStance( pSoldier ); + + // If we are at an exit-grid, make disappear..... + if ( gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALK_TO_GRIDNO ) { - sGridNo = pSoldier->sPendingActionData2; - //usStructureID = (UINT16)pSoldier->uiPendingActionData1; - //pStructure = FindStructureByID( sGridNo, usStructureID ); + // Remove! + RemoveSoldierFromTacticalSector( pSoldier, TRUE ); + } + } + } + else if ( pSoldier->ubPendingAction != NO_PENDING_ACTION ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("We are inside the IF PENDING Animation with soldier #%d", pSoldier->ubID) ); - // LOOK FOR STRUCT OPENABLE - pStructure = FindStructure( sGridNo, STRUCTURE_OPENABLE ); + if ( pSoldier->ubPendingAction == MERC_OPENDOOR || pSoldier->ubPendingAction == MERC_OPENSTRUCT ) + { + sGridNo = pSoldier->sPendingActionData2; + //usStructureID = (UINT16)pSoldier->uiPendingActionData1; + //pStructure = FindStructureByID( sGridNo, usStructureID ); - if ( pStructure == NULL ) - { + // LOOK FOR STRUCT OPENABLE + pStructure = FindStructure( sGridNo, STRUCTURE_OPENABLE ); + + if ( pStructure == NULL ) + { #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Told to open struct at %d and none was found", sGridNo ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Told to open struct at %d and none was found", sGridNo ); #endif - fKeepMoving = FALSE; + fKeepMoving = FALSE; + } + else + { + CalcInteractiveObjectAPs( sGridNo, pStructure, &sAPCost, &sBPCost ); + + if ( EnoughPoints( pSoldier, sAPCost, sBPCost , TRUE ) ) + { + InteractWithInteractiveObject( pSoldier, pStructure, pSoldier->bPendingActionData3 ); } else { - CalcInteractiveObjectAPs( sGridNo, pStructure, &sAPCost, &sBPCost ); - - if ( EnoughPoints( pSoldier, sAPCost, sBPCost , TRUE ) ) - { - InteractWithInteractiveObject( pSoldier, pStructure, pSoldier->bPendingActionData3 ); - } - else - { - fNoAPsForPendingAction = TRUE; - } + fNoAPsForPendingAction = TRUE; } } - if ( pSoldier->ubPendingAction == MERC_PICKUPITEM ) + } + if ( pSoldier->ubPendingAction == MERC_PICKUPITEM ) + { + sGridNo = pSoldier->sPendingActionData2; + + if ( sGridNo == pSoldier->sGridNo ) { - sGridNo = pSoldier->sPendingActionData2; - - if ( sGridNo == pSoldier->sGridNo ) + // OK, now, if in realtime + if ( !( gTacticalStatus.uiFlags & INCOMBAT ) ) { - // OK, now, if in realtime - if ( !( gTacticalStatus.uiFlags & INCOMBAT ) ) + // If the two gridnos are not the same, check to see if we can + // now go into it + if ( sGridNo != (INT16)pSoldier->uiPendingActionData4 ) { - // If the two gridnos are not the same, check to see if we can - // now go into it - if ( sGridNo != (INT16)pSoldier->uiPendingActionData4 ) + if ( NewOKDestination( pSoldier, (INT16)pSoldier->uiPendingActionData4, TRUE, pSoldier->bLevel ) ) { - if ( NewOKDestination( pSoldier, (INT16)pSoldier->uiPendingActionData4, TRUE, pSoldier->bLevel ) ) - { - // GOTO NEW TILE! - SoldierPickupItem( pSoldier, pSoldier->uiPendingActionData1, (INT16)pSoldier->uiPendingActionData4, pSoldier->bPendingActionData3 ); - continue; - } + // GOTO NEW TILE! + SoldierPickupItem( pSoldier, pSoldier->uiPendingActionData1, (INT16)pSoldier->uiPendingActionData4, pSoldier->bPendingActionData3 ); + continue; } } + } - // OK MORON, DOUBLE CHECK THAT THE ITEM EXISTS HERE... - if ( pSoldier->uiPendingActionData1 != ITEM_PICKUP_ACTION_ALL ) - { - //if ( ItemExistsAtLocation( (INT16)( pSoldier->uiPendingActionData4 ), pSoldier->uiPendingActionData1, pSoldier->bLevel ) ) - { - PickPickupAnimation( pSoldier, pSoldier->uiPendingActionData1, (INT16)( pSoldier->uiPendingActionData4 ), pSoldier->bPendingActionData3 ); - } - } - else + // OK MORON, DOUBLE CHECK THAT THE ITEM EXISTS HERE... + if ( pSoldier->uiPendingActionData1 != ITEM_PICKUP_ACTION_ALL ) + { + //if ( ItemExistsAtLocation( (INT16)( pSoldier->uiPendingActionData4 ), pSoldier->uiPendingActionData1, pSoldier->bLevel ) ) { PickPickupAnimation( pSoldier, pSoldier->uiPendingActionData1, (INT16)( pSoldier->uiPendingActionData4 ), pSoldier->bPendingActionData3 ); } } - else - { - SoldierGotoStationaryStance( pSoldier ); - } - } - else if ( pSoldier->ubPendingAction == MERC_PUNCH ) - { - // for the benefit of the AI - pSoldier->bAction = AI_ACTION_KNIFE_STAB; - - EVENT_SoldierBeginPunchAttack( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - } - else if ( pSoldier->ubPendingAction == MERC_TALK ) - { - PlayerSoldierStartTalking( pSoldier, (UINT8)pSoldier->uiPendingActionData1, TRUE ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - } - else if ( pSoldier->ubPendingAction == MERC_DROPBOMB ) - { - EVENT_SoldierBeginDropBomb( pSoldier ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - } - else if ( pSoldier->ubPendingAction == MERC_STEAL ) - { - //pSoldier->bDesiredDirection = pSoldier->bPendingActionData3; - EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bPendingActionData3 ); - - EVENT_InitNewSoldierAnim( pSoldier, STEAL_ITEM, 0 , FALSE ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - } - else if ( pSoldier->ubPendingAction == MERC_KNIFEATTACK) - { - // for the benefit of the AI - pSoldier->bAction = AI_ACTION_KNIFE_STAB; - - EVENT_SoldierBeginBladeAttack( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - } - else if ( pSoldier->ubPendingAction == MERC_GIVEAID ) - { - EVENT_SoldierBeginFirstAid( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - } - else if ( pSoldier->ubPendingAction == MERC_REPAIR ) - { - EVENT_SoldierBeginRepair( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - } - else if ( pSoldier->ubPendingAction == MERC_FUEL_VEHICLE ) - { - EVENT_SoldierBeginRefuel( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - } - else if ( pSoldier->ubPendingAction == MERC_RELOADROBOT ) - { - EVENT_SoldierBeginReloadRobot( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3, (INT8)pSoldier->uiPendingActionData1 ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - } - else if ( pSoldier->ubPendingAction == MERC_TAKEBLOOD ) - { - EVENT_SoldierBeginTakeBlood( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - } - else if ( pSoldier->ubPendingAction == MERC_ATTACH_CAN ) - { - EVENT_SoldierBeginAttachCan( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - } - else if ( pSoldier->ubPendingAction == MERC_ENTER_VEHICLE ) - { - EVENT_SoldierEnterVehicle( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - continue; - } - else if ( pSoldier->ubPendingAction == MERC_CUTFFENCE ) - { - EVENT_SoldierBeginCutFence( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - } - else if ( pSoldier->ubPendingAction == MERC_GIVEITEM ) - { - EVENT_SoldierBeginGiveItem( pSoldier ); - pSoldier->ubPendingAction = NO_PENDING_ACTION; - } - - if ( fNoAPsForPendingAction ) - { - // Change status of guy to waiting - HaltMoveForSoldierOutOfPoints( pSoldier ); - fKeepMoving = FALSE; - pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; - pSoldier->ubPendingDirection = NO_PENDING_DIRECTION; - } - - } - else - { - // OK, ADJUST TO STANDING, WE ARE DONE - // DO NOTHING IF WE ARE UNCONSCIOUS - if ( pSoldier->bLife >= OKLIFE ) - { - if ( pSoldier->ubBodyType == CROW ) - { - // If we are flying, don't stop! - if ( pSoldier->sHeightAdjustment == 0 ) - { - SoldierGotoStationaryStance( pSoldier ); - } - } else { - UnSetUIBusy( pSoldier->ubID ); + PickPickupAnimation( pSoldier, pSoldier->uiPendingActionData1, (INT16)( pSoldier->uiPendingActionData4 ), pSoldier->bPendingActionData3 ); + } + } + else + { + SoldierGotoStationaryStance( pSoldier ); + } + } + else if ( pSoldier->ubPendingAction == MERC_PUNCH ) + { + // for the benefit of the AI + pSoldier->bAction = AI_ACTION_KNIFE_STAB; + EVENT_SoldierBeginPunchAttack( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + } + else if ( pSoldier->ubPendingAction == MERC_TALK ) + { + PlayerSoldierStartTalking( pSoldier, (UINT8)pSoldier->uiPendingActionData1, TRUE ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + } + else if ( pSoldier->ubPendingAction == MERC_DROPBOMB ) + { + EVENT_SoldierBeginDropBomb( pSoldier ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + } + else if ( pSoldier->ubPendingAction == MERC_STEAL ) + { + //pSoldier->bDesiredDirection = pSoldier->bPendingActionData3; + EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bPendingActionData3 ); + + EVENT_InitNewSoldierAnim( pSoldier, STEAL_ITEM, 0 , FALSE ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + } + else if ( pSoldier->ubPendingAction == MERC_KNIFEATTACK) + { + // for the benefit of the AI + pSoldier->bAction = AI_ACTION_KNIFE_STAB; + + EVENT_SoldierBeginBladeAttack( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + } + else if ( pSoldier->ubPendingAction == MERC_GIVEAID ) + { + EVENT_SoldierBeginFirstAid( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + } + else if ( pSoldier->ubPendingAction == MERC_REPAIR ) + { + EVENT_SoldierBeginRepair( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + } + else if ( pSoldier->ubPendingAction == MERC_FUEL_VEHICLE ) + { + EVENT_SoldierBeginRefuel( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + } + else if ( pSoldier->ubPendingAction == MERC_RELOADROBOT ) + { + EVENT_SoldierBeginReloadRobot( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3, (INT8)pSoldier->uiPendingActionData1 ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + } + else if ( pSoldier->ubPendingAction == MERC_TAKEBLOOD ) + { + EVENT_SoldierBeginTakeBlood( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + } + else if ( pSoldier->ubPendingAction == MERC_ATTACH_CAN ) + { + EVENT_SoldierBeginAttachCan( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + } + else if ( pSoldier->ubPendingAction == MERC_ENTER_VEHICLE ) + { + EVENT_SoldierEnterVehicle( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + continue; + } + else if ( pSoldier->ubPendingAction == MERC_CUTFFENCE ) + { + EVENT_SoldierBeginCutFence( pSoldier, pSoldier->sPendingActionData2, pSoldier->bPendingActionData3 ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + } + else if ( pSoldier->ubPendingAction == MERC_GIVEITEM ) + { + EVENT_SoldierBeginGiveItem( pSoldier ); + pSoldier->ubPendingAction = NO_PENDING_ACTION; + } + + if ( fNoAPsForPendingAction ) + { + // Change status of guy to waiting + HaltMoveForSoldierOutOfPoints( pSoldier ); + fKeepMoving = FALSE; + pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; + pSoldier->ubPendingDirection = NO_PENDING_DIRECTION; + } + + } + else + { + // OK, ADJUST TO STANDING, WE ARE DONE + // DO NOTHING IF WE ARE UNCONSCIOUS + if ( pSoldier->bLife >= OKLIFE ) + { + if ( pSoldier->ubBodyType == CROW ) + { + // If we are flying, don't stop! + if ( pSoldier->sHeightAdjustment == 0 ) + { SoldierGotoStationaryStance( pSoldier ); } } - } + else + { + UnSetUIBusy( pSoldier->ubID ); - // RESET MOVE FAST FLAG - if ( (pSoldier->ubProfile == NO_PROFILE) ) - { - pSoldier->fUIMovementFast = FALSE; + SoldierGotoStationaryStance( pSoldier ); + } } + } - // if AI moving and waiting to process something at end of - // move, have them handled the very next frame - if (pSoldier->ubQuoteActionID == QUOTE_ACTION_ID_CHECKFORDEST) - { - pSoldier->fAIFlags |= AI_HANDLE_EVERY_FRAME; - } + // RESET MOVE FAST FLAG + if ( (pSoldier->ubProfile == NO_PROFILE) ) + { + pSoldier->fUIMovementFast = FALSE; + } - fKeepMoving = FALSE; + // if AI moving and waiting to process something at end of + // move, have them handled the very next frame + if (pSoldier->ubQuoteActionID == QUOTE_ACTION_ID_CHECKFORDEST) + { + pSoldier->fAIFlags |= AI_HANDLE_EVERY_FRAME; + } + + fKeepMoving = FALSE; } else if ( !pSoldier->fNoAPToFinishMove ) { @@ -1491,9 +1505,9 @@ BOOLEAN ExecuteOverhead( ) // ATE: Pop up warning.... if ( pSoldier->usPathDataSize != MAX_PATH_LIST_SIZE ) { - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Path for %s ( %d ) did not make merc get to dest .", pSoldier->name, pSoldier->ubID ); - #endif +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Path for %s ( %d ) did not make merc get to dest .", pSoldier->name, pSoldier->ubID ); +#endif } // In case this is an AI person with the path-stored flag set, @@ -1509,22 +1523,40 @@ BOOLEAN ExecuteOverhead( ) { // ATE: Added this to fcalilitate the fact // that our final dest may now have people on it.... - if ( FindBestPath( pSoldier, pSoldier->sFinalDestination, pSoldier->bLevel, pSoldier->usUIMovementMode, NO_COPYROUTE, PATH_THROUGH_PEOPLE ) != 0 ) + // 0verhaul: But what if this is turn-based? The soldier may be waiting forever for + // the other one to leave the position, but since it's turn-based he never will. + // Is that an issue here? + // Yes, I think it is. I found a situation where the soldier's path led through another + // soldier. The other soldier wasn't even at the destination but his path invariably + // led through that soldier. Since this was set up to allow that, he ended up deadlocked + // in "take cover" mode waiting for the soldier right next to him to leave. + // So in turn-based mode, we will just allow the soldier to re-think his next move. + if ( gTacticalStatus.uiFlags & TURNBASED && gTacticalStatus.uiFlags & INCOMBAT) { - INT16 sNewGridNo; - - sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( (UINT8)guiPathingData[ 0 ] ) ); - - SetDelayedTileWaiting( pSoldier, sNewGridNo, 1 ); - } - - // We have not made it to our dest... set flag that we are waiting.... - if ( !EVENT_InternalGetNewSoldierPath( pSoldier, pSoldier->sFinalDestination, pSoldier->usUIMovementMode, 2, FALSE ) ) - { - // ATE: To do here.... we could not get path, so we have to stop - SoldierGotoStationaryStance( pSoldier ); + ActionDone( pSoldier); continue; } + else + { + if ( FindBestPath( pSoldier, pSoldier->sFinalDestination, pSoldier->bLevel, pSoldier->usUIMovementMode, NO_COPYROUTE, PATH_THROUGH_PEOPLE ) != 0 ) + { + INT16 sNewGridNo; + + sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( (UINT8)guiPathingData[ 0 ] ) ); + + SetDelayedTileWaiting( pSoldier, sNewGridNo, 1 ); + } + + // We have not made it to our dest... set flag that we are waiting.... + if ( !EVENT_InternalGetNewSoldierPath( pSoldier, pSoldier->sFinalDestination, pSoldier->usUIMovementMode, 2, FALSE ) ) + { + // ATE: To do here.... we could not get path, so we have to stop + // 0verhaul: May also need to clear the action type so that the soldier will know + // to re-think another move instead of waiting for nothing to finish happening. + SoldierGotoStationaryStance( pSoldier ); + continue; + } + } } } else @@ -1535,7 +1567,7 @@ BOOLEAN ExecuteOverhead( ) // OK, now we want to see if we can continue to another tile... if ( !HandleGotoNewGridNo( pSoldier, &fKeepMoving, FALSE, pSoldier->usAnimState ) ) { - continue; + continue; } } else @@ -1562,11 +1594,11 @@ BOOLEAN ExecuteOverhead( ) if ( !pSoldier->fPausedMove && fKeepMoving ) { // Determine deltas - // dDeltaX = pSoldier->sDestXPos - pSoldier->dXPos; + // dDeltaX = pSoldier->sDestXPos - pSoldier->dXPos; //dDeltaY = pSoldier->sDestYPos - pSoldier->dYPos; // Determine angle - // dAngle = (FLOAT)atan2( dDeltaX, dDeltaY ); + // dAngle = (FLOAT)atan2( dDeltaX, dDeltaY ); dAngle = gdRadiansForAngle[ pSoldier->bMovementDirection ]; @@ -1575,7 +1607,7 @@ BOOLEAN ExecuteOverhead( ) if ( pSoldier->usAnimState == WALKING ) { MoveMerc( pSoldier, gubAnimWalkSpeeds[ pSoldier->ubBodyType ].dMovementChange, dAngle, TRUE ); - + } else { @@ -1588,11 +1620,11 @@ BOOLEAN ExecuteOverhead( ) // Check for direction change if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_TURNING ) { - TurnSoldier( pSoldier ); + TurnSoldier( pSoldier ); } } - - + + #ifdef NETWORKED if(!pSoldier->fNoAPToFinishMove ) pSoldier->usLastUpdateTime = GetJA2Clock(); @@ -1676,55 +1708,55 @@ BOOLEAN ExecuteOverhead( ) } } - if ( gbNumMercsUntilWaitingOver == 0 ) + if ( gbNumMercsUntilWaitingOver == 0 ) + { + // ATE: Unset flag to ignore sight... + gTacticalStatus.uiFlags &= ( ~DISALLOW_SIGHT ); + + + // OK cheif, do something here.... + switch( gubWaitingForAllMercsToExitCode ) { - // ATE: Unset flag to ignore sight... - gTacticalStatus.uiFlags &= ( ~DISALLOW_SIGHT ); + case WAIT_FOR_MERCS_TO_WALKOFF_SCREEN: - - // OK cheif, do something here.... - switch( gubWaitingForAllMercsToExitCode ) + if ( ( gTacticalStatus.ubCurrentTeam == gbPlayerNum ) ) { - case WAIT_FOR_MERCS_TO_WALKOFF_SCREEN: - - if ( ( gTacticalStatus.ubCurrentTeam == gbPlayerNum ) ) - { - guiPendingOverrideEvent = LU_ENDUILOCK; - HandleTacticalUI( ); - } - AllMercsHaveWalkedOffSector( ); - break; - - case WAIT_FOR_MERCS_TO_WALKON_SCREEN: - - // OK, unset UI - if ( ( gTacticalStatus.ubCurrentTeam == gbPlayerNum ) ) - { - guiPendingOverrideEvent = LU_ENDUILOCK; - HandleTacticalUI( ); - } - break; - - case WAIT_FOR_MERCS_TO_WALK_TO_GRIDNO: - - // OK, unset UI - if ( ( gTacticalStatus.ubCurrentTeam == gbPlayerNum ) ) - { - guiPendingOverrideEvent = LU_ENDUILOCK; - HandleTacticalUI( ); - } - AllMercsWalkedToExitGrid( ); - break; - + guiPendingOverrideEvent = LU_ENDUILOCK; + HandleTacticalUI( ); } + AllMercsHaveWalkedOffSector( ); + break; - // ATE; Turn off tactical status flag... - gTacticalStatus.uiFlags &= ( ~IGNORE_ALL_OBSTACLES ); + case WAIT_FOR_MERCS_TO_WALKON_SCREEN: + + // OK, unset UI + if ( ( gTacticalStatus.ubCurrentTeam == gbPlayerNum ) ) + { + guiPendingOverrideEvent = LU_ENDUILOCK; + HandleTacticalUI( ); + } + break; + + case WAIT_FOR_MERCS_TO_WALK_TO_GRIDNO: + + // OK, unset UI + if ( ( gTacticalStatus.ubCurrentTeam == gbPlayerNum ) ) + { + guiPendingOverrideEvent = LU_ENDUILOCK; + HandleTacticalUI( ); + } + AllMercsWalkedToExitGrid( ); + break; - gubWaitingForAllMercsToExitCode = 0; } + + // ATE; Turn off tactical status flag... + gTacticalStatus.uiFlags &= ( ~IGNORE_ALL_OBSTACLES ); + + gubWaitingForAllMercsToExitCode = 0; } - + } + // reset these AI-related global variables to 0 to ensure they don't interfere with the UI gubNPCAPBudget = 0; @@ -2094,7 +2126,7 @@ BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLE pExplosive = &( Explosive[ Item[ GetFirstExplosiveOfType(EXPLOSV_SMOKE) ].ubClassIndex ]); } } - + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Overhead pExplosive: %d", pExplosive->ubType ); if ( gpWorldLevelData[ pSoldier->sGridNo ].ubExtFlags[pSoldier->bLevel] & MAPELEMENT_EXT_TEARGAS ) { @@ -2103,7 +2135,7 @@ BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLE pExplosive = &( Explosive[ Item[ GetFirstExplosiveOfType(EXPLOSV_TEARGAS) ].ubClassIndex ]); } } - + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Overhead pExplosive: %d", pExplosive->ubType ); if ( gpWorldLevelData[ pSoldier->sGridNo ].ubExtFlags[pSoldier->bLevel] & MAPELEMENT_EXT_MUSTARDGAS ) { @@ -2113,7 +2145,7 @@ BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLE } } } - + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Overhead pExplosive: %d", pExplosive->ubType ); if ( gpWorldLevelData[ pSoldier->sGridNo ].ubExtFlags[pSoldier->bLevel] & MAPELEMENT_EXT_CREATUREGAS ) { @@ -2122,7 +2154,7 @@ BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLE pExplosive = &(Explosive[ Item[ GetFirstExplosiveOfType(EXPLOSV_CREATUREGAS) ].ubClassIndex ]); } } - + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Overhead pExplosive: %d", pExplosive->ubType ); if ( gpWorldLevelData[ pSoldier->sGridNo ].ubExtFlags[pSoldier->bLevel] & MAPELEMENT_EXT_BURNABLEGAS ) { @@ -2131,7 +2163,7 @@ BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLE pExplosive = &(Explosive[ Item[ GetFirstExplosiveOfType(EXPLOSV_BURNABLEGAS) ].ubClassIndex ]); } } - + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Overhead pSoldier->fHitByGasFlags: %d", pSoldier->fHitByGasFlags ); //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Overhead pExplosive: %d", pExplosive->ubType ); @@ -2398,7 +2430,7 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving ) INT16 sMineGridNo; UINT8 ubVolume; - + // ATE; Handle bad guys, as they fade, to cancel it if // too long... // ONLY if fading IN! @@ -2418,10 +2450,10 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving ) pSoldier->ubFadeLevel = gpWorldLevelData[ pSoldier->sGridNo ].pLandHead->ubShadeLevel; } - // Set levelnode shade level.... - if ( pSoldier->pLevelNode ) + // Set levelnode shade level.... + if ( pSoldier->pLevelNode ) { - pSoldier->pLevelNode->ubShadeLevel = pSoldier->ubFadeLevel; + pSoldier->pLevelNode->ubShadeLevel = pSoldier->ubFadeLevel; } pSoldier->bVisible = -1; @@ -2562,27 +2594,27 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving ) // we find something by metal detector... we should definitely stop // but we won't place a locator or say anything - // IF not in combat, stop them all - if ( !( gTacticalStatus.uiFlags & INCOMBAT ) ) - { - INT32 cnt2; - SOLDIERTYPE *pSoldier2; + // IF not in combat, stop them all + if ( !( gTacticalStatus.uiFlags & INCOMBAT ) ) + { + INT32 cnt2; + SOLDIERTYPE *pSoldier2; - cnt2 = gTacticalStatus.Team[ gbPlayerNum ].bLastID; + cnt2 = gTacticalStatus.Team[ gbPlayerNum ].bLastID; - // look for all mercs on the same team, - for ( pSoldier2 = MercPtrs[ cnt2 ]; cnt2 >= gTacticalStatus.Team[ gbPlayerNum ].bFirstID; cnt2-- ,pSoldier2-- ) - { - if ( pSoldier2->bActive ) - { - EVENT_StopMerc( pSoldier2, pSoldier2->sGridNo, pSoldier2->bDirection ); - } - } - } - else - { - EVENT_StopMerc( pSoldier, pSoldier->sGridNo, pSoldier->bDirection ); - } + // look for all mercs on the same team, + for ( pSoldier2 = MercPtrs[ cnt2 ]; cnt2 >= gTacticalStatus.Team[ gbPlayerNum ].bFirstID; cnt2-- ,pSoldier2-- ) + { + if ( pSoldier2->bActive ) + { + EVENT_StopMerc( pSoldier2, pSoldier2->sGridNo, pSoldier2->bDirection ); + } + } + } + else + { + EVENT_StopMerc( pSoldier, pSoldier->sGridNo, pSoldier->bDirection ); + } (*pfKeepMoving) = FALSE; @@ -2624,24 +2656,24 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving ) { switch( pSoldier->ubProfile ) { - case SKYRIDER: - if (PythSpacesAway( pSoldier->sGridNo, 8842 ) < 11) - { - // Skyrider has arrived! - EVENT_StopMerc( pSoldier, pSoldier->sGridNo, pSoldier->bDirection ); - SetFactTrue( FACT_SKYRIDER_CLOSE_TO_CHOPPER ); - TriggerNPCRecord( SKYRIDER, 15 ); - SetUpHelicopterForPlayer( 13, MAP_ROW_B ); - } - break; + case SKYRIDER: + if (PythSpacesAway( pSoldier->sGridNo, 8842 ) < 11) + { + // Skyrider has arrived! + EVENT_StopMerc( pSoldier, pSoldier->sGridNo, pSoldier->bDirection ); + SetFactTrue( FACT_SKYRIDER_CLOSE_TO_CHOPPER ); + TriggerNPCRecord( SKYRIDER, 15 ); + SetUpHelicopterForPlayer( 13, MAP_ROW_B ); + } + break; - case MARY: - HandleMaryArrival( pSoldier ); - break; + case MARY: + HandleMaryArrival( pSoldier ); + break; - case JOHN: - HandleJohnArrival( pSoldier ); - break; + case JOHN: + HandleJohnArrival( pSoldier ); + break; } } else if ( pSoldier->ubProfile == MARIA && (pSoldier->sSectorX == 6 && pSoldier->sSectorY == MAP_ROW_C && pSoldier->bSectorZ == 0) && CheckFact( FACT_MARIA_ESCORTED_AT_LEATHER_SHOP, MARIA ) == TRUE ) @@ -2649,7 +2681,7 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving ) // check that Angel is there! if ( NPCInRoom( ANGEL, 2 ) ) // room 2 is leather shop { - // UnRecruitEPC( MARIA ); + // UnRecruitEPC( MARIA ); TriggerNPCRecord( ANGEL, 12 ); } } @@ -2662,7 +2694,7 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving ) TriggerNPCRecord( JOEY, 9 ); } } - + } // Drassen stuff for John & Mary else if ( gubQuest[ QUEST_ESCORT_TOURISTS ] == QUESTINPROGRESS && pSoldier->sSectorX == 13 && pSoldier->sSectorY == MAP_ROW_B && pSoldier->bSectorZ == 0 ) @@ -2682,31 +2714,31 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving ) { switch( pSoldier->ubProfile ) { - case JIM: - case JACK: - case OLAF: - case RAY: - case OLGA: - case TYRONE: + case JIM: + case JACK: + case OLAF: + case RAY: + case OLGA: + case TYRONE: + { + INT16 sDesiredMercDist; + + if ( ClosestPC( pSoldier, &sDesiredMercDist ) != NOWHERE ) { - INT16 sDesiredMercDist; - - if ( ClosestPC( pSoldier, &sDesiredMercDist ) != NOWHERE ) + if ( sDesiredMercDist <= NPC_TALK_RADIUS * 2 ) { - if ( sDesiredMercDist <= NPC_TALK_RADIUS * 2 ) - { - // stop - CancelAIAction( pSoldier, TRUE ); - // aaaaaaaaaaaaaaaaaaaaatttaaaack!!!! - AddToShouldBecomeHostileOrSayQuoteList( pSoldier->ubID ); - //MakeCivHostile( pSoldier, 2 ); - //TriggerNPCWithIHateYouQuote( pSoldier->ubProfile ); - } + // stop + CancelAIAction( pSoldier, TRUE ); + // aaaaaaaaaaaaaaaaaaaaatttaaaack!!!! + AddToShouldBecomeHostileOrSayQuoteList( pSoldier->ubID ); + //MakeCivHostile( pSoldier, 2 ); + //TriggerNPCWithIHateYouQuote( pSoldier->ubProfile ); } } - break; - default: - break; + } + break; + default: + break; } } return( TRUE ); @@ -2736,7 +2768,7 @@ void SelectNextAvailSoldier( SOLDIERTYPE *pSoldier ) if ( fSoldierFound ) { DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("SelectNextAvailSoldier: selectsoldier")); - SelectSoldier( (INT16)cnt, FALSE, FALSE ); + SelectSoldier( (INT16)cnt, FALSE, FALSE ); } else { @@ -2755,12 +2787,11 @@ void InternalSelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fF { SOLDIERTYPE *pSoldier, *pOldSoldier; - // ARM: can't call SelectSoldier() in mapscreen, that will initialize interface panels!!! - // ATE: Adjusted conditions a bit ( sometimes were not getting selected ) + // ATE: Adjusted conditions a bit ( sometimes were not getting selected ) if ( guiCurrentScreen == LAPTOP_SCREEN || guiCurrentScreen == MAP_SCREEN ) - { - return; + { + return; } if ( usSoldierID == NOBODY ) @@ -2776,8 +2807,8 @@ void InternalSelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fF } - // Get guy - pSoldier = MercPtrs[ usSoldierID ]; + // Get guy + pSoldier = MercPtrs[ usSoldierID ]; // If we are dead, ignore @@ -2790,10 +2821,10 @@ void InternalSelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fF if ( !OK_INTERRUPT_MERC( pSoldier ) ) { // OK, we want to display message that we can't.... - if ( fFromUI ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ MERC_IS_UNAVAILABLE_STR ], pSoldier->name ); - } + if ( fFromUI ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ MERC_IS_UNAVAILABLE_STR ], pSoldier->name ); + } return; } @@ -2823,7 +2854,7 @@ void InternalSelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fF if ( pOldSoldier->bLevel == 0 ) { //ConcealWalls((INT16)(pSoldier->dXPos/CELL_X_SIZE), (INT16)(pSoldier->dYPos/CELL_Y_SIZE), REVEAL_WALLS_RADIUS); - // ApplyTranslucencyToWalls((INT16)(pOldSoldier->dXPos/CELL_X_SIZE), (INT16)(pOldSoldier->dYPos/CELL_Y_SIZE)); + // ApplyTranslucencyToWalls((INT16)(pOldSoldier->dXPos/CELL_X_SIZE), (INT16)(pOldSoldier->dYPos/CELL_Y_SIZE)); //LightHideTrees((INT16)(pOldSoldier->dXPos/CELL_X_SIZE), (INT16)(pOldSoldier->dYPos/CELL_Y_SIZE)); } //DeleteSoldierLight( pOldSoldier ); @@ -2838,14 +2869,14 @@ void InternalSelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fF } gusSelectedSoldier = (UINT16)usSoldierID; - + // find which squad this guy is, then set selected squad to this guy SetCurrentSquad( pSoldier -> bAssignment, FALSE ); if ( pSoldier->bLevel == 0 ) { //RevealWalls((INT16)(pSoldier->dXPos/CELL_X_SIZE), (INT16)(pSoldier->dYPos/CELL_Y_SIZE), REVEAL_WALLS_RADIUS); - // CalcTranslucentWalls((INT16)(pSoldier->dXPos/CELL_X_SIZE), (INT16)(pSoldier->dYPos/CELL_Y_SIZE)); + // CalcTranslucentWalls((INT16)(pSoldier->dXPos/CELL_X_SIZE), (INT16)(pSoldier->dYPos/CELL_Y_SIZE)); //LightTranslucentTrees((INT16)(pSoldier->dXPos/CELL_X_SIZE), (INT16)(pSoldier->dYPos/CELL_Y_SIZE)); } @@ -2853,7 +2884,7 @@ void InternalSelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fF // Set interface to reflect new selection! SetCurrentTacticalPanelCurrentMerc( (UINT8)usSoldierID ); - + // PLay ATTN SOUND if ( fAcknowledge ) { @@ -2880,15 +2911,15 @@ void InternalSelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fF { switch ( gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait ) { - case PSYCHO: - if ( Random( 50 ) == 0 ) - { - TacticalCharacterDialogue( pSoldier, QUOTE_PERSONALITY_TRAIT ); - pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY; - } - break; - default: - break; + case PSYCHO: + if ( Random( 50 ) == 0 ) + { + TacticalCharacterDialogue( pSoldier, QUOTE_PERSONALITY_TRAIT ); + pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY; + } + break; + default: + break; } } @@ -2901,7 +2932,7 @@ void InternalSelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fF void SelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fForceReselect ) { - InternalSelectSoldier( usSoldierID, fAcknowledge, fForceReselect, FALSE ); + InternalSelectSoldier( usSoldierID, fAcknowledge, fForceReselect, FALSE ); } @@ -2916,7 +2947,7 @@ BOOLEAN ResetAllAnimationCache( ) if ( pSoldier != NULL ) { InitAnimationCache( (UINT16)cnt, &(pSoldier->AnimCache) ); - + } } @@ -2924,7 +2955,7 @@ BOOLEAN ResetAllAnimationCache( ) return( TRUE ); } - + void LocateSoldier( UINT16 usID, BOOLEAN fSetLocator) @@ -2933,7 +2964,7 @@ void LocateSoldier( UINT16 usID, BOOLEAN fSetLocator) INT16 sNewCenterWorldX, sNewCenterWorldY; //if (!bCenter && SoldierOnScreen(usID)) - //return; + //return; // do we need to move the screen? //ATE: Force this baby to locate if told to @@ -2941,7 +2972,7 @@ void LocateSoldier( UINT16 usID, BOOLEAN fSetLocator) { // Get pointer of soldier pSoldier = MercPtrs[ usID ]; - + // Center on guy sNewCenterWorldX = (INT16)pSoldier->dXPos; sNewCenterWorldY = (INT16)pSoldier->dYPos; @@ -2958,11 +2989,11 @@ void LocateSoldier( UINT16 usID, BOOLEAN fSetLocator) { if ( fSetLocator == SETLOCATOR || fSetLocator == 10 ) { - ShowRadioLocator((UINT8)usID, SHOW_LOCATOR_NORMAL ); + ShowRadioLocator((UINT8)usID, SHOW_LOCATOR_NORMAL ); } else { - ShowRadioLocator((UINT8)usID, SHOW_LOCATOR_FAST ); + ShowRadioLocator((UINT8)usID, SHOW_LOCATOR_FAST ); } } } @@ -2971,7 +3002,7 @@ void LocateSoldier( UINT16 usID, BOOLEAN fSetLocator) void InternalLocateGridNo( UINT16 sGridNo, BOOLEAN fForce ) { INT16 sNewCenterWorldX, sNewCenterWorldY; - + ConvertGridNoToCenterCellXY( sGridNo, &sNewCenterWorldX, &sNewCenterWorldY ); // FIRST CHECK IF WE ARE ON SCREEN @@ -2979,7 +3010,7 @@ void InternalLocateGridNo( UINT16 sGridNo, BOOLEAN fForce ) { return; } - + SetRenderCenter( sNewCenterWorldX, sNewCenterWorldY ); } @@ -3014,7 +3045,7 @@ void SlideTo(INT16 sGridno, UINT16 usSoldierID , UINT16 usReasonID, BOOLEAN fSet // Locate even if on screen if (fSetLocator) - ShowRadioLocator((UINT8) usSoldierID, SHOW_LOCATOR_NORMAL ); + ShowRadioLocator((UINT8) usSoldierID, SHOW_LOCATOR_NORMAL ); // FIRST CHECK IF WE ARE ON SCREEN if ( GridNoOnScreen( MercPtrs[ usSoldierID ]->sGridNo ) ) @@ -3072,7 +3103,7 @@ void RebuildAllSoldierShadeTables( ) void HandlePlayerTeamMemberDeath( SOLDIERTYPE *pSoldier ) { INT32 cnt; - INT32 iNewSelectedSoldier; + INT32 iNewSelectedSoldier; SOLDIERTYPE *pTeamSoldier; BOOLEAN fMissionFailed = TRUE; INT8 bBuddyIndex; @@ -3090,7 +3121,7 @@ void HandlePlayerTeamMemberDeath( SOLDIERTYPE *pSoldier ) { if ( pTeamSoldier->bLife >= OKLIFE && pTeamSoldier->bActive && pTeamSoldier->bInSector ) { - iNewSelectedSoldier = cnt; + iNewSelectedSoldier = cnt; fMissionFailed = FALSE; break; } @@ -3108,7 +3139,7 @@ void HandlePlayerTeamMemberDeath( SOLDIERTYPE *pSoldier ) } // see if this was the friend of a living merc - cnt = gTacticalStatus.Team[ pSoldier->bTeam ].bFirstID; + cnt = gTacticalStatus.Team[ pSoldier->bTeam ].bFirstID; for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ pSoldier->bTeam ].bLastID; cnt++,pTeamSoldier++) { if ( pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->bLife >= OKLIFE ) @@ -3116,20 +3147,20 @@ void HandlePlayerTeamMemberDeath( SOLDIERTYPE *pSoldier ) bBuddyIndex = WhichBuddy( pTeamSoldier->ubProfile, pSoldier->ubProfile ); switch( bBuddyIndex ) { - case 0: - // buddy #1 died! - TacticalCharacterDialogue( pTeamSoldier, QUOTE_BUDDY_ONE_KILLED ); - break; - case 1: - // buddy #2 died! - TacticalCharacterDialogue( pTeamSoldier, QUOTE_BUDDY_TWO_KILLED ); - break; - case 2: - // learn to like buddy died! - TacticalCharacterDialogue( pTeamSoldier, QUOTE_LEARNED_TO_LIKE_MERC_KILLED ); - break; - default: - break; + case 0: + // buddy #1 died! + TacticalCharacterDialogue( pTeamSoldier, QUOTE_BUDDY_ONE_KILLED ); + break; + case 1: + // buddy #2 died! + TacticalCharacterDialogue( pTeamSoldier, QUOTE_BUDDY_TWO_KILLED ); + break; + case 2: + // learn to like buddy died! + TacticalCharacterDialogue( pTeamSoldier, QUOTE_LEARNED_TO_LIKE_MERC_KILLED ); + break; + default: + break; } } } @@ -3137,29 +3168,29 @@ void HandlePlayerTeamMemberDeath( SOLDIERTYPE *pSoldier ) // handle stuff for Carmen if Slay is killed switch( pSoldier->ubProfile ) { - case SLAY: - pTeamSoldier = FindSoldierByProfileID( CARMEN, FALSE ); - if (pTeamSoldier && pTeamSoldier->bAttitude == ATTACKSLAYONLY && ClosestPC( pTeamSoldier, NULL ) != NOWHERE ) - { - // Carmen now becomes friendly again - TriggerNPCRecord( CARMEN, 29 ); - } - break; - case ROBOT: - if (CheckFact( FACT_FIRST_ROBOT_DESTROYED, 0 ) == FALSE ) - { - SetFactTrue( FACT_FIRST_ROBOT_DESTROYED ); - SetFactFalse( FACT_ROBOT_READY ); - } - else - { - SetFactTrue( FACT_SECOND_ROBOT_DESTROYED ); - } - break; + case SLAY: + pTeamSoldier = FindSoldierByProfileID( CARMEN, FALSE ); + if (pTeamSoldier && pTeamSoldier->bAttitude == ATTACKSLAYONLY && ClosestPC( pTeamSoldier, NULL ) != NOWHERE ) + { + // Carmen now becomes friendly again + TriggerNPCRecord( CARMEN, 29 ); + } + break; + case ROBOT: + if (CheckFact( FACT_FIRST_ROBOT_DESTROYED, 0 ) == FALSE ) + { + SetFactTrue( FACT_FIRST_ROBOT_DESTROYED ); + SetFactFalse( FACT_ROBOT_READY ); + } + else + { + SetFactTrue( FACT_SECOND_ROBOT_DESTROYED ); + } + break; } } - + //Make a call to handle the strategic things, such as Life Insurance, record it in history file etc. StrategicHandlePlayerTeamMercDeath( pSoldier ); @@ -3186,10 +3217,10 @@ void HandlePlayerTeamMemberDeath( SOLDIERTYPE *pSoldier ) void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld ) { SOLDIERTYPE *pKiller = NULL; - BOOLEAN bVisible; + BOOLEAN bVisible; pSoldierOld->uiStatusFlags |= SOLDIER_DEAD; - bVisible = pSoldierOld->bVisible; + bVisible = pSoldierOld->bVisible; VerifyPublicOpplistDueToDeath( pSoldierOld ); @@ -3221,137 +3252,137 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld ) { SOLDIERTYPE * pOther; - // ATE: Added string to player - if ( bVisible != -1 && pSoldierOld->ubProfile != NO_PROFILE ) - { - ScreenMsg( FONT_RED, MSG_INTERFACE, pMercDeadString[ 0 ], pSoldierOld->name ); - } + // ATE: Added string to player + if ( bVisible != -1 && pSoldierOld->ubProfile != NO_PROFILE ) + { + ScreenMsg( FONT_RED, MSG_INTERFACE, pMercDeadString[ 0 ], pSoldierOld->name ); + } switch( pSoldierOld->ubProfile ) { - case BRENDA: - SetFactTrue( FACT_BRENDA_DEAD ); + case BRENDA: + SetFactTrue( FACT_BRENDA_DEAD ); + { + pOther = FindSoldierByProfileID( HANS, FALSE ); + if (pOther && pOther->bLife >= OKLIFE && pOther->bNeutral && (SpacesAway( pSoldierOld->sGridNo, pOther->sGridNo ) <= 12) ) { - pOther = FindSoldierByProfileID( HANS, FALSE ); - if (pOther && pOther->bLife >= OKLIFE && pOther->bNeutral && (SpacesAway( pSoldierOld->sGridNo, pOther->sGridNo ) <= 12) ) - { - - TriggerNPCRecord( HANS, 10 ); - } - } - break; - case PABLO: - AddFutureDayStrategicEvent( EVENT_SECOND_AIRPORT_ATTENDANT_ARRIVED, 480 + Random( 60 ), 0, 1 ); - break; - case ROBOT: - if (CheckFact( FACT_FIRST_ROBOT_DESTROYED, 0 ) == FALSE ) - { - SetFactTrue( FACT_FIRST_ROBOT_DESTROYED ); - } - else - { - SetFactTrue( FACT_SECOND_ROBOT_DESTROYED ); - } - break; - case DRUGGIST: - case SLAY: - case ANNIE: - case CHRIS: - case TIFFANY: - case T_REX: - MakeRemainingTerroristsTougher(); - if ( pSoldierOld->ubProfile == DRUGGIST ) - { - pOther = FindSoldierByProfileID( MANNY, 0 ); - if (pOther && pOther->bActive && pOther->bInSector && pOther->bLife >= OKLIFE ) - { - // try to make sure he isn't cowering etc - pOther->sNoiseGridno = NOWHERE; - pOther->bAlertStatus = STATUS_GREEN; - TriggerNPCRecord( MANNY, 10 ); - } - } - break; - case JIM: - case JACK: - case OLAF: - case RAY: - case OLGA: - case TYRONE: - MakeRemainingAssassinsTougher(); - break; - case ELDIN: - // the security guard... Results in an extra loyalty penalty for Balime (in addition to civilian murder) + TriggerNPCRecord( HANS, 10 ); + } + } + break; + case PABLO: + AddFutureDayStrategicEvent( EVENT_SECOND_AIRPORT_ATTENDANT_ARRIVED, 480 + Random( 60 ), 0, 1 ); + break; + case ROBOT: + if (CheckFact( FACT_FIRST_ROBOT_DESTROYED, 0 ) == FALSE ) + { + SetFactTrue( FACT_FIRST_ROBOT_DESTROYED ); + } + else + { + SetFactTrue( FACT_SECOND_ROBOT_DESTROYED ); + } + break; + case DRUGGIST: + case SLAY: + case ANNIE: + case CHRIS: + case TIFFANY: + case T_REX: + MakeRemainingTerroristsTougher(); + if ( pSoldierOld->ubProfile == DRUGGIST ) + { + pOther = FindSoldierByProfileID( MANNY, 0 ); + if (pOther && pOther->bActive && pOther->bInSector && pOther->bLife >= OKLIFE ) + { + // try to make sure he isn't cowering etc + pOther->sNoiseGridno = NOWHERE; + pOther->bAlertStatus = STATUS_GREEN; + TriggerNPCRecord( MANNY, 10 ); + } + } + break; + case JIM: + case JACK: + case OLAF: + case RAY: + case OLGA: + case TYRONE: + MakeRemainingAssassinsTougher(); + break; -/* Delayed loyalty effects elimininated. Sep.12/98. ARM - // create the event value, for town BALIME - uiLoyaltyValue = BuildLoyaltyEventValue( BALIME, LOYALTY_PENALTY_ELDIN_KILLED, FALSE ); + case ELDIN: + // the security guard... Results in an extra loyalty penalty for Balime (in addition to civilian murder) + + /* Delayed loyalty effects elimininated. Sep.12/98. ARM + // create the event value, for town BALIME + uiLoyaltyValue = BuildLoyaltyEventValue( BALIME, LOYALTY_PENALTY_ELDIN_KILLED, FALSE ); + // post the event, 30 minute delay + AddStrategicEvent( EVENT_TOWN_LOYALTY_UPDATE, GetWorldTotalMin() + 30, uiLoyaltyValue ); + */ + DecrementTownLoyalty( BALIME, LOYALTY_PENALTY_ELDIN_KILLED ); + break; + case JOEY: + // check to see if Martha can see this + pOther = FindSoldierByProfileID( MARTHA, FALSE ); + if ( pOther && (PythSpacesAway( pOther->sGridNo, pSoldierOld->sGridNo ) < 10 || SoldierToSoldierLineOfSightTest( pOther, pSoldierOld, (UINT8) MaxDistanceVisible(), TRUE ) != 0 ) ) + { + // Martha has a heart attack and croaks + TriggerNPCRecord( MARTHA, 17 ); + + /* Delayed loyalty effects elimininated. Sep.12/98. ARM + // create the event value, for town CAMBRIA + uiLoyaltyValue = BuildLoyaltyEventValue( CAMBRIA, LOYALTY_PENALTY_MARTHA_HEART_ATTACK, FALSE ); // post the event, 30 minute delay AddStrategicEvent( EVENT_TOWN_LOYALTY_UPDATE, GetWorldTotalMin() + 30, uiLoyaltyValue ); -*/ - DecrementTownLoyalty( BALIME, LOYALTY_PENALTY_ELDIN_KILLED ); - break; - case JOEY: - // check to see if Martha can see this - pOther = FindSoldierByProfileID( MARTHA, FALSE ); - if ( pOther && (PythSpacesAway( pOther->sGridNo, pSoldierOld->sGridNo ) < 10 || SoldierToSoldierLineOfSightTest( pOther, pSoldierOld, (UINT8) MaxDistanceVisible(), TRUE ) != 0 ) ) - { - // Martha has a heart attack and croaks - TriggerNPCRecord( MARTHA, 17 ); - -/* Delayed loyalty effects elimininated. Sep.12/98. ARM - // create the event value, for town CAMBRIA - uiLoyaltyValue = BuildLoyaltyEventValue( CAMBRIA, LOYALTY_PENALTY_MARTHA_HEART_ATTACK, FALSE ); - // post the event, 30 minute delay - AddStrategicEvent( EVENT_TOWN_LOYALTY_UPDATE, GetWorldTotalMin() + 30, uiLoyaltyValue ); -*/ - DecrementTownLoyalty( CAMBRIA, LOYALTY_PENALTY_MARTHA_HEART_ATTACK ); - } - else // Martha doesn't see it. She lives, but Joey is found a day or so later anyways - { -/* - // create the event value, for town CAMBRIA - uiLoyaltyValue = BuildLoyaltyEventValue( CAMBRIA, LOYALTY_PENALTY_JOEY_KILLED, FALSE ); - // post the event, 30 minute delay - AddStrategicEvent( EVENT_TOWN_LOYALTY_UPDATE, GetWorldTotalMin() + ( ( 12 + Random(13)) * 60 ), uiLoyaltyValue ); -*/ - DecrementTownLoyalty( CAMBRIA, LOYALTY_PENALTY_JOEY_KILLED ); - } - break; - case DYNAMO: - // check to see if dynamo quest is on - if ( gubQuest[ QUEST_FREE_DYNAMO ] == QUESTINPROGRESS) - { - EndQuest( QUEST_FREE_DYNAMO, pSoldierOld->sSectorX, pSoldierOld->sSectorY ); - } - break; - case KINGPIN: - // check to see if Kingpin money quest is on - if ( gubQuest[ QUEST_KINGPIN_MONEY ] == QUESTINPROGRESS) - { - EndQuest( QUEST_KINGPIN_MONEY, pSoldierOld->sSectorX, pSoldierOld->sSectorY ); - HandleNPCDoAction( KINGPIN, NPC_ACTION_GRANT_EXPERIENCE_3, 0 ); - } - SetFactTrue( FACT_KINGPIN_DEAD ); - ExecuteStrategicAIAction( STRATEGIC_AI_ACTION_KINGPIN_DEAD, 0, 0 ); - break; - case DOREEN: - // Doreen's dead - if ( CheckFact( FACT_DOREEN_HAD_CHANGE_OF_HEART, 0 ) ) - { - // tsk tsk, player killed her after getting her to reconsider, lose the bonus for sparing her - DecrementTownLoyalty( DRASSEN, LOYALTY_BONUS_CHILDREN_FREED_DOREEN_SPARED ); - } // then get the points for freeing the kids though killing her - IncrementTownLoyalty( DRASSEN, LOYALTY_BONUS_CHILDREN_FREED_DOREEN_KILLED ); - // set the fact true so we have a universal check for whether the kids can go - SetFactTrue( FACT_DOREEN_HAD_CHANGE_OF_HEART ); - EndQuest( QUEST_FREE_CHILDREN, gWorldSectorX, gWorldSectorY ); - if ( CheckFact( FACT_KIDS_ARE_FREE , 0 ) == FALSE ) - { - HandleNPCDoAction( DOREEN, NPC_ACTION_FREE_KIDS, 0 ); - } - break; + */ + DecrementTownLoyalty( CAMBRIA, LOYALTY_PENALTY_MARTHA_HEART_ATTACK ); + } + else // Martha doesn't see it. She lives, but Joey is found a day or so later anyways + { + /* + // create the event value, for town CAMBRIA + uiLoyaltyValue = BuildLoyaltyEventValue( CAMBRIA, LOYALTY_PENALTY_JOEY_KILLED, FALSE ); + // post the event, 30 minute delay + AddStrategicEvent( EVENT_TOWN_LOYALTY_UPDATE, GetWorldTotalMin() + ( ( 12 + Random(13)) * 60 ), uiLoyaltyValue ); + */ + DecrementTownLoyalty( CAMBRIA, LOYALTY_PENALTY_JOEY_KILLED ); + } + break; + case DYNAMO: + // check to see if dynamo quest is on + if ( gubQuest[ QUEST_FREE_DYNAMO ] == QUESTINPROGRESS) + { + EndQuest( QUEST_FREE_DYNAMO, pSoldierOld->sSectorX, pSoldierOld->sSectorY ); + } + break; + case KINGPIN: + // check to see if Kingpin money quest is on + if ( gubQuest[ QUEST_KINGPIN_MONEY ] == QUESTINPROGRESS) + { + EndQuest( QUEST_KINGPIN_MONEY, pSoldierOld->sSectorX, pSoldierOld->sSectorY ); + HandleNPCDoAction( KINGPIN, NPC_ACTION_GRANT_EXPERIENCE_3, 0 ); + } + SetFactTrue( FACT_KINGPIN_DEAD ); + ExecuteStrategicAIAction( STRATEGIC_AI_ACTION_KINGPIN_DEAD, 0, 0 ); + break; + case DOREEN: + // Doreen's dead + if ( CheckFact( FACT_DOREEN_HAD_CHANGE_OF_HEART, 0 ) ) + { + // tsk tsk, player killed her after getting her to reconsider, lose the bonus for sparing her + DecrementTownLoyalty( DRASSEN, LOYALTY_BONUS_CHILDREN_FREED_DOREEN_SPARED ); + } // then get the points for freeing the kids though killing her + IncrementTownLoyalty( DRASSEN, LOYALTY_BONUS_CHILDREN_FREED_DOREEN_KILLED ); + // set the fact true so we have a universal check for whether the kids can go + SetFactTrue( FACT_DOREEN_HAD_CHANGE_OF_HEART ); + EndQuest( QUEST_FREE_CHILDREN, gWorldSectorX, gWorldSectorY ); + if ( CheckFact( FACT_KIDS_ARE_FREE , 0 ) == FALSE ) + { + HandleNPCDoAction( DOREEN, NPC_ACTION_FREE_KIDS, 0 ); + } + break; } // Are we looking at the queen? @@ -3360,11 +3391,11 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld ) if ( pSoldierOld->ubAttackerID != NOBODY ) { pKiller = MercPtrs[ pSoldierOld->ubAttackerID ]; - } + } BeginHandleDeidrannaDeath( pKiller, pSoldierOld->sGridNo, pSoldierOld->bLevel ); } - + // crows/cows are on the civilian team, but none of the following applies to them if ( ( pSoldierOld->ubBodyType != CROW ) && ( pSoldierOld->ubBodyType != COW ) ) { @@ -3379,7 +3410,7 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld ) else if ( pSoldierOld->bTeam == MILITIA_TEAM ) { INT8 bMilitiaRank; - + bMilitiaRank = SoldierClassToMilitiaRank( pSoldierOld->ubSoldierClass ); if (bMilitiaRank != -1) @@ -3399,8 +3430,8 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld ) } else // enemies and creatures... should any of this stuff not be called if a creature dies? { - if ( pSoldierOld->ubBodyType == QUEENMONSTER ) - { + if ( pSoldierOld->ubBodyType == QUEENMONSTER ) + { SOLDIERTYPE *pKiller = NULL; if ( pSoldierOld->ubAttackerID != NOBODY ) @@ -3409,7 +3440,7 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld ) BeginHandleQueenBitchDeath( pKiller, pSoldierOld->sGridNo, pSoldierOld->bLevel ); } - } + } if ( pSoldierOld->bTeam == ENEMY_TEAM ) { @@ -3501,8 +3532,8 @@ UINT8 LastActiveTeamMember( UINT8 ubTeam ) cnt = gTacticalStatus.Team[ ubTeam ].bLastID; - // look for all mercs on the same team, - for ( pSoldier = MercPtrs[ cnt ]; cnt >= gTacticalStatus.Team[ ubTeam ].bFirstID; cnt-- ,pSoldier--) + // look for all mercs on the same team, + for ( pSoldier = MercPtrs[ cnt ]; cnt >= gTacticalStatus.Team[ ubTeam ].bFirstID; cnt-- ,pSoldier--) { if ( pSoldier->bActive ) { @@ -3525,17 +3556,17 @@ void CheckForPotentialAddToBattleIncrement( SOLDIERTYPE *pSoldier ) // maybe increment num enemy attacked switch ( pSoldier->ubCivilianGroup ) { - case REBEL_CIV_GROUP: - case KINGPIN_CIV_GROUP: - case HICKS_CIV_GROUP: - if ( FindObjClass( pSoldier, IC_WEAPON ) != NO_SLOT ) - { - gTacticalStatus.bNumFoughtInBattle[ pSoldier->bTeam ]++; - } - break; - default: - // nope! - break; + case REBEL_CIV_GROUP: + case KINGPIN_CIV_GROUP: + case HICKS_CIV_GROUP: + if ( FindObjClass( pSoldier, IC_WEAPON ) != NO_SLOT ) + { + gTacticalStatus.bNumFoughtInBattle[ pSoldier->bTeam ]++; + } + break; + default: + // nope! + break; } } else @@ -3585,33 +3616,33 @@ void MakeCivHostile( SOLDIERTYPE *pSoldier, INT8 bNewSide ) switch( pSoldier->ubProfile ) { - case IRA: - case DIMITRI: - case MIGUEL: - case CARLOS: - case MADLAB: - case DYNAMO: - case SHANK: - // rebels and rebel sympathizers become hostile to player and enemy + case IRA: + case DIMITRI: + case MIGUEL: + case CARLOS: + case MADLAB: + case DYNAMO: + case SHANK: + // rebels and rebel sympathizers become hostile to player and enemy + bNewSide = 2; + break; + case MARIA: + case ANGEL: + if ( gubQuest[ QUEST_RESCUE_MARIA ] == QUESTINPROGRESS || gubQuest[ QUEST_RESCUE_MARIA ] == QUESTDONE ) + { + bNewSide = 2; + } + break; + default: + switch( pSoldier->ubCivilianGroup ) + { + case REBEL_CIV_GROUP: bNewSide = 2; break; - case MARIA: - case ANGEL: - if ( gubQuest[ QUEST_RESCUE_MARIA ] == QUESTINPROGRESS || gubQuest[ QUEST_RESCUE_MARIA ] == QUESTDONE ) - { - bNewSide = 2; - } - break; default: - switch( pSoldier->ubCivilianGroup ) - { - case REBEL_CIV_GROUP: - bNewSide = 2; - break; - default: - break; - } break; + } + break; } if ( !pSoldier->bNeutral && bNewSide == pSoldier->bSide ) @@ -3678,7 +3709,7 @@ UINT8 CivilianGroupMembersChangeSidesWithinProximity( SOLDIERTYPE * pAttacked ) } cnt = gTacticalStatus.Team[ CIV_TEAM ].bFirstID; - for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ CIV_TEAM ].bLastID; cnt++ ,pSoldier++ ) + for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ CIV_TEAM ].bLastID; cnt++ ,pSoldier++ ) { if ( pSoldier->bActive && pSoldier->bInSector && pSoldier->bLife && pSoldier->bNeutral ) { @@ -3686,8 +3717,8 @@ UINT8 CivilianGroupMembersChangeSidesWithinProximity( SOLDIERTYPE * pAttacked ) { // if in LOS of this guy's attacker if ( (pAttacked->ubAttackerID != NOBODY && pSoldier->bOppList[pAttacked->ubAttackerID] == SEEN_CURRENTLY) - || ( PythSpacesAway( pSoldier->sGridNo, pAttacked->sGridNo ) < MaxDistanceVisible() ) - || ( pAttacked->ubAttackerID != NOBODY && PythSpacesAway( pSoldier->sGridNo, MercPtrs[ pAttacked->ubAttackerID ]->sGridNo ) < MaxDistanceVisible() ) ) + || ( PythSpacesAway( pSoldier->sGridNo, pAttacked->sGridNo ) < MaxDistanceVisible() ) + || ( pAttacked->ubAttackerID != NOBODY && PythSpacesAway( pSoldier->sGridNo, MercPtrs[ pAttacked->ubAttackerID ]->sGridNo ) < MaxDistanceVisible() ) ) { MakeCivHostile( pSoldier, 2 ); if ( pSoldier->bOppCnt > 0 ) @@ -3724,7 +3755,7 @@ SOLDIERTYPE * CivilianGroupMemberChangesSides( SOLDIERTYPE * pAttacked ) // remove anyone (rebels) on our team and put them back in the civ team cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; - for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; cnt++ ,pSoldier++) + for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; cnt++ ,pSoldier++) { if (pSoldier->bActive && pSoldier->bInSector && pSoldier->bLife) { @@ -3758,12 +3789,12 @@ SOLDIERTYPE * CivilianGroupMemberChangesSides( SOLDIERTYPE * pAttacked ) CivilianGroupMembersChangeSidesWithinProximity( pNewAttacked ); } -/* + /* if ( ubFirstProfile != NO_PROFILE ) { - TriggerFriendWithHostileQuote( ubFirstProfile ); + TriggerFriendWithHostileQuote( ubFirstProfile ); } -*/ + */ if ( gTacticalStatus.fCivGroupHostile[ pNewAttacked->ubCivilianGroup ] == CIV_GROUP_NEUTRAL ) { @@ -3792,7 +3823,7 @@ void CivilianGroupChangesSides( UINT8 ubCivilianGroup ) // now change sides for anyone on the civ team cnt = gTacticalStatus.Team[ CIV_TEAM ].bFirstID; - for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ CIV_TEAM ].bLastID; cnt++ ,pSoldier++) + for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ CIV_TEAM ].bLastID; cnt++ ,pSoldier++) { if (pSoldier->bActive && pSoldier->bInSector && pSoldier->bLife && pSoldier->bNeutral) { @@ -3806,17 +3837,17 @@ void CivilianGroupChangesSides( UINT8 ubCivilianGroup ) /* if ( (pSoldier->ubProfile != NO_PROFILE) && (pSoldier->bOppCnt > 0) && ( ubFirstProfile == NO_PROFILE || Random( 2 ) ) ) { - ubFirstProfile = pSoldier->ubProfile; + ubFirstProfile = pSoldier->ubProfile; } */ } } } - + /* if ( ubFirstProfile != NO_PROFILE ) { - TriggerFriendWithHostileQuote( ubFirstProfile ); + TriggerFriendWithHostileQuote( ubFirstProfile ); } */ } @@ -3828,7 +3859,7 @@ void HickCowAttacked( SOLDIERTYPE * pNastyGuy, SOLDIERTYPE * pTarget ) // now change sides for anyone on the civ team cnt = gTacticalStatus.Team[ CIV_TEAM ].bFirstID; - for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ CIV_TEAM ].bLastID; cnt++ ,pSoldier++) + for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ CIV_TEAM ].bLastID; cnt++ ,pSoldier++) { if ( pSoldier->bActive && pSoldier->bInSector && pSoldier->bLife && pSoldier->bNeutral && pSoldier->ubCivilianGroup == HICKS_CIV_GROUP ) { @@ -3856,12 +3887,12 @@ void MilitiaChangesSides( void ) // remove anyone (rebels) on our team and put them back in the civ team cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; - for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; cnt++ ,pSoldier++) + for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; cnt++ ,pSoldier++) { if (pSoldier->bActive && pSoldier->bInSector && pSoldier->bLife) { if ( (gWorldSectorX ==0 && gWorldSectorY == 0) || !NumEnemiesInSector( gWorldSectorX, gWorldSectorY ) ) - MakeCivHostile( pSoldier, 2 ); + MakeCivHostile( pSoldier, 2 ); RecalculateOppCntsDueToNoLongerNeutral( pSoldier ); } } @@ -3870,17 +3901,17 @@ void MilitiaChangesSides( void ) /* void MakePotentiallyHostileCivGroupsHostile( void ) { - UINT8 ubLoop; +UINT8 ubLoop; - // loop through all civ groups that might become hostile and set them - // to hostile - for ( ubLoop = REBEL_CIV_GROUP; ubLoop < NUM_CIV_GROUPS; ubLoop++ ) - { - if (gTacticalStatus.fCivGroupHostile[ ubLoop ] == CIV_GROUP_WILL_BECOME_HOSTILE) - { - gTacticalStatus.fCivGroupHostile[ ubLoop ] = CIV_GROUP_HOSTILE; - } - } +// loop through all civ groups that might become hostile and set them +// to hostile +for ( ubLoop = REBEL_CIV_GROUP; ubLoop < NUM_CIV_GROUPS; ubLoop++ ) +{ +if (gTacticalStatus.fCivGroupHostile[ ubLoop ] == CIV_GROUP_WILL_BECOME_HOSTILE) +{ +gTacticalStatus.fCivGroupHostile[ ubLoop ] = CIV_GROUP_HOSTILE; +} +} } */ @@ -3892,8 +3923,8 @@ INT8 NumActiveAndConsciousTeamMembers( UINT8 ubTeam ) cnt = gTacticalStatus.Team[ ubTeam ].bFirstID; - // look for all mercs on the same team, - for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ ubTeam ].bLastID; cnt++,pSoldier++) + // look for all mercs on the same team, + for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ ubTeam ].bLastID; cnt++,pSoldier++) { if ( OK_CONTROLLABLE_MERC( pSoldier) ) { @@ -3914,8 +3945,8 @@ UINT8 FindNextActiveAndAliveMerc( SOLDIERTYPE *pSoldier, BOOLEAN fGoodForLessOKL cnt = pSoldier->ubID + 1; bLastTeamID = gTacticalStatus.Team[ pSoldier->bTeam ].bLastID; - // look for all mercs on the same team, - for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= bLastTeamID; cnt++,pTeamSoldier++) + // look for all mercs on the same team, + for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= bLastTeamID; cnt++,pTeamSoldier++) { if ( fOnlyRegularMercs ) { @@ -3946,7 +3977,7 @@ UINT8 FindNextActiveAndAliveMerc( SOLDIERTYPE *pSoldier, BOOLEAN fGoodForLessOKL cnt = gTacticalStatus.Team[ pSoldier->bTeam ].bFirstID; bLastTeamID = pSoldier->ubID; - for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= bLastTeamID; cnt++,pTeamSoldier++) + for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= bLastTeamID; cnt++,pTeamSoldier++) { if ( fOnlyRegularMercs ) { @@ -3987,10 +4018,10 @@ SOLDIERTYPE *FindNextActiveSquad( SOLDIERTYPE *pSoldier ) { for( cnt2 =0; cnt2 < NUMBER_OF_SOLDIERS_PER_SQUAD; cnt2++ ) { - if ( Squad[ cnt ][ cnt2 ] != NULL && Squad[ cnt ][ cnt2 ]->bInSector && OK_INTERRUPT_MERC( Squad[ cnt ][ cnt2 ] ) && OK_CONTROLLABLE_MERC( Squad[ cnt ][ cnt2 ] ) && !(Squad[ cnt ][ cnt2 ]->uiStatusFlags & SOLDIER_VEHICLE) ) - { - return( Squad[ cnt ][ cnt2 ] ); - } + if ( Squad[ cnt ][ cnt2 ] != NULL && Squad[ cnt ][ cnt2 ]->bInSector && OK_INTERRUPT_MERC( Squad[ cnt ][ cnt2 ] ) && OK_CONTROLLABLE_MERC( Squad[ cnt ][ cnt2 ] ) && !(Squad[ cnt ][ cnt2 ]->uiStatusFlags & SOLDIER_VEHICLE) ) + { + return( Squad[ cnt ][ cnt2 ] ); + } } } @@ -4000,10 +4031,10 @@ SOLDIERTYPE *FindNextActiveSquad( SOLDIERTYPE *pSoldier ) { for( cnt2 =0; cnt2 < NUMBER_OF_SOLDIERS_PER_SQUAD; cnt2++ ) { - if ( Squad[ cnt ][ cnt2 ] != NULL && Squad[ cnt ][ cnt2 ]->bInSector && OK_INTERRUPT_MERC( Squad[ cnt ][ cnt2 ] ) && OK_CONTROLLABLE_MERC( Squad[ cnt ][ cnt2 ] ) && !(Squad[ cnt ][ cnt2 ]->uiStatusFlags & SOLDIER_VEHICLE) ) - { - return( Squad[ cnt ][ cnt2 ] ); - } + if ( Squad[ cnt ][ cnt2 ] != NULL && Squad[ cnt ][ cnt2 ]->bInSector && OK_INTERRUPT_MERC( Squad[ cnt ][ cnt2 ] ) && OK_CONTROLLABLE_MERC( Squad[ cnt ][ cnt2 ] ) && !(Squad[ cnt ][ cnt2 ]->uiStatusFlags & SOLDIER_VEHICLE) ) + { + return( Squad[ cnt ][ cnt2 ] ); + } } } @@ -4024,7 +4055,7 @@ UINT8 FindPrevActiveAndAliveMerc( SOLDIERTYPE *pSoldier, BOOLEAN fGoodForLessOKL bLastTeamID = gTacticalStatus.Team[ pSoldier->bTeam ].bFirstID; cnt = pSoldier->ubID - 1; - for ( pTeamSoldier = MercPtrs[ cnt ]; cnt >= bLastTeamID; cnt--,pTeamSoldier-- ) + for ( pTeamSoldier = MercPtrs[ cnt ]; cnt >= bLastTeamID; cnt--,pTeamSoldier-- ) { if ( fOnlyRegularMercs ) { @@ -4054,8 +4085,8 @@ UINT8 FindPrevActiveAndAliveMerc( SOLDIERTYPE *pSoldier, BOOLEAN fGoodForLessOKL bLastTeamID = pSoldier->ubID; cnt = gTacticalStatus.Team[ pSoldier->bTeam ].bLastID; - // look for all mercs on the same team, - for ( pTeamSoldier = MercPtrs[ cnt ]; cnt >= bLastTeamID; cnt--,pTeamSoldier-- ) + // look for all mercs on the same team, + for ( pTeamSoldier = MercPtrs[ cnt ]; cnt >= bLastTeamID; cnt--,pTeamSoldier-- ) { if ( fOnlyRegularMercs ) { @@ -4096,8 +4127,8 @@ BOOLEAN CheckForPlayerTeamInMissionExit( ) // End the turn of player charactors cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; - // look for all mercs on the same team, - for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++) + // look for all mercs on the same team, + for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++) { if ( pSoldier->bActive && pSoldier->bLife >= OKLIFE ) { @@ -4192,10 +4223,10 @@ INT16 NewOKDestination( SOLDIERTYPE * pCurrSoldier, INT16 sGridNo, BOOLEAN fPeop INT16 sDesiredLevel; BOOLEAN fOKCheckStruct; - if ( !GridNoOnVisibleWorldTile( sGridNo ) ) - { - return( TRUE ); - } + if ( !GridNoOnVisibleWorldTile( sGridNo ) ) + { + return( TRUE ); + } if (fPeopleToo && ( bPerson = WhoIsThere2( sGridNo, bLevel ) ) != NO_SOLDIER ) { @@ -4206,7 +4237,7 @@ INT16 NewOKDestination( SOLDIERTYPE * pCurrSoldier, INT16 sGridNo, BOOLEAN fPeop if ( pCurrSoldier->bTeam == gbPlayerNum ) { if ( ( Menptr[ bPerson ].bVisible >= 0) || ( gTacticalStatus.uiFlags & SHOW_ALL_MERCS ) ) - return( FALSE ); // if someone there it's NOT OK + return( FALSE ); // if someone there it's NOT OK } else { @@ -4273,9 +4304,9 @@ INT16 NewOKDestination( SOLDIERTYPE * pCurrSoldier, INT16 sGridNo, BOOLEAN fPeop pStructure = FindStructure( sGridNo, STRUCTURE_BLOCKSMOVES ); - // ATE: If we are trying to get a path to an exit grid AND - // we are a cave....still allow this.. - //if ( pStructure && gfPlotPathToExitGrid && pStructure->fFlags & STRUCTURE_CAVEWALL ) + // ATE: If we are trying to get a path to an exit grid AND + // we are a cave....still allow this.. + //if ( pStructure && gfPlotPathToExitGrid && pStructure->fFlags & STRUCTURE_CAVEWALL ) if ( pStructure && gfPlotPathToExitGrid ) { pStructure = NULL; @@ -4305,7 +4336,7 @@ INT16 NewOKDestination( SOLDIERTYPE * pCurrSoldier, INT16 sGridNo, BOOLEAN fPeop } } } - + pStructure = FindNextStructure( pStructure, STRUCTURE_BLOCKSMOVES ); } } @@ -4330,7 +4361,7 @@ INT16 NewOKDestinationAndDirection( SOLDIERTYPE * pCurrSoldier, INT16 sGridNo, I if ( pCurrSoldier->bTeam == gbPlayerNum ) { if ( ( Menptr[ bPerson ].bVisible >= 0) || ( gTacticalStatus.uiFlags & SHOW_ALL_MERCS ) ) - return( FALSE ); // if someone there it's NOT OK + return( FALSE ); // if someone there it's NOT OK } else { @@ -4395,9 +4426,9 @@ INT16 NewOKDestinationAndDirection( SOLDIERTYPE * pCurrSoldier, INT16 sGridNo, I pStructure = FindStructure( sGridNo, STRUCTURE_BLOCKSMOVES ); - // ATE: If we are trying to get a path to an exit grid AND - // we are a cave....still allow this.. - //if ( pStructure && gfPlotPathToExitGrid && pStructure->fFlags & STRUCTURE_CAVEWALL ) + // ATE: If we are trying to get a path to an exit grid AND + // we are a cave....still allow this.. + //if ( pStructure && gfPlotPathToExitGrid && pStructure->fFlags & STRUCTURE_CAVEWALL ) if ( pStructure && gfPlotPathToExitGrid ) { pStructure = NULL; @@ -4427,7 +4458,7 @@ INT16 NewOKDestinationAndDirection( SOLDIERTYPE * pCurrSoldier, INT16 sGridNo, I } } } - + pStructure = FindNextStructure( pStructure, STRUCTURE_BLOCKSMOVES ); } } @@ -4469,7 +4500,7 @@ BOOLEAN IsLocationSittable( INT32 iMapIndex, BOOLEAN fOnRoof ) STRUCTURE *pStructure; INT16 sDesiredLevel; if( WhoIsThere2( (INT16)iMapIndex, 0 ) != NO_SOLDIER ) - return FALSE; + return FALSE; //Locations on roofs without a roof is not possible, so //we convert the onroof intention to ground. if( fOnRoof && !FlatRoofAboveGridNo( iMapIndex ) ) @@ -4538,57 +4569,57 @@ BOOLEAN TeamMemberNear(INT8 bTeam, INT16 sGridNo, INT32 iRange) INT16 FindAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pubDirection, INT16 *psAdjustedGridNo, BOOLEAN fForceToPerson, BOOLEAN fDoor ) { -// psAdjustedGridNo gets the original gridno or the new one if updated + // psAdjustedGridNo gets the original gridno or the new one if updated // It will ONLY be updated IF we were over a merc, ( it's updated to their gridno ) -// pubDirection gets the direction to the final gridno -// fForceToPerson: forces the grid under consideration to be the one occupiedby any target -// in that location, because we could be passed a gridno based on the overlap of soldier's graphic -// fDoor determines whether special door-handling code should be used (for interacting with doors) + // pubDirection gets the direction to the final gridno + // fForceToPerson: forces the grid under consideration to be the one occupiedby any target + // in that location, because we could be passed a gridno based on the overlap of soldier's graphic + // fDoor determines whether special door-handling code should be used (for interacting with doors) - INT16 sFourGrids[4], sDistance=0; - INT16 sDirs[4] = { NORTH, EAST, SOUTH, WEST }; - INT32 cnt; - INT16 sClosest=NOWHERE, sSpot, sOkTest; - INT16 sCloseGridNo=NOWHERE; - UINT32 uiMercFlags; - UINT16 usSoldierIndex; - UINT8 ubDir; - STRUCTURE *pDoor; - //STRUCTURE *pWall; - UINT8 ubWallOrientation; - BOOLEAN fCheckGivenGridNo = TRUE; - UINT8 ubTestDirection; - EXITGRID ExitGrid; + INT16 sFourGrids[4], sDistance=0; + INT16 sDirs[4] = { NORTH, EAST, SOUTH, WEST }; + INT32 cnt; + INT16 sClosest=NOWHERE, sSpot, sOkTest; + INT16 sCloseGridNo=NOWHERE; + UINT32 uiMercFlags; + UINT16 usSoldierIndex; + UINT8 ubDir; + STRUCTURE *pDoor; + //STRUCTURE *pWall; + UINT8 ubWallOrientation; + BOOLEAN fCheckGivenGridNo = TRUE; + UINT8 ubTestDirection; + EXITGRID ExitGrid; - // Set default direction - if (pubDirection) - { - *pubDirection = pSoldier->bDirection; - } + // Set default direction + if (pubDirection) + { + *pubDirection = pSoldier->bDirection; + } - // CHECK IF WE WANT TO FORCE GRIDNO TO PERSON - if ( psAdjustedGridNo != NULL ) - { - *psAdjustedGridNo = sGridNo; - } + // CHECK IF WE WANT TO FORCE GRIDNO TO PERSON + if ( psAdjustedGridNo != NULL ) + { + *psAdjustedGridNo = sGridNo; + } - // CHECK IF IT'S THE SAME ONE AS WE'RE ON, IF SO, RETURN THAT! - if ( pSoldier->sGridNo == sGridNo && !FindStructure( sGridNo, ( STRUCTURE_SWITCH ) ) ) - { - // OK, if we are looking for a door, it may be in the same tile as us, so find the direction we - // have to face to get to the door, not just our initial direction... - // If we are in the same tile as a switch, we can NEVER pull it.... - if( fDoor ) - { + // CHECK IF IT'S THE SAME ONE AS WE'RE ON, IF SO, RETURN THAT! + if ( pSoldier->sGridNo == sGridNo && !FindStructure( sGridNo, ( STRUCTURE_SWITCH ) ) ) + { + // OK, if we are looking for a door, it may be in the same tile as us, so find the direction we + // have to face to get to the door, not just our initial direction... + // If we are in the same tile as a switch, we can NEVER pull it.... + if( fDoor ) + { // This can only happen if a door was to the south to east of us! - // Do south! - //sSpot = NewGridNo( sGridNo, DirectionInc( SOUTH ) ); + // Do south! + //sSpot = NewGridNo( sGridNo, DirectionInc( SOUTH ) ); - // ATE: Added: Switch behave EXACTLY like doors + // ATE: Added: Switch behave EXACTLY like doors pDoor = FindStructure( sGridNo, ( STRUCTURE_ANYDOOR ) ); - if ( pDoor != NULL ) + if ( pDoor != NULL ) { // Get orinetation ubWallOrientation = pDoor->ubWallOrientation; @@ -4596,7 +4627,7 @@ INT16 FindAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pubDirect if ( ubWallOrientation == OUTSIDE_TOP_LEFT || ubWallOrientation == INSIDE_TOP_LEFT ) { // To the south! - sSpot = NewGridNo( sGridNo, DirectionInc( SOUTH ) ); + sSpot = NewGridNo( sGridNo, DirectionInc( SOUTH ) ); if (pubDirection) { (*pubDirection) = (UINT8)GetDirectionFromGridNo( sSpot, pSoldier ); @@ -4613,13 +4644,13 @@ INT16 FindAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pubDirect } } } - } + } - // Use soldier's direction - return( sGridNo ); - } + // Use soldier's direction + return( sGridNo ); + } - // Look for a door! + // Look for a door! if (fDoor) { pDoor = FindStructure( sGridNo, ( STRUCTURE_ANYDOOR | STRUCTURE_SWITCH ) ); @@ -4648,77 +4679,77 @@ INT16 FindAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pubDirect } - if ( ( sOkTest = NewOKDestination( pSoldier, sGridNo, TRUE, pSoldier->bLevel ) ) > 0) // no problem going there! nobody on it! - { - // OK, if we are looking to goto a switch, ignore this.... - if ( pDoor ) - { + if ( ( sOkTest = NewOKDestination( pSoldier, sGridNo, TRUE, pSoldier->bLevel ) ) > 0) // no problem going there! nobody on it! + { + // OK, if we are looking to goto a switch, ignore this.... + if ( pDoor ) + { if ( pDoor->fFlags & STRUCTURE_SWITCH ) { // Don't continuel fCheckGivenGridNo = FALSE; } - } + } - // If there is an exit grid.... - if ( GetExitGrid( sGridNo, &ExitGrid ) ) - { + // If there is an exit grid.... + if ( GetExitGrid( sGridNo, &ExitGrid ) ) + { // Don't continuel fCheckGivenGridNo = FALSE; - } + } - if ( fCheckGivenGridNo ) - { - sDistance = PlotPath( pSoldier, sGridNo, NO_COPYROUTE, NO_PLOT, TEMPORARY, (INT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints ); + if ( fCheckGivenGridNo ) + { + sDistance = PlotPath( pSoldier, sGridNo, NO_COPYROUTE, NO_PLOT, TEMPORARY, (INT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints ); - if ( sDistance > 0 ) + if ( sDistance > 0 ) { - + if ( sDistance < sClosest ) { - sClosest = sDistance; - sCloseGridNo = (INT16)sGridNo; + sClosest = sDistance; + sCloseGridNo = (INT16)sGridNo; } } - } - } + } + } - for (cnt = 0; cnt < 4; cnt++) - { - // MOVE OUT TWO DIRECTIONS - sFourGrids[cnt] = sSpot = NewGridNo( sGridNo, DirectionInc( sDirs[ cnt ] ) ); + for (cnt = 0; cnt < 4; cnt++) + { + // MOVE OUT TWO DIRECTIONS + sFourGrids[cnt] = sSpot = NewGridNo( sGridNo, DirectionInc( sDirs[ cnt ] ) ); - ubTestDirection = (UINT8)sDirs[ cnt ]; + ubTestDirection = (UINT8)sDirs[ cnt ]; - // For switches, ALLOW them to walk through walls to reach it.... - if ( pDoor && pDoor->fFlags & STRUCTURE_SWITCH ) - { + // For switches, ALLOW them to walk through walls to reach it.... + if ( pDoor && pDoor->fFlags & STRUCTURE_SWITCH ) + { ubTestDirection = gOppositeDirection[ ubTestDirection ]; - } + } - if( fDoor ) - { + if( fDoor ) + { if ( gubWorldMovementCosts[ sSpot ][ ubTestDirection ][ pSoldier->bLevel ] >= TRAVELCOST_BLOCKED ) { // obstacle or wall there! continue; } - } - else - { - // this function returns original MP cost if not a door cost - if ( DoorTravelCost( pSoldier, sSpot, gubWorldMovementCosts[ sSpot ][ ubTestDirection ][ pSoldier->bLevel ], FALSE, NULL ) >= TRAVELCOST_BLOCKED ) + } + else + { + // this function returns original MP cost if not a door cost + if ( DoorTravelCost( pSoldier, sSpot, gubWorldMovementCosts[ sSpot ][ ubTestDirection ][ pSoldier->bLevel ], FALSE, NULL ) >= TRAVELCOST_BLOCKED ) { - // obstacle or wall there! - continue; + // obstacle or wall there! + continue; } - } + } - // Eliminate some directions if we are looking at doors! - if ( pDoor != NULL ) - { + // Eliminate some directions if we are looking at doors! + if ( pDoor != NULL ) + { // Get orinetation ubWallOrientation = pDoor->ubWallOrientation; @@ -4735,89 +4766,89 @@ INT16 FindAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pubDirect if ( sDirs[ cnt ] == NORTH || sDirs[ cnt ] == WEST || sDirs[ cnt ] == EAST ) continue; } - } + } - // If this spot is our soldier's gridno use that! - if ( sSpot == pSoldier->sGridNo ) - { - // Use default diurection ) soldier's direction ) - - // OK, at least get direction to face...... - // Defaults to soldier's facing dir unless we change it! - //if ( pDoor != NULL ) + // If this spot is our soldier's gridno use that! + if ( sSpot == pSoldier->sGridNo ) + { + // Use default diurection ) soldier's direction ) + + // OK, at least get direction to face...... + // Defaults to soldier's facing dir unless we change it! + //if ( pDoor != NULL ) { - // Use direction to the door! - if (pubDirection) + // Use direction to the door! + if (pubDirection) { (*pubDirection) = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier ); } } return( sSpot ); - } + } - // don't store path, just measure it - ubDir = (UINT8)GetDirectionToGridNoFromGridNo( sSpot, sGridNo ); + // don't store path, just measure it + ubDir = (UINT8)GetDirectionToGridNoFromGridNo( sSpot, sGridNo ); - if ( ( NewOKDestinationAndDirection( pSoldier, sSpot, ubDir, TRUE, pSoldier->bLevel ) > 0 ) && - ( ( sDistance = PlotPath( pSoldier, sSpot, NO_COPYROUTE, NO_PLOT, TEMPORARY, (INT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints ) ) > 0 ) ) - { - if ( sDistance < sClosest ) - { + if ( ( NewOKDestinationAndDirection( pSoldier, sSpot, ubDir, TRUE, pSoldier->bLevel ) > 0 ) && + ( ( sDistance = PlotPath( pSoldier, sSpot, NO_COPYROUTE, NO_PLOT, TEMPORARY, (INT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints ) ) > 0 ) ) + { + if ( sDistance < sClosest ) + { sClosest = sDistance; sCloseGridNo = (INT16)sSpot; - } - } - } + } + } + } if (sClosest != NOWHERE) - { - // Take last direction and use opposite! - // This will be usefull for ours and AI mercs + { + // Take last direction and use opposite! + // This will be usefull for ours and AI mercs - // If our gridno is the same ( which can be if we are look at doors ) - if ( sGridNo == sCloseGridNo ) - { - if (pubDirection) + // If our gridno is the same ( which can be if we are look at doors ) + if ( sGridNo == sCloseGridNo ) + { + if (pubDirection) + { + // ATE: Only if we have a valid door! + if ( pDoor ) { - // ATE: Only if we have a valid door! - if ( pDoor ) + switch( pDoor->pDBStructureRef->pDBStructure->ubWallOrientation ) { - switch( pDoor->pDBStructureRef->pDBStructure->ubWallOrientation ) - { - case OUTSIDE_TOP_LEFT: - case INSIDE_TOP_LEFT: + case OUTSIDE_TOP_LEFT: + case INSIDE_TOP_LEFT: - *pubDirection = SOUTH; - break; + *pubDirection = SOUTH; + break; - case OUTSIDE_TOP_RIGHT: - case INSIDE_TOP_RIGHT: + case OUTSIDE_TOP_RIGHT: + case INSIDE_TOP_RIGHT: - *pubDirection = EAST; - break; - } + *pubDirection = EAST; + break; } } - } - else - { - // Calculate direction if our gridno is different.... - ubDir = (UINT8)GetDirectionToGridNoFromGridNo( sCloseGridNo, sGridNo ); - if (pubDirection) - { - *pubDirection = ubDir; - } - } - //if ( psAdjustedGridNo != NULL ) - //{ + } + } + else + { + // Calculate direction if our gridno is different.... + ubDir = (UINT8)GetDirectionToGridNoFromGridNo( sCloseGridNo, sGridNo ); + if (pubDirection) + { + *pubDirection = ubDir; + } + } + //if ( psAdjustedGridNo != NULL ) + //{ // (*psAdjustedGridNo) = sCloseGridNo; - //} - if ( sCloseGridNo == NOWHERE ) - { - return( -1 ); - } - return( sCloseGridNo ); - } + //} + if ( sCloseGridNo == NOWHERE ) + { + return( -1 ); + } + return( sCloseGridNo ); + } else return( -1 ); } @@ -4825,42 +4856,42 @@ INT16 FindAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pubDirect INT16 FindNextToAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pubDirection, INT16 *psAdjustedGridNo, BOOLEAN fForceToPerson, BOOLEAN fDoor ) { -// This function works in a similar way as FindAdjacentGridEx, but looks for a location 2 tiles away + // This function works in a similar way as FindAdjacentGridEx, but looks for a location 2 tiles away -// psAdjustedGridNo gets the original gridno or the new one if updated -// pubDirection gets the direction to the final gridno -// fForceToPerson: forces the grid under consideration to be the one occupiedby any target -// in that location, because we could be passed a gridno based on the overlap of soldier's graphic -// fDoor determines whether special door-handling code should be used (for interacting with doors) + // psAdjustedGridNo gets the original gridno or the new one if updated + // pubDirection gets the direction to the final gridno + // fForceToPerson: forces the grid under consideration to be the one occupiedby any target + // in that location, because we could be passed a gridno based on the overlap of soldier's graphic + // fDoor determines whether special door-handling code should be used (for interacting with doors) - INT16 sFourGrids[4], sDistance=0; - INT16 sDirs[4] = { NORTH, EAST, SOUTH, WEST }; - INT32 cnt; - INT16 sClosest=WORLD_MAX, sSpot, sSpot2, sOkTest; - INT16 sCloseGridNo=NOWHERE; - UINT32 uiMercFlags; - UINT16 usSoldierIndex; - UINT8 ubDir; - STRUCTURE *pDoor; - UINT8 ubWallOrientation; - BOOLEAN fCheckGivenGridNo = TRUE; - UINT8 ubTestDirection; - UINT8 ubWhoIsThere; + INT16 sFourGrids[4], sDistance=0; + INT16 sDirs[4] = { NORTH, EAST, SOUTH, WEST }; + INT32 cnt; + INT16 sClosest=WORLD_MAX, sSpot, sSpot2, sOkTest; + INT16 sCloseGridNo=NOWHERE; + UINT32 uiMercFlags; + UINT16 usSoldierIndex; + UINT8 ubDir; + STRUCTURE *pDoor; + UINT8 ubWallOrientation; + BOOLEAN fCheckGivenGridNo = TRUE; + UINT8 ubTestDirection; + UINT8 ubWhoIsThere; - // CHECK IF WE WANT TO FORCE GRIDNO TO PERSON - if ( psAdjustedGridNo != NULL ) - { - *psAdjustedGridNo = sGridNo; - } + // CHECK IF WE WANT TO FORCE GRIDNO TO PERSON + if ( psAdjustedGridNo != NULL ) + { + *psAdjustedGridNo = sGridNo; + } - // CHECK IF IT'S THE SAME ONE AS WE'RE ON, IF SO, RETURN THAT! - if ( pSoldier->sGridNo == sGridNo ) - { - *pubDirection = pSoldier->bDirection; - return( sGridNo ); - } + // CHECK IF IT'S THE SAME ONE AS WE'RE ON, IF SO, RETURN THAT! + if ( pSoldier->sGridNo == sGridNo ) + { + *pubDirection = pSoldier->bDirection; + return( sGridNo ); + } - // Look for a door! + // Look for a door! if (fDoor) { pDoor = FindStructure( sGridNo, ( STRUCTURE_ANYDOOR | STRUCTURE_SWITCH ) ); @@ -4883,63 +4914,63 @@ INT16 FindNextToAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pub } - if ( ( sOkTest = NewOKDestination( pSoldier, sGridNo, TRUE, pSoldier->bLevel ) ) > 0) // no problem going there! nobody on it! - { - // OK, if we are looking to goto a switch, ignore this.... - if ( pDoor ) - { + if ( ( sOkTest = NewOKDestination( pSoldier, sGridNo, TRUE, pSoldier->bLevel ) ) > 0) // no problem going there! nobody on it! + { + // OK, if we are looking to goto a switch, ignore this.... + if ( pDoor ) + { if ( pDoor->fFlags & STRUCTURE_SWITCH ) { // Don't continuel fCheckGivenGridNo = FALSE; } - } + } - if ( fCheckGivenGridNo ) - { - sDistance = PlotPath( pSoldier, sGridNo, NO_COPYROUTE, NO_PLOT, TEMPORARY, (INT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints ); + if ( fCheckGivenGridNo ) + { + sDistance = PlotPath( pSoldier, sGridNo, NO_COPYROUTE, NO_PLOT, TEMPORARY, (INT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints ); - if ( sDistance > 0 ) + if ( sDistance > 0 ) { - + if ( sDistance < sClosest ) { - sClosest = sDistance; - sCloseGridNo = (INT16)sGridNo; + sClosest = sDistance; + sCloseGridNo = (INT16)sGridNo; } } - } - } + } + } - for (cnt = 0; cnt < 4; cnt++) - { - // MOVE OUT TWO DIRECTIONS - sFourGrids[cnt] = sSpot = NewGridNo( sGridNo, DirectionInc( sDirs[ cnt ] ) ); + for (cnt = 0; cnt < 4; cnt++) + { + // MOVE OUT TWO DIRECTIONS + sFourGrids[cnt] = sSpot = NewGridNo( sGridNo, DirectionInc( sDirs[ cnt ] ) ); - ubTestDirection = (UINT8)sDirs[ cnt ]; + ubTestDirection = (UINT8)sDirs[ cnt ]; - if ( pDoor && pDoor->fFlags & STRUCTURE_SWITCH ) - { + if ( pDoor && pDoor->fFlags & STRUCTURE_SWITCH ) + { ubTestDirection = gOppositeDirection[ ubTestDirection ]; - } + } - if ( gubWorldMovementCosts[ sSpot ][ ubTestDirection ][ pSoldier->bLevel ] >= TRAVELCOST_BLOCKED ) - { - // obstacle or wall there! - continue; - } + if ( gubWorldMovementCosts[ sSpot ][ ubTestDirection ][ pSoldier->bLevel ] >= TRAVELCOST_BLOCKED ) + { + // obstacle or wall there! + continue; + } - ubWhoIsThere = WhoIsThere2( sSpot, pSoldier->bLevel ); - if ( ubWhoIsThere != NOBODY && ubWhoIsThere != pSoldier->ubID ) - { - // skip this direction b/c it's blocked by another merc! - continue; - } + ubWhoIsThere = WhoIsThere2( sSpot, pSoldier->bLevel ); + if ( ubWhoIsThere != NOBODY && ubWhoIsThere != pSoldier->ubID ) + { + // skip this direction b/c it's blocked by another merc! + continue; + } - // Eliminate some directions if we are looking at doors! - if ( pDoor != NULL ) - { + // Eliminate some directions if we are looking at doors! + if ( pDoor != NULL ) + { // Get orinetation ubWallOrientation = pDoor->ubWallOrientation; @@ -4956,97 +4987,97 @@ INT16 FindNextToAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pub if ( sDirs[ cnt ] == NORTH || sDirs[ cnt ] == WEST || sDirs[ cnt ] == EAST ) continue; } - } + } - // first tile is okay, how about the second? - sSpot2 = NewGridNo( sSpot, DirectionInc( sDirs[ cnt ] ) ); - if ( gubWorldMovementCosts[ sSpot2 ][ sDirs[cnt] ][ pSoldier->bLevel ] >= TRAVELCOST_BLOCKED || - DoorTravelCost( pSoldier, sSpot2, gubWorldMovementCosts[ sSpot2 ][ sDirs[cnt] ][ pSoldier->bLevel ], (BOOLEAN) (pSoldier->bTeam == gbPlayerNum), NULL ) == TRAVELCOST_DOOR ) // closed door blocks! - { - // obstacle or wall there! - continue; - } + // first tile is okay, how about the second? + sSpot2 = NewGridNo( sSpot, DirectionInc( sDirs[ cnt ] ) ); + if ( gubWorldMovementCosts[ sSpot2 ][ sDirs[cnt] ][ pSoldier->bLevel ] >= TRAVELCOST_BLOCKED || + DoorTravelCost( pSoldier, sSpot2, gubWorldMovementCosts[ sSpot2 ][ sDirs[cnt] ][ pSoldier->bLevel ], (BOOLEAN) (pSoldier->bTeam == gbPlayerNum), NULL ) == TRAVELCOST_DOOR ) // closed door blocks! + { + // obstacle or wall there! + continue; + } - ubWhoIsThere = WhoIsThere2( sSpot2, pSoldier->bLevel ); - if ( ubWhoIsThere != NOBODY && ubWhoIsThere != pSoldier->ubID ) - { - // skip this direction b/c it's blocked by another merc! - continue; - } + ubWhoIsThere = WhoIsThere2( sSpot2, pSoldier->bLevel ); + if ( ubWhoIsThere != NOBODY && ubWhoIsThere != pSoldier->ubID ) + { + // skip this direction b/c it's blocked by another merc! + continue; + } - sSpot = sSpot2; + sSpot = sSpot2; - // If this spot is our soldier's gridno use that! - if ( sSpot == pSoldier->sGridNo ) - { - if (pubDirection) + // If this spot is our soldier's gridno use that! + if ( sSpot == pSoldier->sGridNo ) + { + if (pubDirection) { - (*pubDirection) = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier ); + (*pubDirection) = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier ); } - //*pubDirection = pSoldier->bDirection; - return( sSpot ); - } + //*pubDirection = pSoldier->bDirection; + return( sSpot ); + } - ubDir = (UINT8)GetDirectionToGridNoFromGridNo( sSpot, sGridNo ); + ubDir = (UINT8)GetDirectionToGridNoFromGridNo( sSpot, sGridNo ); - // don't store path, just measure it - if ( ( NewOKDestinationAndDirection( pSoldier, sSpot, ubDir, TRUE , pSoldier->bLevel ) > 0 ) && - ( ( sDistance = PlotPath( pSoldier, sSpot, NO_COPYROUTE, NO_PLOT, TEMPORARY, (INT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints ) ) > 0 ) ) - { - if ( sDistance < sClosest ) - { + // don't store path, just measure it + if ( ( NewOKDestinationAndDirection( pSoldier, sSpot, ubDir, TRUE , pSoldier->bLevel ) > 0 ) && + ( ( sDistance = PlotPath( pSoldier, sSpot, NO_COPYROUTE, NO_PLOT, TEMPORARY, (INT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints ) ) > 0 ) ) + { + if ( sDistance < sClosest ) + { sClosest = sDistance; sCloseGridNo = (INT16)sSpot; - } - } - } + } + } + } if (sClosest != NOWHERE) - { - // Take last direction and use opposite! - // This will be usefull for ours and AI mercs + { + // Take last direction and use opposite! + // This will be usefull for ours and AI mercs - // If our gridno is the same ( which can be if we are look at doors ) - if ( sGridNo == sCloseGridNo ) - { - if (pubDirection) + // If our gridno is the same ( which can be if we are look at doors ) + if ( sGridNo == sCloseGridNo ) + { + if (pubDirection) + { + // ATE: Only if we have a valid door! + if ( pDoor ) { - // ATE: Only if we have a valid door! - if ( pDoor ) + switch( pDoor->pDBStructureRef->pDBStructure->ubWallOrientation ) { - switch( pDoor->pDBStructureRef->pDBStructure->ubWallOrientation ) - { - case OUTSIDE_TOP_LEFT: - case INSIDE_TOP_LEFT: + case OUTSIDE_TOP_LEFT: + case INSIDE_TOP_LEFT: - *pubDirection = SOUTH; - break; + *pubDirection = SOUTH; + break; - case OUTSIDE_TOP_RIGHT: - case INSIDE_TOP_RIGHT: + case OUTSIDE_TOP_RIGHT: + case INSIDE_TOP_RIGHT: - *pubDirection = EAST; - break; - } + *pubDirection = EAST; + break; } } - } - else - { - // Calculate direction if our gridno is different.... - ubDir = (UINT8)GetDirectionToGridNoFromGridNo( sCloseGridNo, sGridNo ); - if (pubDirection) - { - *pubDirection = ubDir; - } - } + } + } + else + { + // Calculate direction if our gridno is different.... + ubDir = (UINT8)GetDirectionToGridNoFromGridNo( sCloseGridNo, sGridNo ); + if (pubDirection) + { + *pubDirection = ubDir; + } + } - if ( sCloseGridNo == NOWHERE ) - { - return( -1 ); - } - return( sCloseGridNo ); - } + if ( sCloseGridNo == NOWHERE ) + { + return( -1 ); + } + return( sCloseGridNo ); + } else return( -1 ); @@ -5054,71 +5085,71 @@ INT16 FindNextToAdjacentGridEx( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 *pub /* if (sCloseGridNo != NOWHERE) - { - // Take last direction and use opposite! - // This will be usefull for ours and AI mercs + { + // Take last direction and use opposite! + // This will be usefull for ours and AI mercs - // If our gridno is the same ( which can be if we are look at doors ) - if ( sGridNo == sCloseGridNo ) - { - switch( pDoor->pDBStructureRef->pDBStructure->ubWallOrientation ) - { - case OUTSIDE_TOP_LEFT: - case INSIDE_TOP_LEFT: + // If our gridno is the same ( which can be if we are look at doors ) + if ( sGridNo == sCloseGridNo ) + { + switch( pDoor->pDBStructureRef->pDBStructure->ubWallOrientation ) + { + case OUTSIDE_TOP_LEFT: + case INSIDE_TOP_LEFT: - *pubDirection = SOUTH; - break; + *pubDirection = SOUTH; + break; - case OUTSIDE_TOP_RIGHT: - case INSIDE_TOP_RIGHT: + case OUTSIDE_TOP_RIGHT: + case INSIDE_TOP_RIGHT: - *pubDirection = EAST; - break; - } - } - else - { - // Calculate direction if our gridno is different.... - ubDir = (UINT8)GetDirectionToGridNoFromGridNo( sCloseGridNo, sGridNo ); - *pubDirection = ubDir; - } - return( sCloseGridNo ); - } + *pubDirection = EAST; + break; + } + } else - return( -1 ); + { + // Calculate direction if our gridno is different.... + ubDir = (UINT8)GetDirectionToGridNoFromGridNo( sCloseGridNo, sGridNo ); + *pubDirection = ubDir; + } + return( sCloseGridNo ); + } + else + return( -1 ); */ } INT16 FindAdjacentPunchTarget( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTargetSoldier, INT16 * psAdjustedTargetGridNo, UINT8 * pubDirection ) { - INT16 cnt; - INT16 sSpot; - UINT8 ubGuyThere; + INT16 cnt; + INT16 sSpot; + UINT8 ubGuyThere; - for ( cnt = 0; cnt < NUM_WORLD_DIRECTIONS; cnt++ ) - { - sSpot = (INT16)NewGridNo( pSoldier->sGridNo, DirectionInc( cnt ) ); + for ( cnt = 0; cnt < NUM_WORLD_DIRECTIONS; cnt++ ) + { + sSpot = (INT16)NewGridNo( pSoldier->sGridNo, DirectionInc( cnt ) ); - if ( DoorTravelCost( pSoldier, sSpot, gubWorldMovementCosts[ sSpot ][ cnt ][ pSoldier->bLevel ], FALSE, NULL ) >= TRAVELCOST_BLOCKED ) - { - // blocked! - continue; - } + if ( DoorTravelCost( pSoldier, sSpot, gubWorldMovementCosts[ sSpot ][ cnt ][ pSoldier->bLevel ], FALSE, NULL ) >= TRAVELCOST_BLOCKED ) + { + // blocked! + continue; + } - // Check for who is there... - ubGuyThere = WhoIsThere2( sSpot, pSoldier->bLevel ); + // Check for who is there... + ubGuyThere = WhoIsThere2( sSpot, pSoldier->bLevel ); - if ( pTargetSoldier != NULL && ubGuyThere == pTargetSoldier->ubID ) - { - // We've got a guy here.... - // Who is the one we want...... - *psAdjustedTargetGridNo = pTargetSoldier->sGridNo; - *pubDirection = ( UINT8 )cnt; - return( sSpot ); - } - } + if ( pTargetSoldier != NULL && ubGuyThere == pTargetSoldier->ubID ) + { + // We've got a guy here.... + // Who is the one we want...... + *psAdjustedTargetGridNo = pTargetSoldier->sGridNo; + *pubDirection = ( UINT8 )cnt; + return( sSpot ); + } + } - return( NOWHERE ); + return( NOWHERE ); } @@ -5170,7 +5201,7 @@ void HandleTeamServices( UINT8 ubTeamNum ) UINT32 uiPointsUsed; UINT16 usSoldierIndex, usInHand; UINT16 usKitPts; - INT8 bSlot; + INT8 bSlot; BOOLEAN fDone; // IF IT'S THE SELECTED GUY, MAKE ANOTHER SELECTED! @@ -5205,7 +5236,7 @@ void HandleTeamServices( UINT8 ubTeamNum ) if ( !pTargetSoldier->bBleeding && pTargetSoldier->bLife >= OKLIFE ) { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ MERC_IS_ALL_BANDAGED_STR ], pTargetSoldier->name ); - + // Cancel all services for this guy! ReceivingSoldierCancelServices( pTargetSoldier ); fDone = TRUE; @@ -5237,7 +5268,7 @@ void HandleTeamServices( UINT8 ubTeamNum ) SwapObjs( &(pTeamSoldier->inv[HANDPOS]), &(pTeamSoldier->inv[bSlot] ) ); } else - { + { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ MERC_IS_OUT_OF_BANDAGES_STR ], pTeamSoldier->name ); GivingSoldierCancelServices( pTeamSoldier ); @@ -5246,7 +5277,7 @@ void HandleTeamServices( UINT8 ubTeamNum ) DoMercBattleSound( pTeamSoldier, (INT8)( BATTLE_SOUND_CURSE1 ) ); } - } + } } } } @@ -5291,7 +5322,7 @@ void HandlePlayerServices( SOLDIERTYPE *pTeamSoldier ) if ( !pTargetSoldier->bBleeding && pTargetSoldier->bLife >= OKLIFE ) { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ MERC_IS_ALL_BANDAGED_STR ], pTargetSoldier->name ); - + // Cancel all services for this guy! ReceivingSoldierCancelServices( pTargetSoldier ); fDone = TRUE; @@ -5324,7 +5355,7 @@ void HandlePlayerServices( SOLDIERTYPE *pTeamSoldier ) SwapObjs( &(pTeamSoldier->inv[HANDPOS]), &(pTeamSoldier->inv[bSlot] ) ); } else - { + { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ MERC_IS_OUT_OF_BANDAGES_STR ], pTeamSoldier->name ); GivingSoldierCancelServices( pTeamSoldier ); @@ -5332,7 +5363,7 @@ void HandlePlayerServices( SOLDIERTYPE *pTeamSoldier ) { DoMercBattleSound( pTeamSoldier, (INT8)( BATTLE_SOUND_CURSE1 ) ); } - } + } } } } @@ -5355,7 +5386,7 @@ void CommonEnterCombatModeCode( ) gTacticalStatus.ubLastBattleSectorX = (UINT8) gWorldSectorX; gTacticalStatus.ubLastBattleSectorY = (UINT8) gWorldSectorY; gTacticalStatus.fLastBattleWon = FALSE; - gTacticalStatus.fItemsSeenOnAttack = FALSE; + gTacticalStatus.fItemsSeenOnAttack = FALSE; // ATE: If we have an item pointer end it! @@ -5375,7 +5406,7 @@ void CommonEnterCombatModeCode( ) // Set some flags for quotes pSoldier->usQuoteSaidFlags &= (~SOLDIER_QUOTE_SAID_IN_SHIT ); pSoldier->usQuoteSaidFlags &= (~SOLDIER_QUOTE_SAID_MULTIPLE_CREATURES); - + // Hault! EVENT_StopMerc( pSoldier, pSoldier->sGridNo, pSoldier->bDirection ); @@ -5396,6 +5427,10 @@ void CommonEnterCombatModeCode( ) // ATE: Refresh APs CalcNewActionPoints( pSoldier ); + // Either I just noticed this, or it just hasn't been a problem before. But + // if the last battle left a soldier at 0 points, he will not gain full points with + // carryover for this battle. So we'll hit it again. + CalcNewActionPoints( pSoldier ); if ( pSoldier->ubProfile != NO_PROFILE ) { @@ -5413,20 +5448,20 @@ void CommonEnterCombatModeCode( ) } } - if ( !gTacticalStatus.fHasEnteredCombatModeSinceEntering ) - { - // ATE: reset player's movement mode at the very start of - // combat - //if ( pSoldier->bTeam == gbPlayerNum ) - //{ - //pSoldier->usUIMovementMode = RUNNING; - //} - } + if ( !gTacticalStatus.fHasEnteredCombatModeSinceEntering ) + { + // ATE: reset player's movement mode at the very start of + // combat + //if ( pSoldier->bTeam == gbPlayerNum ) + //{ + //pSoldier->usUIMovementMode = RUNNING; + //} + } } } } - gTacticalStatus.fHasEnteredCombatModeSinceEntering = TRUE; + gTacticalStatus.fHasEnteredCombatModeSinceEntering = TRUE; SyncStrategicTurnTimes( ); @@ -5437,7 +5472,7 @@ void CommonEnterCombatModeCode( ) // Change music modes SetMusicMode( MUSIC_TACTICAL_BATTLE ); - + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CommonEnterCombatMode done"); } @@ -5466,18 +5501,18 @@ void EnterCombatMode( UINT8 ubStartingTeam ) DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Entering combat mode" ); - // ATE: Added here to guarentee we have fEnemyInSector - // Mostly this was not getting set if: - // 1 ) we see bloodcats ( which makes them hostile ) - // 2 ) we make civs hostile - // only do this once they are seen..... - if ( !gTacticalStatus.fEnemyInSector ) - { + // ATE: Added here to guarentee we have fEnemyInSector + // Mostly this was not getting set if: + // 1 ) we see bloodcats ( which makes them hostile ) + // 2 ) we make civs hostile + // only do this once they are seen..... + if ( !gTacticalStatus.fEnemyInSector ) + { SetEnemyPresence( ); - } + } CommonEnterCombatModeCode( ); - + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"EnterCombatMode continuing..."); if (ubStartingTeam == gbPlayerNum) @@ -5506,7 +5541,7 @@ void EnterCombatMode( UINT8 ubStartingTeam ) else { DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"EnterCombatMode continuing... end turn"); - // have to call EndTurn so that we freeze the interface etc + // have to call EndTurn so that we freeze the interface etc EndTurn( ubStartingTeam ); } @@ -5610,7 +5645,7 @@ void SetEnemyPresence( ) ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ ENEMY_IN_SECTOR_STR ] ); // Change music modes.. - + // If we are just starting game, don't do this! if ( !DidGameJustStart() && !AreInMeanwhile( ) ) { @@ -5618,19 +5653,19 @@ void SetEnemyPresence( ) DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("SetEnemyPresence: warnings = false")); sniperwarning = FALSE; biggunwarning = FALSE; -// airstrikeavailable = TRUE; + // airstrikeavailable = TRUE; } else { DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("SetEnemyPresence: warnings = true")); sniperwarning = TRUE; biggunwarning = TRUE; -// airstrikeavailable = FALSE; + // airstrikeavailable = FALSE; } // Say quote... //SayQuoteFromAnyBodyInSector( QUOTE_ENEMY_PRESENCE ); - + gTacticalStatus.fEnemyInSector = TRUE; } @@ -5644,10 +5679,10 @@ BOOLEAN SoldierHasSeenEnemiesLastFewTurns( SOLDIERTYPE *pTeamSoldier ) INT32 cnt2; SOLDIERTYPE *pSoldier; INT32 cnt; - + for ( cnt = 0; cnt < MAXTEAMS; cnt++ ) { - + if ( gTacticalStatus.Team[ cnt ].bSide != pTeamSoldier->bSide ) { @@ -5661,7 +5696,7 @@ BOOLEAN SoldierHasSeenEnemiesLastFewTurns( SOLDIERTYPE *pTeamSoldier ) { // Have we not seen this guy..... if ( ( pTeamSoldier->bOppList[ cnt2 ] >= SEEN_CURRENTLY ) && - ( pTeamSoldier->bOppList[ cnt2 ] <= SEEN_THIS_TURN ) ) + ( pTeamSoldier->bOppList[ cnt2 ] <= SEEN_THIS_TURN ) ) { gTacticalStatus.bConsNumTurnsNotSeen = 0; return( TRUE ); @@ -5819,7 +5854,7 @@ BOOLEAN CheckForEndOfCombatMode( BOOLEAN fIncrementTurnsNotSeen ) { // we have to loop through EVERYONE to see if anyone sees a hostile... if so, stay in turnbased... - + for ( cnt = 0; cnt < guiNumMercSlots; cnt++ ) { pTeamSoldier = MercSlots[ cnt ]; @@ -5851,7 +5886,7 @@ BOOLEAN CheckForEndOfCombatMode( BOOLEAN fIncrementTurnsNotSeen ) } return( FALSE ); } - + // IF here, we don;t see anybody.... increment count for end check if( fIncrementTurnsNotSeen ) { @@ -5888,34 +5923,34 @@ BOOLEAN CheckForEndOfCombatMode( BOOLEAN fIncrementTurnsNotSeen ) fSayQuote = TRUE; } - // ATE: Are there creatures here? If so, say another quote... - if ( fSayQuote && ( gTacticalStatus.uiFlags & IN_CREATURE_LAIR ) ) - { + // ATE: Are there creatures here? If so, say another quote... + if ( fSayQuote && ( gTacticalStatus.uiFlags & IN_CREATURE_LAIR ) ) + { SayQuoteFromAnyBodyInSector( QUOTE_WORRIED_ABOUT_CREATURE_PRESENCE ); - } - // Are we fighting bloodcats? - else if ( NumBloodcatsInSectorNotDeadOrDying( ) > 0 ) - { + } + // Are we fighting bloodcats? + else if ( NumBloodcatsInSectorNotDeadOrDying( ) > 0 ) + { - } - else - { - if ( fSayQuote ) - { - // Double check by seeing if we have any active enemies in sector! - if ( NumEnemyInSectorNotDeadOrDying( ) > 0 ) - { - SayQuoteFromAnyBodyInSector( QUOTE_WARNING_OUTSTANDING_ENEMY_AFTER_RT ); - } - } - } -/* + } + else + { + if ( fSayQuote ) + { + // Double check by seeing if we have any active enemies in sector! + if ( NumEnemyInSectorNotDeadOrDying( ) > 0 ) + { + SayQuoteFromAnyBodyInSector( QUOTE_WARNING_OUTSTANDING_ENEMY_AFTER_RT ); + } + } + } + /* if ( (!fWeSeeNoOne || !fNobodyAlerted) && WeSawSomeoneThisTurn() ) { - // Say quote to the effect that the battle has lulled - SayQuoteFromAnyBodyInSector( QUOTE_WARNING_OUTSTANDING_ENEMY_AFTER_RT ); + // Say quote to the effect that the battle has lulled + SayQuoteFromAnyBodyInSector( QUOTE_WARNING_OUTSTANDING_ENEMY_AFTER_RT ); } -*/ + */ // Begin tense music.... gfForceMusicToTense = TRUE; @@ -5930,7 +5965,7 @@ BOOLEAN CheckForEndOfCombatMode( BOOLEAN fIncrementTurnsNotSeen ) void DeathNoMessageTimerCallback( void ) { - CheckAndHandleUnloadingOfCurrentWorld(); + CheckAndHandleUnloadingOfCurrentWorld(); } void RemoveStaticEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY ) @@ -6017,12 +6052,12 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) if ( fBattleLost ) { - // CJC: End AI's turn here.... first... so that UnSetUIBusy will succeed if militia win + // CJC: End AI's turn here.... first... so that UnSetUIBusy will succeed if militia win // battle for us EndAllAITurns( ); // Set enemy presence to false - // This is safe 'cause we're about to unload the friggen sector anyway.... + // This is safe 'cause we're about to unload the friggen sector anyway.... gTacticalStatus.fEnemyInSector = FALSE; // If here, the battle has been lost! @@ -6071,7 +6106,7 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) if ( gTacticalStatus.bBoxingState == NOT_BOXING ) // if boxing don't do any of this stuff { - gTacticalStatus.fLastBattleWon = TRUE; + gTacticalStatus.fLastBattleWon = TRUE; // OK, KILL any enemies that are incompacitated if ( KillIncompacitatedEnemyInSector( ) ) @@ -6082,7 +6117,7 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) // Kill all enemies. Sometime even after killing all the enemies, there appeares "in battle" enemies in sector info RemoveStaticEnemiesFromSectorInfo( gWorldSectorX, gWorldSectorY ); - + // If here, the battle has been won! // hurray! a glorious victory! @@ -6113,7 +6148,7 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) // Only do some stuff if we actually faught a battle if ( gTacticalStatus.bNumFoughtInBattle[ ENEMY_TEAM ] + gTacticalStatus.bNumFoughtInBattle[ CREATURE_TEAM ] + gTacticalStatus.bNumFoughtInBattle[ CIV_TEAM ] > 0 ) - //if ( gTacticalStatus.bNumEnemiesFoughtInBattle > 0 ) + //if ( gTacticalStatus.bNumEnemiesFoughtInBattle > 0 ) { // Loop through all mercs and make go for ( pTeamSoldier = MercPtrs[ gTacticalStatus.Team[ gbPlayerNum ].bFirstID ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pTeamSoldier++) @@ -6131,15 +6166,15 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) { if ( pTeamSoldier->bAssignment < ON_DUTY ) { - // Reset some quote flags.... - pTeamSoldier->usQuoteSaidExtFlags &= (~SOLDIER_QUOTE_SAID_BUDDY_1_WITNESSED); - pTeamSoldier->usQuoteSaidExtFlags &= (~SOLDIER_QUOTE_SAID_BUDDY_2_WITNESSED); - pTeamSoldier->usQuoteSaidExtFlags &= (~SOLDIER_QUOTE_SAID_BUDDY_3_WITNESSED); + // Reset some quote flags.... + pTeamSoldier->usQuoteSaidExtFlags &= (~SOLDIER_QUOTE_SAID_BUDDY_1_WITNESSED); + pTeamSoldier->usQuoteSaidExtFlags &= (~SOLDIER_QUOTE_SAID_BUDDY_2_WITNESSED); + pTeamSoldier->usQuoteSaidExtFlags &= (~SOLDIER_QUOTE_SAID_BUDDY_3_WITNESSED); - // toggle stealth mode.... - gfUIStanceDifferent = TRUE; - pTeamSoldier->bStealthMode = FALSE; - fInterfacePanelDirty = DIRTYLEVEL2; + // toggle stealth mode.... + gfUIStanceDifferent = TRUE; + pTeamSoldier->bStealthMode = FALSE; + fInterfacePanelDirty = DIRTYLEVEL2; if ( gAnimControl[ pTeamSoldier->usAnimState ].ubHeight != ANIM_STAND ) { @@ -6166,16 +6201,16 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_BATTLE_WON, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); // Change music modes - if ( gfLastMercTalkedAboutKillingID == NOBODY || ( gfLastMercTalkedAboutKillingID != NOBODY && !( MercPtrs[ gfLastMercTalkedAboutKillingID ]->uiStatusFlags & SOLDIER_MONSTER ) ) ) - { - SetMusicMode( MUSIC_TACTICAL_VICTORY ); + if ( gfLastMercTalkedAboutKillingID == NOBODY || ( gfLastMercTalkedAboutKillingID != NOBODY && !( MercPtrs[ gfLastMercTalkedAboutKillingID ]->uiStatusFlags & SOLDIER_MONSTER ) ) ) + { + SetMusicMode( MUSIC_TACTICAL_VICTORY ); - ShouldBeginAutoBandage( ); - } - else if ( gfLastMercTalkedAboutKillingID != NOBODY && ( MercPtrs[ gfLastMercTalkedAboutKillingID ]->uiStatusFlags & SOLDIER_MONSTER ) ) - { - ShouldBeginAutoBandage( ); - } + ShouldBeginAutoBandage( ); + } + else if ( gfLastMercTalkedAboutKillingID != NOBODY && ( MercPtrs[ gfLastMercTalkedAboutKillingID ]->uiStatusFlags & SOLDIER_MONSTER ) ) + { + ShouldBeginAutoBandage( ); + } // Say battle end quote.... @@ -6193,10 +6228,10 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) } else if ( gfLastMercTalkedAboutKillingID != NOBODY && ( MercPtrs[ gfLastMercTalkedAboutKillingID ]->ubBodyType == BLOODCAT ) ) { - SayBattleSoundFromAnyBodyInSector( BATTLE_SOUND_COOL1 ); - } - else - { + SayBattleSoundFromAnyBodyInSector( BATTLE_SOUND_COOL1 ); + } + else + { SayQuoteFromAnyBodyInSector( QUOTE_SECTOR_SAFE ); } } @@ -6206,7 +6241,7 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) { // Change to nothing music... SetMusicMode( MUSIC_TACTICAL_NOTHING ); - ShouldBeginAutoBandage(); + ShouldBeginAutoBandage(); } HandleMilitiaStatusInCurrentMapBeforeLoadingNewMap(); @@ -6255,7 +6290,7 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) if ( gTacticalStatus.bBoxingState == NOT_BOXING ) // if boxing don't do any of this stuff { LogBattleResults( LOG_VICTORY ); - + SetThisSectorAsPlayerControlled( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, TRUE ); HandleVictoryInNPCSector( gWorldSectorX, gWorldSectorY,( INT16 ) gbWorldSectorZ ); if ( CheckFact( FACT_FIRST_BATTLE_BEING_FOUGHT, 0 ) ) @@ -6566,24 +6601,24 @@ UINT8 NumBloodcatsInSectorNotDeadOrDying( ) // Kill those not already dead.,... if ( pTeamSoldier->bActive && pTeamSoldier->bInSector ) { - if ( pTeamSoldier->ubBodyType == BLOODCAT ) - { - // For sure for flag thet they are dead is not set - if ( !( pTeamSoldier->uiStatusFlags & SOLDIER_DEAD ) ) - { - // Also, we want to pick up unconcious guys as NOT being capable, - // but we want to make sure we don't get those ones that are in the - // process of dying - if ( pTeamSoldier->bLife >= OKLIFE ) - { - // Check for any more badguys - if ( !pTeamSoldier->bNeutral && (pTeamSoldier->bSide != 0 ) ) - { - ubNumEnemies++; - } - } - } - } + if ( pTeamSoldier->ubBodyType == BLOODCAT ) + { + // For sure for flag thet they are dead is not set + if ( !( pTeamSoldier->uiStatusFlags & SOLDIER_DEAD ) ) + { + // Also, we want to pick up unconcious guys as NOT being capable, + // but we want to make sure we don't get those ones that are in the + // process of dying + if ( pTeamSoldier->bLife >= OKLIFE ) + { + // Check for any more badguys + if ( !pTeamSoldier->bNeutral && (pTeamSoldier->bSide != 0 ) ) + { + ubNumEnemies++; + } + } + } + } } } @@ -6640,22 +6675,22 @@ BOOLEAN CheckForLosingEndOfBattle( ) INT8 bNumDead = 0, bNumNotOK = 0, bNumInBattle = 0, bNumNotOKRealMercs = 0; BOOLEAN fMadeCorpse; BOOLEAN fDoCapture = FALSE; - BOOLEAN fOnlyEPCsLeft = TRUE; - BOOLEAN fMilitiaInSector = FALSE; + BOOLEAN fOnlyEPCsLeft = TRUE; + BOOLEAN fMilitiaInSector = FALSE; - // ATE: Check for MILITIA - we won't lose if we have some..... + // ATE: Check for MILITIA - we won't lose if we have some..... cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; cnt++,pTeamSoldier++) { if ( pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->bSide == gbPlayerNum ) { if ( pTeamSoldier->bLife >= OKLIFE ) - { - // We have at least one poor guy who will still fight.... - // we have not lost ( yet )! - fMilitiaInSector = TRUE; - } + { + // We have at least one poor guy who will still fight.... + // we have not lost ( yet )! + fMilitiaInSector = TRUE; + } } } @@ -6679,43 +6714,43 @@ BOOLEAN CheckForLosingEndOfBattle( ) { bNumNotOK++; - if ( !AM_AN_EPC( pTeamSoldier ) && !AM_A_ROBOT( pTeamSoldier ) ) - { - bNumNotOKRealMercs++; - } + if ( !AM_AN_EPC( pTeamSoldier ) && !AM_A_ROBOT( pTeamSoldier ) ) + { + bNumNotOKRealMercs++; + } + } + else + { + if ( !AM_A_ROBOT( pTeamSoldier ) || !AM_AN_EPC( pTeamSoldier ) ) + { + fOnlyEPCsLeft = FALSE; + } } - else - { - if ( !AM_A_ROBOT( pTeamSoldier ) || !AM_AN_EPC( pTeamSoldier ) ) - { - fOnlyEPCsLeft = FALSE; - } - } } } // OK< check ALL in battle, if that matches SUM of dead, incompacitated, we're done! if ( ( bNumDead + bNumNotOK ) == bNumInBattle || fOnlyEPCsLeft ) - { - // Are there militia in sector? - if ( fMilitiaInSector ) - { - if( guiCurrentScreen != AUTORESOLVE_SCREEN ) - { - // if here, check if we should autoresolve. - // if we have at least one guy unconscious, call below function... - if ( HandlePotentialBringUpAutoresolveToFinishBattle( ) ) - { - // return false here as we are autoresolving... - return( FALSE ); - } - } - else - { - return( FALSE ); - } - } + { + // Are there militia in sector? + if ( fMilitiaInSector ) + { + if( guiCurrentScreen != AUTORESOLVE_SCREEN ) + { + // if here, check if we should autoresolve. + // if we have at least one guy unconscious, call below function... + if ( HandlePotentialBringUpAutoresolveToFinishBattle( ) ) + { + // return false here as we are autoresolving... + return( FALSE ); + } + } + else + { + return( FALSE ); + } + } // Bring up box if we have ANY guy incompaciteded..... @@ -6727,19 +6762,19 @@ BOOLEAN CheckForLosingEndOfBattle( ) // Check if we should get captured.... if ( bNumNotOKRealMercs < 4 && bNumNotOKRealMercs > 1 ) { - // Check if any enemies exist.... - if ( gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector > 0 ) - { - //if( GetWorldDay() > STARTDAY_ALLOW_PLAYER_CAPTURE_FOR_RESCUE && !( gStrategicStatus.uiFlags & STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE )) - { - if ( gubQuest[ QUEST_HELD_IN_ALMA ] == QUESTNOTSTARTED || ( gubQuest[ QUEST_HELD_IN_ALMA ] == QUESTDONE && gubQuest[ QUEST_INTERROGATION ] == QUESTNOTSTARTED ) ) - { - fDoCapture = TRUE; + // Check if any enemies exist.... + if ( gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector > 0 ) + { + //if( GetWorldDay() > STARTDAY_ALLOW_PLAYER_CAPTURE_FOR_RESCUE && !( gStrategicStatus.uiFlags & STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE )) + { + if ( gubQuest[ QUEST_HELD_IN_ALMA ] == QUESTNOTSTARTED || ( gubQuest[ QUEST_HELD_IN_ALMA ] == QUESTDONE && gubQuest[ QUEST_INTERROGATION ] == QUESTNOTSTARTED ) ) + { + fDoCapture = TRUE; // CJC Dec 1 2002: fix capture sequences BeginCaptureSquence(); - } - } - } + } + } + } } gfKillingGuysForLosingBattle = TRUE; @@ -6755,7 +6790,7 @@ BOOLEAN CheckForLosingEndOfBattle( ) { if ( pTeamSoldier->bLife != 0 && pTeamSoldier->bLife < OKLIFE || AM_AN_EPC( pTeamSoldier ) || AM_A_ROBOT( pTeamSoldier ) ) { - // Captured EPCs or ROBOTS will be kiiled in capture routine.... + // Captured EPCs or ROBOTS will be kiiled in capture routine.... if ( !fDoCapture ) { // Kill! @@ -6769,8 +6804,8 @@ BOOLEAN CheckForLosingEndOfBattle( ) } } - // ATE: if we are told to do capture.... - if ( pTeamSoldier->bLife != 0 && fDoCapture ) + // ATE: if we are told to do capture.... + if ( pTeamSoldier->bLife != 0 && fDoCapture ) { EnemyCapturesPlayerSoldier( pTeamSoldier ); @@ -6868,20 +6903,20 @@ INT8 CalcSuppressionTolerance( SOLDIERTYPE * pSoldier ) // give +2 for every morale category from normal, for a max change of 4 bTolerance += ( pSoldier->bAIMorale - MORALE_NORMAL ) * 2; } - + if ( pSoldier->ubProfile != NO_PROFILE ) { // change tolerance based on attitude switch ( gMercProfiles[ pSoldier->ubProfile ].bAttitude ) { - case ATT_AGGRESSIVE: - bTolerance += 2; - break; - case ATT_COWARD: - bTolerance += -2; - break; - default: - break; + case ATT_AGGRESSIVE: + bTolerance += 2; + break; + case ATT_COWARD: + bTolerance += -2; + break; + default: + break; } } else @@ -6889,18 +6924,18 @@ INT8 CalcSuppressionTolerance( SOLDIERTYPE * pSoldier ) // generic NPC/civvie; change tolerance based on attitude switch ( pSoldier->bAttitude ) { - case BRAVESOLO: - case BRAVEAID: - bTolerance += 2; - break; - case AGGRESSIVE: - bTolerance += 1; - break; - case DEFENSIVE: - bTolerance += -1; - break; - default: - break; + case BRAVESOLO: + case BRAVEAID: + bTolerance += 2; + break; + case AGGRESSIVE: + bTolerance += 1; + break; + case DEFENSIVE: + bTolerance += -1; + break; + default: + break; } } @@ -6949,7 +6984,7 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) // default: // break; //} - + // cap the # of APs we can lose if (ubPointsLost > MAX_APS_SUPPRESSED) { @@ -6984,64 +7019,64 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) // merc gets to use APs to react! switch (gAnimControl[ pSoldier->usAnimState ].ubEndHeight) { - case ANIM_PRONE: - // can't change stance below prone! - break; - case ANIM_CROUCH: - if (ubTotalPointsLost >= AP_PRONE && IsValidStance( pSoldier, ANIM_PRONE ) ) + case ANIM_PRONE: + // can't change stance below prone! + break; + case ANIM_CROUCH: + if (ubTotalPointsLost >= AP_PRONE && IsValidStance( pSoldier, ANIM_PRONE ) ) + { + sClosestOpponent = ClosestKnownOpponent( pSoldier, &sClosestOppLoc, NULL ); + if (sClosestOpponent == NOWHERE || SpacesAway( pSoldier->sGridNo, sClosestOppLoc ) > 8) { - sClosestOpponent = ClosestKnownOpponent( pSoldier, &sClosestOppLoc, NULL ); - if (sClosestOpponent == NOWHERE || SpacesAway( pSoldier->sGridNo, sClosestOppLoc ) > 8) + if (ubPointsLost < AP_PRONE) { - if (ubPointsLost < AP_PRONE) - { - // Have to give APs back so that we can change stance without - // losing more APs - pSoldier->bActionPoints += (AP_PRONE - ubPointsLost); - ubPointsLost = 0; - } - else - { - ubPointsLost -= AP_PRONE; - } + // Have to give APs back so that we can change stance without + // losing more APs + pSoldier->bActionPoints += (AP_PRONE - ubPointsLost); + ubPointsLost = 0; + } + else + { + ubPointsLost -= AP_PRONE; + } + ubNewStance = ANIM_PRONE; + } + } + break; + default: // standing! + if (pSoldier->bOverTerrainType == LOW_WATER || pSoldier->bOverTerrainType == DEEP_WATER) + { + // can't change stance here! + break; + } + else if (ubTotalPointsLost >= (AP_CROUCH + AP_PRONE) && ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_PRONE ) && IsValidStance( pSoldier, ANIM_PRONE ) ) + { + sClosestOpponent = ClosestKnownOpponent( pSoldier, &sClosestOppLoc, NULL ); + if ( sClosestOpponent == NOWHERE || SpacesAway( pSoldier->sGridNo, sClosestOppLoc ) > 8 ) + { + if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND ) + { + // can only crouch for now + ubNewStance = ANIM_CROUCH; + } + else + { + // lie prone! ubNewStance = ANIM_PRONE; } } - break; - default: // standing! - if (pSoldier->bOverTerrainType == LOW_WATER || pSoldier->bOverTerrainType == DEEP_WATER) + else if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND && IsValidStance( pSoldier, ANIM_CROUCH ) ) { - // can't change stance here! - break; - } - else if (ubTotalPointsLost >= (AP_CROUCH + AP_PRONE) && ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_PRONE ) && IsValidStance( pSoldier, ANIM_PRONE ) ) - { - sClosestOpponent = ClosestKnownOpponent( pSoldier, &sClosestOppLoc, NULL ); - if ( sClosestOpponent == NOWHERE || SpacesAway( pSoldier->sGridNo, sClosestOppLoc ) > 8 ) - { - if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND ) - { - // can only crouch for now - ubNewStance = ANIM_CROUCH; - } - else - { - // lie prone! - ubNewStance = ANIM_PRONE; - } - } - else if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND && IsValidStance( pSoldier, ANIM_CROUCH ) ) - { - // crouch, at least! - ubNewStance = ANIM_CROUCH; - } - } - else if ( ubTotalPointsLost >= AP_CROUCH && ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_CROUCH ) && IsValidStance( pSoldier, ANIM_CROUCH ) ) - { - // crouch! + // crouch, at least! ubNewStance = ANIM_CROUCH; } - break; + } + else if ( ubTotalPointsLost >= AP_CROUCH && ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_CROUCH ) && IsValidStance( pSoldier, ANIM_CROUCH ) ) + { + // crouch! + ubNewStance = ANIM_CROUCH; + } + break; } } @@ -7076,22 +7111,22 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) if ((gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT)) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting suppression, on %d", pSoldier->ubID ) ); + DebugAttackBusy( String("!!!!!!! Starting suppression, on %d\n", pSoldier->ubID ) ); + //gTacticalStatus.ubAttackBusyCount++; - gTacticalStatus.ubAttackBusyCount++; - - // make sure supressor ID is the same! - pSoldier->ubSuppressorID = ubCausedAttacker; + // make sure supressor ID is the same! + pSoldier->ubSuppressorID = ubCausedAttacker; } - pSoldier->fChangingStanceDueToSuppression = TRUE; - pSoldier->fDontChargeAPsForStanceChange = TRUE; // AI people will have to have their actions cancelled if (!(pSoldier->uiStatusFlags & SOLDIER_PC)) { CancelAIAction( pSoldier, TRUE ); +#if 0 pSoldier->bAction = AI_ACTION_CHANGE_STANCE; pSoldier->usActionData = ubNewStance; pSoldier->bActionInProgress = TRUE; +#endif } // go for it! @@ -7100,9 +7135,14 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) // ATE: Turn off non-interrupt flag ( this NEEDS to be done! ) pSoldier->fInNonintAnim = FALSE; pSoldier->fRTInNonintAnim = FALSE; + gTacticalStatus.ubAttackBusyCount++; + DebugAttackBusy( String( "Attack busy %d due to suppression fire on %d\n", gTacticalStatus.ubAttackBusyCount, pSoldier->ubID )); DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("HandleSuppressionFire: change stance")); ChangeSoldierStance( pSoldier, ubNewStance ); + + pSoldier->fChangingStanceDueToSuppression = TRUE; + pSoldier->fDontChargeAPsForStanceChange = TRUE; } } // end of examining one soldier @@ -7150,7 +7190,7 @@ BOOLEAN ProcessImplicationsOfPCAttack( SOLDIERTYPE * pSoldier, SOLDIERTYPE ** pp SetSoldierNeutral( pTarget ); } } - + } } @@ -7184,8 +7224,8 @@ BOOLEAN ProcessImplicationsOfPCAttack( SOLDIERTYPE * pSoldier, SOLDIERTYPE ** pp { //Kaiden: Added to keep Militia from going Hostile if you attack a Crow or Cow with an explosive. if ( (pTarget->ubBodyType != CROW) && (pTarget->ubBodyType != COW) ) - // militia, if any, turn hostile - MilitiaChangesSides(); + // militia, if any, turn hostile + MilitiaChangesSides(); } } } @@ -7213,7 +7253,7 @@ BOOLEAN ProcessImplicationsOfPCAttack( SOLDIERTYPE * pSoldier, SOLDIERTYPE ** pp // change sides individually or all together CivilianGroupMemberChangesSides( pTarget ); - + if (pTarget->ubProfile != NO_PROFILE && pTarget->bLife >= OKLIFE && pTarget->bVisible == TRUE) { // trigger quote! @@ -7246,7 +7286,7 @@ BOOLEAN ProcessImplicationsOfPCAttack( SOLDIERTYPE * pSoldier, SOLDIERTYPE ** pp // Do we have a gun in a\hand? if ( Item[ pTarget->inv[ HANDPOS ].usItem ].usItemClass == IC_GUN ) { - // Toggle burst capable... + // Toggle burst capable... if ( !pTarget->bDoBurst ) { if ( IsGunBurstCapable( pTarget, HANDPOS , FALSE ) ) @@ -7277,7 +7317,7 @@ BOOLEAN ProcessImplicationsOfPCAttack( SOLDIERTYPE * pSoldier, SOLDIERTYPE ** pp return( fEnterCombat ); } -SOLDIERTYPE *InternalReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacker, UINT8 ubTargetID ) +SOLDIERTYPE *InternalReduceAttackBusyCount( ) { // Strange as this may seem, this function returns a pointer to // the *target* in case the target has changed sides as a result @@ -7285,7 +7325,11 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacke SOLDIERTYPE * pSoldier; SOLDIERTYPE * pTarget; BOOLEAN fEnterCombat = FALSE; + UINT32 cnt; + UINT8 ubID; +#if 0 +// 0verhaul: None of this is necessary anymore with the new attack busy system if (ubID == NOBODY) { pSoldier = NULL; @@ -7315,6 +7359,7 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacke } } } +#endif // if ((gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT)) // { @@ -7326,9 +7371,10 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacke if ( (gTacticalStatus.uiFlags & INCOMBAT) ) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! &&&&&&& Problem with attacker busy count decrementing past 0.... preventing wrap-around." ) ); - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Attack busy problem. Save, exit and send debug.txt + save file to Sir-Tech." ); - #endif +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Attack busy problem. Save, exit and send debug.txt + save file to Sir-Tech." ); + DebugAttackBusy( "Attack Busy Problem\n"); +#endif } } else @@ -7336,27 +7382,72 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacke gTacticalStatus.ubAttackBusyCount--; } + DebugAttackBusy( String( "New attack busy %d\n", gTacticalStatus.ubAttackBusyCount)); + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Ending attack, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); -// } + // } if (gTacticalStatus.ubAttackBusyCount > 0) { - return( pTarget ); + return( NULL ); + } + + // I'm going to go out on limb here and decide that from this point on we really care about the current soldier who + // started this chain of events. So we'll grab that one instead of relying on the correct one passed in. + // This should help with collapses and other 'attacks' with + // no attackers that happened due to actions from other soldiers or turns, shots against dead bodies, etc. + + pSoldier = NULL; + + if (gTacticalStatus.ubCurrentTeam == gbPlayerNum) + { + pSoldier = MercPtrs[ gusSelectedSoldier ]; + } + else + { + for (cnt = gTacticalStatus.Team[ gTacticalStatus.ubCurrentTeam ].bFirstID; + cnt <= gTacticalStatus.Team[ gTacticalStatus.ubCurrentTeam ].bLastID; + cnt++) + { + if (MercPtrs[ cnt ] && + MercPtrs[ cnt ]->uiStatusFlags & SOLDIER_UNDERAICONTROL) + { + pSoldier = MercPtrs[ cnt ]; + break; + } + } + } + // If we still haven't figured out who last acted, it could be that the team number changed during the attack. Unfortunately this + // can happen during a switch from real-time. For now we will assume the last actor was a PC, but a real "Who started this?" pointer + // would work quite well. If only I could close all the holes that the UI opens so that one routine could handle everything. + if (!pSoldier) + { + pSoldier = MercPtrs[ gusSelectedSoldier ]; + } + + ubID = pSoldier->ubID; + + DebugAttackBusy( String( "Ending action for %d\n", ubID ) ); + // Get the intended target info + pTarget = NULL; + if (pSoldier->ubTargetID != NOBODY) + { + pTarget = MercPtrs[ pSoldier->ubTargetID ]; } if ((gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT)) { // Check to see if anyone was suppressed - if (pSoldier) + if (pTarget) { - HandleSuppressionFire( pSoldier->ubTargetID, ubID ); + HandleSuppressionFire( pTarget->ubID, ubID ); } else { HandleSuppressionFire( NOBODY, ubID ); } - + //HandleAfterShootingGuy( pSoldier, pTarget ); @@ -7364,7 +7455,7 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacke if (gTacticalStatus.ubAttackBusyCount > 0) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting suppression, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); - return( pTarget ); + return( NULL ); } } @@ -7374,15 +7465,18 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacke // OK< let's NOT do this if it was the queen attacking.... if ( AreInMeanwhile( ) && pSoldier != NULL && pSoldier->ubProfile != QUEEN ) { - return( pTarget ); + return( NULL ); } +#if 0 +// 0verhaul: This is moved to the end loop where everybody's state is reset for the next action if (pTarget) { // reset # of shotgun pellets hit by pTarget->bNumPelletsHitBy = 0; // reset flag for making "ow" sound on being shot } +#endif if (pSoldier) { @@ -7428,7 +7522,7 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacke if ( pTeamSoldier->bOppList[ pSoldier->ubID ] == SEEN_CURRENTLY ) { //ZEROTIMECOUNTER( pTeamSoldier->AICounter ); - + //MakeCivHostile( pTeamSoldier, 2 ); HandleCrowFlyAway( pTeamSoldier ); @@ -7500,6 +7594,11 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacke if ( !fEnterCombat ) { + // It's still possible that something happened + if (!(gTacticalStatus.uiFlags & INCOMBAT) ) + { + HandleBestSightingPositionInRealtime(); + } DebugMsg( TOPIC_JA2, DBG_LEVEL_3, ">>Not to enter combat from this attack" ); } @@ -7524,7 +7623,7 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacke HandleKilledQuote( MercPtrs[ gTacticalStatus.ubEnemyKilledOnAttack ], MercPtrs[ gTacticalStatus.ubEnemyKilledOnAttackKiller ], gTacticalStatus.ubEnemyKilledOnAttackLocation, gTacticalStatus.bEnemyKilledOnAttackLevel ); gTacticalStatus.fKilledEnemyOnAttack = FALSE; } - + // ATE: Check for stat changes.... HandleAnyStatChangesAfterAttack( ); @@ -7534,17 +7633,17 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacke gTacticalStatus.fItemsSeenOnAttack = FALSE; // Display quote! - if ( !AM_AN_EPC( MercPtrs[ gTacticalStatus.ubItemsSeenOnAttackSoldier ] ) ) - { - TacticalCharacterDialogueWithSpecialEvent( MercPtrs[ gTacticalStatus.ubItemsSeenOnAttackSoldier ], (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ), DIALOGUE_SPECIAL_EVENT_SIGNAL_ITEM_LOCATOR_START, gTacticalStatus.usItemsSeenOnAttackGridNo, 0 ); - } - else - { + if ( !AM_AN_EPC( MercPtrs[ gTacticalStatus.ubItemsSeenOnAttackSoldier ] ) ) + { + TacticalCharacterDialogueWithSpecialEvent( MercPtrs[ gTacticalStatus.ubItemsSeenOnAttackSoldier ], (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ), DIALOGUE_SPECIAL_EVENT_SIGNAL_ITEM_LOCATOR_START, gTacticalStatus.usItemsSeenOnAttackGridNo, 0 ); + } + else + { // Turn off item lock for locators... gTacticalStatus.fLockItemLocators = FALSE; // Slide to location! SlideToLocation( 0, gTacticalStatus.usItemsSeenOnAttackGridNo ); - } + } } if ( gTacticalStatus.uiFlags & CHECK_SIGHT_AT_END_OF_ATTACK ) @@ -7596,37 +7695,73 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacke } // record last target - // Check for valid target! - if ( pSoldier ) - { - pSoldier->sLastTarget = pSoldier->sTargetGridNo; - } + // Check for valid target! + if ( pSoldier ) + { + pSoldier->sLastTarget = pSoldier->sTargetGridNo; + } + + // Reset various flags and values that should be 0 once the action is overwith + for (cnt = 0; cnt < guiNumMercSlots; cnt++) + { + pSoldier = MercSlots[ cnt ]; + if ( pSoldier ) + { + pSoldier->bNumPelletsHitBy = 0; + pSoldier->fGettingHit = FALSE; + + if (pSoldier->ubAttackerID != NOBODY ) + { + if (pSoldier->ubPreviousAttackerID != pSoldier->ubAttackerID) + { + pSoldier->ubNextToPreviousAttackerID = pSoldier->ubPreviousAttackerID; + } + + pSoldier->ubPreviousAttackerID = pSoldier->ubAttackerID; + + // Why not keep the attacker ID for a dead queen monster? + if ( pSoldier->bLife != 0 && pSoldier->ubBodyType != QUEENMONSTER ) + { + pSoldier->ubAttackerID = NOBODY; + } + } + } + } return( pTarget ); } -SOLDIERTYPE * ReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacker ) +SOLDIERTYPE * ReduceAttackBusyCount( ) { +#if 0 DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("ReduceAttackBusyCount") ); - if ( ubID == NOBODY ) - { - return( InternalReduceAttackBusyCount( ubID, fCalledByAttacker, NOBODY ) ); - } - else - { - return( InternalReduceAttackBusyCount( ubID, fCalledByAttacker, MercPtrs[ ubID ]->ubTargetID ) ); - } + if ( ubID == NOBODY ) + { + return( InternalReduceAttackBusyCount( ubID, fCalledByAttacker, NOBODY ) ); + } + else + { + return( InternalReduceAttackBusyCount( ubID, fCalledByAttacker, MercPtrs[ ubID ]->ubTargetID ) ); + } +#endif +// 0verhaul: This is now a simple subroutine. + return InternalReduceAttackBusyCount( ); } -SOLDIERTYPE * FreeUpAttacker( UINT8 ubID ) +SOLDIERTYPE * FreeUpAttacker( ) { - // Strange as this may seem, this function returns a pointer to - // the *target* in case the target has changed sides as a result - // of being attacked + // Okay, so the objective here is not to simply decrease the ABC, but to twiddle it and see what + // falls out. So there's an increase followed immediately by a decrease. + // If the ABC is 0 at this point, such as an aborted action might give, this will finalize the + // action and allow the soldier to try something else. DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FreeUpAttacker") ); - return( ReduceAttackBusyCount( ubID, TRUE ) ); + DebugAttackBusy( "Freeing up attacker\n"); + gTacticalStatus.ubAttackBusyCount++; + return( ReduceAttackBusyCount( ) ); } +#if 0 +// 0verhaul: These routines are declared obsolete. Call ReduceAttackBusyCount instead. SOLDIERTYPE * FreeUpAttackerGivenTarget( UINT8 ubID, UINT8 ubTargetID ) { // Strange as this may seem, this function returns a pointer to @@ -7644,6 +7779,7 @@ SOLDIERTYPE * ReduceAttackBusyGivenTarget( UINT8 ubID, UINT8 ubTargetID ) DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("ReduceAttackBusyGivenTarget") ); return( InternalReduceAttackBusyCount( ubID, FALSE, ubTargetID ) ); } +#endif void StopMercAnimation( BOOLEAN fStop ) @@ -7717,12 +7853,12 @@ void HandleBloodForNewGridNo( SOLDIERTYPE *pSoldier ) { // Handle bleeding... if ( ( pSoldier->bBleeding > MIN_BLEEDING_THRESHOLD ) ) - { + { INT8 bBlood; bBlood = ( ( pSoldier->bBleeding-MIN_BLEEDING_THRESHOLD ) / BLOODDIVISOR); - if ( bBlood > MAXBLOODQUANTITY ) + if ( bBlood > MAXBLOODQUANTITY ) { bBlood = MAXBLOODQUANTITY; } @@ -7736,7 +7872,7 @@ void HandleBloodForNewGridNo( SOLDIERTYPE *pSoldier ) // this handles all soldiers' dropping blood during movement DropBlood( pSoldier, bBlood, pSoldier->bVisible ); } - } + } } void CencelAllActionsForTimeCompression( void ) @@ -7750,7 +7886,7 @@ void CencelAllActionsForTimeCompression( void ) { if ( pSoldier->bInSector ) { - // Hault! + // Hault! EVENT_StopMerc( pSoldier, pSoldier->sGridNo, pSoldier->bDirection ); // END AI actions @@ -7791,9 +7927,9 @@ void RemoveManFromTeam( INT8 bTeam ) } else if (gTacticalStatus.Team[ bTeam ].bMenInSector < 0) { - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Number of people on team %d dropped to %d", bTeam, gTacticalStatus.Team[ bTeam ].bMenInSector ); - #endif +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Number of people on team %d dropped to %d", bTeam, gTacticalStatus.Team[ bTeam ].bMenInSector ); +#endif // reset! gTacticalStatus.Team[ bTeam ].bMenInSector = 0; } @@ -7818,46 +7954,46 @@ void RemoveSoldierFromTacticalSector( SOLDIERTYPE *pSoldier, BOOLEAN fAdjustSele // Select next avialiable guy.... if ( fAdjustSelected ) { - if ( guiCurrentScreen == GAME_SCREEN ) - { - if ( gusSelectedSoldier == pSoldier->ubID ) - { - ubID = FindNextActiveAndAliveMerc( pSoldier, FALSE, FALSE ); - - if ( ubID != NOBODY && ubID != gusSelectedSoldier ) - { - SelectSoldier( ubID, FALSE, FALSE ); - } - else - { - // OK - let's look for another squad... - pNewSoldier = FindNextActiveSquad( pSoldier ); + if ( guiCurrentScreen == GAME_SCREEN ) + { + if ( gusSelectedSoldier == pSoldier->ubID ) + { + ubID = FindNextActiveAndAliveMerc( pSoldier, FALSE, FALSE ); - if ( pNewSoldier != pSoldier ) - { - // Good squad found! - SelectSoldier( pNewSoldier->ubID, FALSE, FALSE ); - } - else - { - // if here, make nobody - gusSelectedSoldier = NOBODY; - } - } - } - UpdateTeamPanelAssignments( ); - } - else - { - gusSelectedSoldier = NOBODY; + if ( ubID != NOBODY && ubID != gusSelectedSoldier ) + { + SelectSoldier( ubID, FALSE, FALSE ); + } + else + { + // OK - let's look for another squad... + pNewSoldier = FindNextActiveSquad( pSoldier ); - if ( guiCurrentScreen == GAME_SCREEN ) - { - // otherwise, make sure interface is team panel... - UpdateTeamPanelAssignments( ); - SetCurrentInterfacePanel( (UINT8)TEAM_PANEL ); - } - } + if ( pNewSoldier != pSoldier ) + { + // Good squad found! + SelectSoldier( pNewSoldier->ubID, FALSE, FALSE ); + } + else + { + // if here, make nobody + gusSelectedSoldier = NOBODY; + } + } + } + UpdateTeamPanelAssignments( ); + } + else + { + gusSelectedSoldier = NOBODY; + + if ( guiCurrentScreen == GAME_SCREEN ) + { + // otherwise, make sure interface is team panel... + UpdateTeamPanelAssignments( ); + SetCurrentInterfacePanel( (UINT8)TEAM_PANEL ); + } + } } } @@ -7894,7 +8030,7 @@ void InitializeTacticalStatusAtBattleStart( void ) gTacticalStatus.bPanicTriggerIsAlarm[ bLoop ] = FALSE; gTacticalStatus.ubPanicTolerance[ bLoop ] = 0; } - + for( cnt = 0; cnt < MAXTEAMS; cnt++ ) { gTacticalStatus.Team[ cnt ].ubLastMercToRadio = NOBODY; @@ -8090,112 +8226,112 @@ void HandleCreatureTenseQuote( ) UINT8 ubChosenMerc; SOLDIERTYPE *pTeamSoldier; INT32 cnt; - INT32 uiTime; - + INT32 uiTime; + // Check for quote seeing creature attacks.... - if ( gubQuest[ QUEST_CREATURES ] != QUESTDONE ) - { - if ( gTacticalStatus.uiFlags & IN_CREATURE_LAIR ) - { - if( !(gTacticalStatus.uiFlags & INCOMBAT ) ) - { - uiTime = GetJA2Clock( ); + if ( gubQuest[ QUEST_CREATURES ] != QUESTDONE ) + { + if ( gTacticalStatus.uiFlags & IN_CREATURE_LAIR ) + { + if( !(gTacticalStatus.uiFlags & INCOMBAT ) ) + { + uiTime = GetJA2Clock( ); - if ( ( uiTime - gTacticalStatus.uiCreatureTenseQuoteLastUpdate ) > (UINT32)( gTacticalStatus.sCreatureTenseQuoteDelay * 1000 ) ) - { - gTacticalStatus.uiCreatureTenseQuoteLastUpdate = uiTime; + if ( ( uiTime - gTacticalStatus.uiCreatureTenseQuoteLastUpdate ) > (UINT32)( gTacticalStatus.sCreatureTenseQuoteDelay * 1000 ) ) + { + gTacticalStatus.uiCreatureTenseQuoteLastUpdate = uiTime; - // set up soldier ptr as first element in mercptrs list - cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; + // set up soldier ptr as first element in mercptrs list + cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; - // run through list - for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pTeamSoldier++ ) - { - // Add guy if he's a candidate... - if ( OK_INSECTOR_MERC( pTeamSoldier ) && !AM_AN_EPC( pTeamSoldier ) && !( pTeamSoldier->uiStatusFlags & SOLDIER_GASSED ) && !(AM_A_ROBOT( pTeamSoldier )) && !pTeamSoldier->fMercAsleep ) - { - ubMercsInSector[ ubNumMercs ] = (UINT8)cnt; - ubNumMercs++; - } - } - - // If we are > 0 - if ( ubNumMercs > 0 ) - { - ubChosenMerc = (UINT8)Random( ubNumMercs ); + // run through list + for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pTeamSoldier++ ) + { + // Add guy if he's a candidate... + if ( OK_INSECTOR_MERC( pTeamSoldier ) && !AM_AN_EPC( pTeamSoldier ) && !( pTeamSoldier->uiStatusFlags & SOLDIER_GASSED ) && !(AM_A_ROBOT( pTeamSoldier )) && !pTeamSoldier->fMercAsleep ) + { + ubMercsInSector[ ubNumMercs ] = (UINT8)cnt; + ubNumMercs++; + } + } - DoCreatureTensionQuote ( MercPtrs[ ubMercsInSector[ ubChosenMerc ] ] ); - } + // If we are > 0 + if ( ubNumMercs > 0 ) + { + ubChosenMerc = (UINT8)Random( ubNumMercs ); - // Adjust delay.... - gTacticalStatus.sCreatureTenseQuoteDelay = (INT16)( 60 + Random( 60 ) ); + DoCreatureTensionQuote ( MercPtrs[ ubMercsInSector[ ubChosenMerc ] ] ); + } - } - } - } + // Adjust delay.... + gTacticalStatus.sCreatureTenseQuoteDelay = (INT16)( 60 + Random( 60 ) ); + + } + } + } } } void DoCreatureTensionQuote( SOLDIERTYPE *pSoldier ) { - INT32 iRandomQuote; - BOOLEAN fCanDoQuote = TRUE; - INT32 iQuoteToUse; + INT32 iRandomQuote; + BOOLEAN fCanDoQuote = TRUE; + INT32 iQuoteToUse; // Check for playing smell quote.... - iRandomQuote = Random( 3 ); + iRandomQuote = Random( 3 ); - switch( iRandomQuote ) - { - case 0: + switch( iRandomQuote ) + { + case 0: - iQuoteToUse = QUOTE_SMELLED_CREATURE; - if ( !( pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_SMELLED_CREATURE ) ) - { - // set flag - pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_SMELLED_CREATURE; - } - else - { - fCanDoQuote = FALSE; - } - break; + iQuoteToUse = QUOTE_SMELLED_CREATURE; + if ( !( pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_SMELLED_CREATURE ) ) + { + // set flag + pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_SMELLED_CREATURE; + } + else + { + fCanDoQuote = FALSE; + } + break; - case 1: + case 1: - iQuoteToUse = QUOTE_TRACES_OF_CREATURE_ATTACK; - if ( !( pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_SPOTTING_CREATURE_ATTACK ) ) - { - // set flag - pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_SPOTTING_CREATURE_ATTACK; - } - else - { - fCanDoQuote = FALSE; - } - break; + iQuoteToUse = QUOTE_TRACES_OF_CREATURE_ATTACK; + if ( !( pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_SPOTTING_CREATURE_ATTACK ) ) + { + // set flag + pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_SPOTTING_CREATURE_ATTACK; + } + else + { + fCanDoQuote = FALSE; + } + break; - case 2: + case 2: - iQuoteToUse = QUOTE_WORRIED_ABOUT_CREATURE_PRESENCE; - if ( !( pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_WORRIED_ABOUT_CREATURES ) ) - { - // set flag - pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_WORRIED_ABOUT_CREATURES; - } - else - { - fCanDoQuote = FALSE; - } - break; - } + iQuoteToUse = QUOTE_WORRIED_ABOUT_CREATURE_PRESENCE; + if ( !( pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_WORRIED_ABOUT_CREATURES ) ) + { + // set flag + pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_WORRIED_ABOUT_CREATURES; + } + else + { + fCanDoQuote = FALSE; + } + break; + } - if ( fCanDoQuote ) - { - TacticalCharacterDialogue( pSoldier, (INT16)iQuoteToUse ); - } + if ( fCanDoQuote ) + { + TacticalCharacterDialogue( pSoldier, (INT16)iQuoteToUse ); + } } // Kaiden: Taken from UB to reveal all items after combat. diff --git a/Tactical/Overhead.h b/Tactical/Overhead.h index 1da15169..a36c3afa 100644 --- a/Tactical/Overhead.h +++ b/Tactical/Overhead.h @@ -304,7 +304,7 @@ void CycleThroughKnownEnemies( ); BOOLEAN CheckForEndOfCombatMode( BOOLEAN fIncrementTurnsNotSeen ); -SOLDIERTYPE * FreeUpAttacker( UINT8 ubID ); +SOLDIERTYPE * FreeUpAttacker( ); BOOLEAN PlayerTeamFull( ); @@ -314,7 +314,7 @@ void ResetAllMercSpeeds( ); BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLEAN fInitialMove, UINT16 usAnimState ); -SOLDIERTYPE * ReduceAttackBusyCount( UINT8 ubID, BOOLEAN fCalledByAttacker ); +SOLDIERTYPE * ReduceAttackBusyCount( ); void CommonEnterCombatModeCode( ); diff --git a/Tactical/Points.cpp b/Tactical/Points.cpp index a97ea2c1..3cc58c2e 100644 --- a/Tactical/Points.cpp +++ b/Tactical/Points.cpp @@ -24,6 +24,14 @@ #include "SkillCheck.h" #include "wcheck.h" #include "Soldier Profile.h" + #include "Soldier macros.h" + #include "Random.h" + #include "Campaign.h" + #include "drugs and alcohol.h" + #include "GameSettings.h" + #include "worldman.h" + #include "math.h" + #include "Interface Items.h" #endif //rain @@ -823,28 +831,23 @@ INT16 GetBreathPerAP( SOLDIERTYPE *pSoldier, UINT16 usAnimState ) fAnimTypeFound = TRUE; } - if ( gAnimControl[ usAnimState ].uiFlags & ANIM_NO_EFFORT ) - { - sBreathPerAP = BP_PER_AP_NO_EFFORT; - fAnimTypeFound = TRUE; - } - - if ( gAnimControl[ usAnimState ].uiFlags & ANIM_MIN_EFFORT ) - { - sBreathPerAP = BP_PER_AP_MIN_EFFORT; - fAnimTypeFound = TRUE; - } - - if ( gAnimControl[ usAnimState ].uiFlags & ANIM_LIGHT_EFFORT ) - { - sBreathPerAP = BP_PER_AP_LT_EFFORT; - fAnimTypeFound = TRUE; - } - - if ( gAnimControl[ usAnimState ].uiFlags & ANIM_MODERATE_EFFORT ) - { - sBreathPerAP = BP_PER_AP_MOD_EFFORT; - fAnimTypeFound = TRUE; + switch ( EFFORT( gAnimControl[ usAnimState ].uiFlags) ) { + case 0: // No effort + sBreathPerAP = BP_PER_AP_NO_EFFORT; + fAnimTypeFound = TRUE; + break; + case 1: // Minimal effort + sBreathPerAP = BP_PER_AP_MIN_EFFORT; + fAnimTypeFound = TRUE; + break; + case 2: // Light effort + sBreathPerAP = BP_PER_AP_LT_EFFORT; + fAnimTypeFound = TRUE; + break; + case 3: // Moderate effort + sBreathPerAP = BP_PER_AP_MOD_EFFORT; + fAnimTypeFound = TRUE; + break; } if ( !fAnimTypeFound ) @@ -1089,7 +1092,7 @@ UINT8 CalcTotalAPsToAttack( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubAddTur return( (INT8)sAPCost ); } -UINT8 MinAPsToAttack(SOLDIERTYPE *pSoldier, INT16 sGridno, UINT8 ubAddTurningCost) +UINT8 MinAPsToAttack(SOLDIERTYPE *pSoldier, INT16 sGridno, UINT8 ubAddTurningCost, UINT8 ubForceRaiseGunCost) { UINT16 sAPCost = 0; UINT32 uiItemClass; @@ -1119,7 +1122,7 @@ UINT8 MinAPsToAttack(SOLDIERTYPE *pSoldier, INT16 sGridno, UINT8 ubAddTurningCos if ( uiItemClass == IC_BLADE || uiItemClass == IC_GUN || uiItemClass == IC_LAUNCHER || uiItemClass == IC_TENTACLES || uiItemClass == IC_THROWING_KNIFE ) { - sAPCost = MinAPsToShootOrStab( pSoldier, sGridno, ubAddTurningCost ); + sAPCost = MinAPsToShootOrStab( pSoldier, sGridno, ubAddTurningCost, ubForceRaiseGunCost ); } else if ( uiItemClass & ( IC_GRENADE | IC_THROWN ) ) { @@ -1237,7 +1240,7 @@ void GetAPChargeForShootOrStabWRTGunRaises( SOLDIERTYPE *pSoldier, INT16 sGridNo (*pfChargeRaise ) = fAddingRaiseGunCost; } -UINT8 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubAddTurningCost) +UINT8 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubAddTurningCost, UINT8 ubForceRaiseGunCost) { UINT32 uiMercFlags; UINT16 usTargID; @@ -1263,6 +1266,10 @@ UINT8 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubAddTurni GetAPChargeForShootOrStabWRTGunRaises( pSoldier, sGridNo, ubAddTurningCost, &fAddingTurningCost, &fAddingRaiseGunCost ); + if (ubForceRaiseGunCost) + { + fAddingRaiseGunCost = TRUE; + } if ( Item[ usItem ].usItemClass == IC_THROWING_KNIFE ) { @@ -1306,7 +1313,7 @@ UINT8 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubAddTurni } // if attacking a new target (or if the specific target is uncertain) - if (( sGridNo != pSoldier->sLastTarget ) && !Item[usItem].rocketlauncher ) + if (ubForceRaiseGunCost || (( sGridNo != pSoldier->sLastTarget ) && !Item[usItem].rocketlauncher )) { bAPCost += AP_CHANGE_TARGET; } diff --git a/Tactical/Points.h b/Tactical/Points.h index 8fc6101e..2985c542 100644 --- a/Tactical/Points.h +++ b/Tactical/Points.h @@ -282,11 +282,11 @@ void DeductPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost, BOOLEAN INT32 AdjustBreathPts(SOLDIERTYPE *pSold, INT32 iBPCost); void UnusedAPsToBreath(SOLDIERTYPE *pSold); INT16 TerrainBreathPoints(SOLDIERTYPE * pSoldier, INT16 sGridno,INT8 bDir, UINT16 usMovementMode); -UINT8 MinAPsToAttack(SOLDIERTYPE *pSoldier, INT16 sGridno, UINT8 ubAddTurningCost); +UINT8 MinAPsToAttack(SOLDIERTYPE *pSoldier, INT16 sGridno, UINT8 ubAddTurningCost, UINT8 ubForceRaiseGunCost = 0); INT8 MinPtsToMove(SOLDIERTYPE *pSoldier); INT8 MinAPsToStartMovement( SOLDIERTYPE * pSoldier, UINT16 usMovementMode ); INT8 PtsToMoveDirection(SOLDIERTYPE *pSoldier, INT8 bDirection ); -UINT8 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT16 sGridno, UINT8 ubAddTurningCost ); +UINT8 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT16 sGridno, UINT8 ubAddTurningCost, UINT8 ubForceRaiseGunCost = 0 ); BOOLEAN EnoughAmmo( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay, INT8 bInvPos ); void DeductAmmo( SOLDIERTYPE *pSoldier, INT8 bInvPos ); diff --git a/Tactical/Rain.cpp b/Tactical/Rain.cpp index 2bdfbc21..c558bc54 100644 --- a/Tactical/Rain.cpp +++ b/Tactical/Rain.cpp @@ -42,6 +42,17 @@ #ifdef DEBUG_INTERRUPTS #include "debug.h" #endif + #include "render dirty.h" + #include "GameSettings.h" + #include "screenids.h" + #include "vsurface.h" + #include "math.h" + #include "merctextbox.h" + #include "Video.h" + #include "local.h" + #include "line.h" + #include "overhead map.h" + #include "interface dialogue.h" #endif #include "Rain.h" diff --git a/Tactical/Real Time Input.cpp b/Tactical/Real Time Input.cpp index 4b1f67e6..434a0d38 100644 --- a/Tactical/Real Time Input.cpp +++ b/Tactical/Real Time Input.cpp @@ -1,65 +1,67 @@ #ifdef PRECOMPILEDHEADERS - #include "Tactical All.h" +#include "Tactical All.h" #else - #include - #include - #include "wcheck.h" - #include "stdlib.h" - #include "debug.h" - #include "math.h" - #include "jascreens.h" - #include "pathai.h" - #include "Soldier Control.h" - #include "Animation Control.h" - #include "Animation Data.h" - #include "Event Pump.h" - #include "Timer Control.h" - #include "cursors.h" - #include "Handle UI.h" - #include "Isometric Utils.h" - #include "input.h" - #include "overhead.h" - #include "Sys Globals.h" - #include "screenids.h" - #include "interface.h" - #include "cursor control.h" - #include "points.h" - #include "Interactive Tiles.h" - #include "interface cursors.h" - #include "Sound Control.h" - #include "environment.h" - #include "opplist.h" - #include "spread burst.h" - #include "overhead map.h" - #include "world items.h" - #include "Game Clock.h" - #include "interface items.h" - #include "physics.h" - #include "ui cursors.h" - #include "worldman.h" - #include "strategicmap.h" - #include "soldier profile.h" - #include "soldier create.h" - #include "soldier add.h" - #include "dialogue control.h" - #include "interface dialogue.h" - #include "interactive tiles.h" - #include "messageboxscreen.h" - #include "gameloop.h" - #include "gamescreen.h" - #include "spread burst.h" - #include "tile animation.h" - #include "merc entering.h" - #include "explosion control.h" - #include "message.h" - #include "Strategic Exit GUI.h" - #include "Assignments.h" - #include "Map Screen Interface.h" - #include "renderworld.h" - #include "GameSettings.h" - #include "english.h" - #include "text.h" - #include "soldier macros.h" +#include +#include +#include "wcheck.h" +#include "stdlib.h" +#include "debug.h" +#include "math.h" +#include "jascreens.h" +#include "pathai.h" +#include "Soldier Control.h" +#include "Animation Control.h" +#include "Animation Data.h" +#include "Event Pump.h" +#include "Timer Control.h" +#include "cursors.h" +#include "Handle UI.h" +#include "Isometric Utils.h" +#include "input.h" +#include "overhead.h" +#include "Sys Globals.h" +#include "screenids.h" +#include "interface.h" +#include "cursor control.h" +#include "points.h" +#include "Interactive Tiles.h" +#include "interface cursors.h" +#include "Sound Control.h" +#include "environment.h" +#include "opplist.h" +#include "spread burst.h" +#include "overhead map.h" +#include "world items.h" +#include "Game Clock.h" +#include "interface items.h" +#include "physics.h" +#include "ui cursors.h" +#include "worldman.h" +#include "strategicmap.h" +#include "soldier profile.h" +#include "soldier create.h" +#include "soldier add.h" +#include "dialogue control.h" +#include "interface dialogue.h" +#include "interactive tiles.h" +#include "messageboxscreen.h" +#include "gameloop.h" +#include "gamescreen.h" +#include "spread burst.h" +#include "tile animation.h" +#include "merc entering.h" +#include "explosion control.h" +#include "message.h" +#include "Strategic Exit GUI.h" +#include "Assignments.h" +#include "Map Screen Interface.h" +#include "renderworld.h" +#include "GameSettings.h" +#include "english.h" +#include "text.h" +#include "soldier macros.h" +#include "render dirty.h" +#include "Militia Control.h" #endif @@ -93,8 +95,8 @@ extern BOOLEAN ValidQuickExchangePosition( ); void GetRTMouseButtonInput( UINT32 *puiNewEvent ) { - QueryRTLeftButton( puiNewEvent ); - QueryRTRightButton( puiNewEvent ); + QueryRTLeftButton( puiNewEvent ); + QueryRTRightButton( puiNewEvent ); } void QueryRTLeftButton( UINT32 *puiNewEvent ) @@ -112,9 +114,9 @@ void QueryRTLeftButton( UINT32 *puiNewEvent ) // LEFT MOUSE BUTTON - if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) + if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) { - if (!GetMouseMapPos( (INT16 *)&usMapPos ) && !gfUIShowExitSouth ) + if (!GetMouseMapPos( &usMapPos ) && !gfUIShowExitSouth ) { return; } @@ -142,101 +144,100 @@ void QueryRTLeftButton( UINT32 *puiNewEvent ) { switch( gCurrentUIMode ) { - case ACTION_MODE: + case ACTION_MODE: - if ( gusSelectedSoldier != NOBODY ) + if ( gusSelectedSoldier != NOBODY ) + { + if( GetSoldier( &pSoldier, gusSelectedSoldier ) && gpItemPointer == NULL ) { - if( GetSoldier( &pSoldier, gusSelectedSoldier ) && gpItemPointer == NULL ) + // OK, check for needing ammo + if ( HandleUIReloading( pSoldier ) ) { - // OK, check for needing ammo - if ( HandleUIReloading( pSoldier ) ) + gfRTClickLeftHoldIntercepted = TRUE; + //fLeftButtonDown = FALSE; + } + else + { + if ( pSoldier->bDoBurst ) { - gfRTClickLeftHoldIntercepted = TRUE; - //fLeftButtonDown = FALSE; + pSoldier->sStartGridNo = usMapPos; + ResetBurstLocations( ); + *puiNewEvent = A_CHANGE_TO_CONFIM_ACTION; } else { - if ( pSoldier->bDoBurst ) - { - pSoldier->sStartGridNo = usMapPos; - ResetBurstLocations( ); - *puiNewEvent = A_CHANGE_TO_CONFIM_ACTION; - } - else - { - gfRTClickLeftHoldIntercepted = TRUE; + gfRTClickLeftHoldIntercepted = TRUE; - if ( UIMouseOnValidAttackLocation( pSoldier ) ) - { - // OK< going into confirm will call a function that will automatically move - // us to shoot in most vases ( grenades need a confirm mode regardless ) - *puiNewEvent = A_CHANGE_TO_CONFIM_ACTION; - //*puiNewEvent = CA_MERC_SHOOT; - PauseRT( FALSE ); - } + if ( UIMouseOnValidAttackLocation( pSoldier ) ) + { + // OK< going into confirm will call a function that will automatically move + // us to shoot in most vases ( grenades need a confirm mode regardless ) + *puiNewEvent = A_CHANGE_TO_CONFIM_ACTION; + //*puiNewEvent = CA_MERC_SHOOT; + PauseRT( FALSE ); } } } } - break; + } + break; - case MOVE_MODE: - - gfUICanBeginAllMoveCycle = TRUE; + case MOVE_MODE: - if ( !HandleCheckForExitArrowsInput( FALSE ) && gpItemPointer == NULL ) + gfUICanBeginAllMoveCycle = TRUE; + + if ( !HandleCheckForExitArrowsInput( FALSE ) && gpItemPointer == NULL ) + { + if ( gfUIFullTargetFound && ( guiUIFullTargetFlags & OWNED_MERC ) ) { - if ( gfUIFullTargetFound && ( guiUIFullTargetFlags & OWNED_MERC ) ) + // Reset , if this guy is selected merc, reset any multi selections... + if ( gusUIFullTargetID == gusSelectedSoldier ) { - // Reset , if this guy is selected merc, reset any multi selections... - if ( gusUIFullTargetID == gusSelectedSoldier ) - { - ResetMultiSelection( ); - } + ResetMultiSelection( ); } - else + } + else + { + INT8 bReturnCode; + + bReturnCode = HandleMoveModeInteractiveClick( usMapPos, puiNewEvent ); + + if ( bReturnCode == -1 ) + { + //gfRTClickLeftHoldIntercepted = TRUE; + } + else if ( bReturnCode == -2 ) + { + //if ( gGameSettings.fOptions[ TOPTION_RTCONFIRM ] ) + //{ + // *puiNewEvent = C_WAIT_FOR_CONFIRM; + // gfPlotNewMovement = TRUE; + //}/ + //else + } + else if ( bReturnCode == -3 ) + { + gfRTClickLeftHoldIntercepted = TRUE; + } + else if ( bReturnCode == 0 ) { - INT8 bReturnCode; - - bReturnCode = HandleMoveModeInteractiveClick( usMapPos, puiNewEvent ); - - if ( bReturnCode == -1 ) - { - //gfRTClickLeftHoldIntercepted = TRUE; - } - else if ( bReturnCode == -2 ) - { - //if ( gGameSettings.fOptions[ TOPTION_RTCONFIRM ] ) - //{ - // *puiNewEvent = C_WAIT_FOR_CONFIRM; - // gfPlotNewMovement = TRUE; - //}/ - //else - } - else if ( bReturnCode == -3 ) - { - gfRTClickLeftHoldIntercepted = TRUE; - } - else if ( bReturnCode == 0 ) { { - { - BOOLEAN fResult; + BOOLEAN fResult; - if ( gusSelectedSoldier != NOBODY ) + if ( gusSelectedSoldier != NOBODY ) + { + if ( ( fResult = UIOKMoveDestination( MercPtrs[ gusSelectedSoldier ], usMapPos ) ) == 1 ) { - if ( ( fResult = UIOKMoveDestination( MercPtrs[ gusSelectedSoldier ], usMapPos ) ) == 1 ) + if ( gsCurrentActionPoints != 0 ) { - if ( gsCurrentActionPoints != 0 ) + // We're on terrain in which we can walk, walk + // If we're on terrain, + if ( !gGameSettings.fOptions[ TOPTION_RTCONFIRM ] ) { - // We're on terrain in which we can walk, walk - // If we're on terrain, - if ( !gGameSettings.fOptions[ TOPTION_RTCONFIRM ] ) - { - *puiNewEvent = C_WAIT_FOR_CONFIRM; - gfPlotNewMovement = TRUE; - } + *puiNewEvent = C_WAIT_FOR_CONFIRM; + gfPlotNewMovement = TRUE; } } } @@ -244,17 +245,18 @@ void QueryRTLeftButton( UINT32 *puiNewEvent ) } } } - //gfRTClickLeftHoldIntercepted = TRUE; } - else - { - gfRTClickLeftHoldIntercepted = TRUE; - fIgnoreLeftUp = TRUE; - } - - break; + //gfRTClickLeftHoldIntercepted = TRUE; } + else + { + gfRTClickLeftHoldIntercepted = TRUE; + fIgnoreLeftUp = TRUE; + } + + break; } + } } if ( gfUIWaitingForUserSpeechAdvance ) { @@ -271,70 +273,70 @@ void QueryRTLeftButton( UINT32 *puiNewEvent ) switch( gCurrentUIMode ) { - case MOVE_MODE: - case CONFIRM_MOVE_MODE: + case MOVE_MODE: + case CONFIRM_MOVE_MODE: - // First check if we clicked on a guy, if so, make selected if it's ours - if( FindSoldierFromMouse( &usSoldierIndex, &uiMercFlags ) ) + // First check if we clicked on a guy, if so, make selected if it's ours + if( FindSoldierFromMouse( &usSoldierIndex, &uiMercFlags ) ) + { + // Select guy + if ( (uiMercFlags & SELECTED_MERC) && !( uiMercFlags & UNCONSCIOUS_MERC ) && !( MercPtrs[ usSoldierIndex ]->uiStatusFlags & SOLDIER_VEHICLE ) ) { - // Select guy - if ( (uiMercFlags & SELECTED_MERC) && !( uiMercFlags & UNCONSCIOUS_MERC ) && !( MercPtrs[ usSoldierIndex ]->uiStatusFlags & SOLDIER_VEHICLE ) ) - { - *puiNewEvent = M_CHANGE_TO_ADJPOS_MODE; - } + *puiNewEvent = M_CHANGE_TO_ADJPOS_MODE; } - else + } + else + { + //if ( COUNTERDONE( RUBBER_BAND_START_DELAY ) ) { - //if ( COUNTERDONE( RUBBER_BAND_START_DELAY ) ) + // OK, change to rubber banding mode.. + // Have we started this yet? + if ( !gfStartLookingForRubberBanding && !gRubberBandActive ) { - // OK, change to rubber banding mode.. - // Have we started this yet? - if ( !gfStartLookingForRubberBanding && !gRubberBandActive ) + gfStartLookingForRubberBanding = TRUE; + gusRubberBandX = gusMouseXPos; + gusRubberBandY = gusMouseYPos; + } + else + { + // Have we moved....? + if ( abs( gusMouseXPos - gusRubberBandX ) > 10 || abs( gusMouseYPos - gusRubberBandY ) > 10 ) { - gfStartLookingForRubberBanding = TRUE; - gusRubberBandX = gusMouseXPos; - gusRubberBandY = gusMouseYPos; - } - else - { - // Have we moved....? - if ( abs( gusMouseXPos - gusRubberBandX ) > 10 || abs( gusMouseYPos - gusRubberBandY ) > 10 ) + gfStartLookingForRubberBanding = FALSE; + + // Stop scrolling: + gfIgnoreScrolling = TRUE; + + // Anchor cursor.... + RestrictMouseToXYXY( 0, 0, gsVIEWPORT_END_X, gsVIEWPORT_WINDOW_END_Y ); + + // OK, settup anchor.... + gRubberBandRect.iLeft = gusRubberBandX; + gRubberBandRect.iTop = gusRubberBandY; + + gRubberBandActive = TRUE; + + // ATE: If we have stopped scrolling..... + if ( gfScrollInertia != FALSE ) { - gfStartLookingForRubberBanding = FALSE; + SetRenderFlags( RENDER_FLAG_FULL | RENDER_FLAG_CHECKZ ); - // Stop scrolling: - gfIgnoreScrolling = TRUE; + // Restore Interface! + RestoreInterface( ); - // Anchor cursor.... - RestrictMouseToXYXY( 0, 0, gsVIEWPORT_END_X, gsVIEWPORT_WINDOW_END_Y ); + // Delete Topmost blitters saved areas + DeleteVideoOverlaysArea( ); - // OK, settup anchor.... - gRubberBandRect.iLeft = gusRubberBandX; - gRubberBandRect.iTop = gusRubberBandY; - - gRubberBandActive = TRUE; - - // ATE: If we have stopped scrolling..... - if ( gfScrollInertia != FALSE ) - { - SetRenderFlags( RENDER_FLAG_FULL | RENDER_FLAG_CHECKZ ); - - // Restore Interface! - RestoreInterface( ); - - // Delete Topmost blitters saved areas - DeleteVideoOverlaysArea( ); - - gfScrollInertia = FALSE; - } - - *puiNewEvent = RB_ON_TERRAIN; - return; + gfScrollInertia = FALSE; } + + *puiNewEvent = RB_ON_TERRAIN; + return; } } - } - break; + } + } + break; } } } @@ -354,20 +356,20 @@ void QueryRTLeftButton( UINT32 *puiNewEvent ) { if ( gpItemPointer == NULL ) { - fDoubleClickIntercepted = TRUE; + fDoubleClickIntercepted = TRUE; - // First check if we clicked on a guy, if so, make selected if it's ours - if( gusSelectedSoldier != NO_SOLDIER ) + // First check if we clicked on a guy, if so, make selected if it's ours + if( gusSelectedSoldier != NO_SOLDIER ) + { + // Set movement mode + // OK, only change this if we are stationary! + //if ( gAnimControl[ MercPtrs[ gusSelectedSoldier ]->usAnimState ].uiFlags & ANIM_STATIONARY ) + //if ( MercPtrs[ gusSelectedSoldier ]->usAnimState == WALKING ) { - // Set movement mode - // OK, only change this if we are stationary! - //if ( gAnimControl[ MercPtrs[ gusSelectedSoldier ]->usAnimState ].uiFlags & ANIM_STATIONARY ) - //if ( MercPtrs[ gusSelectedSoldier ]->usAnimState == WALKING ) - { - MercPtrs[ gusSelectedSoldier ]->fUIMovementFast = TRUE; - *puiNewEvent = C_MOVE_MERC; - } - } + MercPtrs[ gusSelectedSoldier ]->fUIMovementFast = TRUE; + *puiNewEvent = C_MOVE_MERC; + } + } } } @@ -383,11 +385,11 @@ void QueryRTLeftButton( UINT32 *puiNewEvent ) // FIRST CHECK FOR ANYTIME ( NON-INTERVAL ) CLICKS switch( gCurrentUIMode ) { - case ADJUST_STANCE_MODE: + case ADJUST_STANCE_MODE: - // If button has come up, change to mocve mode - *puiNewEvent = PADJ_ADJUST_STANCE; - break; + // If button has come up, change to mocve mode + *puiNewEvent = PADJ_ADJUST_STANCE; + break; } // CHECK IF WE CLICKED-HELD @@ -397,35 +399,35 @@ void QueryRTLeftButton( UINT32 *puiNewEvent ) // Switch on UI mode switch( gCurrentUIMode ) { - case CONFIRM_ACTION_MODE: - case ACTION_MODE: + case CONFIRM_ACTION_MODE: + case ACTION_MODE: - if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + { + if ( pSoldier->bDoBurst ) { - if ( pSoldier->bDoBurst ) + pSoldier->sEndGridNo = usMapPos; + + gfBeginBurstSpreadTracking = FALSE; + + if ( pSoldier->sEndGridNo != pSoldier->sStartGridNo ) { - pSoldier->sEndGridNo = usMapPos; + pSoldier->fDoSpread = TRUE; - gfBeginBurstSpreadTracking = FALSE; + PickBurstLocations( pSoldier ); - if ( pSoldier->sEndGridNo != pSoldier->sStartGridNo ) - { - pSoldier->fDoSpread = TRUE; - - PickBurstLocations( pSoldier ); - - *puiNewEvent = CA_MERC_SHOOT; - } - else - { - pSoldier->fDoSpread = FALSE; - } - gfRTClickLeftHoldIntercepted = TRUE; + *puiNewEvent = CA_MERC_SHOOT; } + else + { + pSoldier->fDoSpread = FALSE; + } + gfRTClickLeftHoldIntercepted = TRUE; } - break; - } + break; + + } } //else { @@ -462,427 +464,427 @@ void QueryRTLeftButton( UINT32 *puiNewEvent ) } else { - switch( gCurrentUIMode ) + switch( gCurrentUIMode ) + { + + case MENU_MODE: + + // If we get a hit here and we're in menu mode, quit the menu mode + EndMenuEvent( guiCurrentEvent ); + break; + + case IDLE_MODE: + + // First check if we clicked on a guy, if so, make selected if it's ours + if( FindSoldierFromMouse( &usSoldierIndex, &uiMercFlags ) ) { + // Select guy + if ( uiMercFlags & OWNED_MERC ) + { + *puiNewEvent = I_SELECT_MERC; + } - case MENU_MODE: + } + break; - // If we get a hit here and we're in menu mode, quit the menu mode - EndMenuEvent( guiCurrentEvent ); - break; - - case IDLE_MODE: + case HANDCURSOR_MODE: - // First check if we clicked on a guy, if so, make selected if it's ours - if( FindSoldierFromMouse( &usSoldierIndex, &uiMercFlags ) ) + HandleHandCursorClick( usMapPos, puiNewEvent ); + break; + + case ACTION_MODE: + + //*puiNewEvent = A_CHANGE_TO_CONFIM_ACTION; + //if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + //{ + // pSoldier->sStartGridNo = usMapPos; + // ResetBurstLocations( ); + //} + *puiNewEvent = CA_MERC_SHOOT; + break; + + case CONFIRM_MOVE_MODE: + + if ( gusSelectedSoldier != NO_SOLDIER ) + { + if ( MercPtrs[ gusSelectedSoldier ]->usAnimState != RUNNING ) + { + *puiNewEvent = C_MOVE_MERC; + } + else + { + MercPtrs[ gusSelectedSoldier ]->fUIMovementFast = 2; + *puiNewEvent = C_MOVE_MERC; + } + } + + //*puiNewEvent = C_MOVE_MERC; + + //if ( gGameSettings.fOptions[ TOPTION_RTCONFIRM ] ) + { + fValidDoubleClickPossible = TRUE; + } + break; + + case CONFIRM_ACTION_MODE: + + // Check if we are stationary + //if ( AimCubeUIClick( ) ) + //{ + // if ( gusSelectedSoldier != NO_SOLDIER ) + // { + // if ( !( gAnimControl[ MercPtrs[ gusSelectedSoldier ]->usAnimState ].uiFlags & ANIM_STATIONARY ) ) + // { + + //gUITargetShotWaiting = TRUE; + //gsUITargetShotGridNo = usMapPos; + // } + // else + // { + // *puiNewEvent = CA_MERC_SHOOT; + // } + *puiNewEvent = CA_MERC_SHOOT; + // } + //} + break; + + case MOVE_MODE: + + if ( !HandleCheckForExitArrowsInput( FALSE ) && gpItemPointer == NULL ) + { + // First check if we clicked on a guy, if so, make selected if it's ours + if ( gfUIFullTargetFound && ( guiUIFullTargetFlags & OWNED_MERC ) ) + { + if ( !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) { - // Select guy - if ( uiMercFlags & OWNED_MERC ) - { - *puiNewEvent = I_SELECT_MERC; - } - - } - break; - - case HANDCURSOR_MODE: - - HandleHandCursorClick( usMapPos, puiNewEvent ); - break; - - case ACTION_MODE: - - //*puiNewEvent = A_CHANGE_TO_CONFIM_ACTION; - //if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) - //{ - // pSoldier->sStartGridNo = usMapPos; - // ResetBurstLocations( ); - //} - *puiNewEvent = CA_MERC_SHOOT; - break; - - case CONFIRM_MOVE_MODE: - - if ( gusSelectedSoldier != NO_SOLDIER ) - { - if ( MercPtrs[ gusSelectedSoldier ]->usAnimState != RUNNING ) - { - *puiNewEvent = C_MOVE_MERC; - } - else - { - MercPtrs[ gusSelectedSoldier ]->fUIMovementFast = 2; - *puiNewEvent = C_MOVE_MERC; - } - } - - //*puiNewEvent = C_MOVE_MERC; - - //if ( gGameSettings.fOptions[ TOPTION_RTCONFIRM ] ) - { - fValidDoubleClickPossible = TRUE; - } - break; - - case CONFIRM_ACTION_MODE: - - // Check if we are stationary - //if ( AimCubeUIClick( ) ) - //{ - // if ( gusSelectedSoldier != NO_SOLDIER ) - // { - // if ( !( gAnimControl[ MercPtrs[ gusSelectedSoldier ]->usAnimState ].uiFlags & ANIM_STATIONARY ) ) - // { - - //gUITargetShotWaiting = TRUE; - //gsUITargetShotGridNo = usMapPos; - // } - // else - // { - // *puiNewEvent = CA_MERC_SHOOT; - // } - *puiNewEvent = CA_MERC_SHOOT; - // } - //} - break; - - case MOVE_MODE: - - if ( !HandleCheckForExitArrowsInput( FALSE ) && gpItemPointer == NULL ) - { - // First check if we clicked on a guy, if so, make selected if it's ours - if ( gfUIFullTargetFound && ( guiUIFullTargetFlags & OWNED_MERC ) ) + // Select guy + if( GetSoldier( &pSoldier, gusUIFullTargetID ) && gpItemPointer == NULL ) + { + if( pSoldier->bAssignment >= ON_DUTY && !(pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) { - if ( !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) - { - // Select guy - if( GetSoldier( &pSoldier, gusUIFullTargetID ) && gpItemPointer == NULL ) - { - if( pSoldier->bAssignment >= ON_DUTY && !(pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) - { - PopupAssignmentMenuInTactical( pSoldier ); - } - else - { - if ( !_KeyDown( ALT ) ) - { - ResetMultiSelection( ); - *puiNewEvent = I_SELECT_MERC; - } - else - { - if ( pSoldier->uiStatusFlags & SOLDIER_MULTI_SELECTED ) - { - pSoldier->uiStatusFlags &= (~SOLDIER_MULTI_SELECTED ); - } - else - { - pSoldier->uiStatusFlags |= (SOLDIER_MULTI_SELECTED ); - // Say Confimation... - if( !gGameSettings.fOptions[ TOPTION_MUTE_CONFIRMATIONS ] ) - DoMercBattleSound( pSoldier, BATTLE_SOUND_ATTN1 ); - - // OK, if we have a selected guy.. make him part too.... - if ( gusSelectedSoldier != NOBODY ) - { - MercPtrs[ gusSelectedSoldier ]->uiStatusFlags |= (SOLDIER_MULTI_SELECTED ); - } - } - - gfIgnoreOnSelectedGuy = TRUE; - - - EndMultiSoldierSelection( FALSE ); - } - } - } - else - { - if ( !_KeyDown( ALT ) ) - { - ResetMultiSelection( ); - *puiNewEvent = I_SELECT_MERC; - } - else - { - if ( pSoldier->uiStatusFlags & SOLDIER_MULTI_SELECTED ) - { - pSoldier->uiStatusFlags &= (~SOLDIER_MULTI_SELECTED ); - } - else - { - pSoldier->uiStatusFlags |= (SOLDIER_MULTI_SELECTED ); - // Say Confimation... - if( !gGameSettings.fOptions[ TOPTION_MUTE_CONFIRMATIONS ] ) - DoMercBattleSound( pSoldier, BATTLE_SOUND_ATTN1 ); - } - - // OK, if we have a selected guy.. make him part too.... - if ( gusSelectedSoldier != NOBODY ) - { - MercPtrs[ gusSelectedSoldier ]->uiStatusFlags |= (SOLDIER_MULTI_SELECTED ); - } - - gfIgnoreOnSelectedGuy = TRUE; - - EndMultiSoldierSelection( FALSE ); - } - } - } - gfRTClickLeftHoldIntercepted = TRUE; + PopupAssignmentMenuInTactical( pSoldier ); } else { - INT8 bReturnCode; - - bReturnCode = HandleMoveModeInteractiveClick( usMapPos, puiNewEvent ); - - if ( bReturnCode == -1 ) + if ( !_KeyDown( ALT ) ) { - gfRTClickLeftHoldIntercepted = TRUE; + ResetMultiSelection( ); + *puiNewEvent = I_SELECT_MERC; } - else if ( bReturnCode == -2 ) + else { - //if ( gGameSettings.fOptions[ TOPTION_RTCONFIRM ] ) - //{ - // *puiNewEvent = C_WAIT_FOR_CONFIRM; - // gfPlotNewMovement = TRUE; - //}/ - //else + if ( pSoldier->uiStatusFlags & SOLDIER_MULTI_SELECTED ) { - INT16 sIntTileGridNo; + pSoldier->uiStatusFlags &= (~SOLDIER_MULTI_SELECTED ); + } + else + { + pSoldier->uiStatusFlags |= (SOLDIER_MULTI_SELECTED ); + // Say Confimation... + if( !gGameSettings.fOptions[ TOPTION_MUTE_CONFIRMATIONS ] ) + DoMercBattleSound( pSoldier, BATTLE_SOUND_ATTN1 ); - if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + // OK, if we have a selected guy.. make him part too.... + if ( gusSelectedSoldier != NOBODY ) { - BeginDisplayTimedCursor( GetInteractiveTileCursor( guiCurrentUICursor, TRUE ), 300 ); - - if ( pSoldier->usAnimState != RUNNING ) - { - *puiNewEvent = C_MOVE_MERC; - } - else - { - if ( GetCurInteractiveTileGridNo( &sIntTileGridNo ) != NULL ) - { - pSoldier->fUIMovementFast = TRUE; - *puiNewEvent = C_MOVE_MERC; - } - } - fValidDoubleClickPossible = TRUE; + MercPtrs[ gusSelectedSoldier ]->uiStatusFlags |= (SOLDIER_MULTI_SELECTED ); } } + + gfIgnoreOnSelectedGuy = TRUE; + + + EndMultiSoldierSelection( FALSE ); } - else if ( bReturnCode == 0 ) + } + } + else + { + if ( !_KeyDown( ALT ) ) + { + ResetMultiSelection( ); + *puiNewEvent = I_SELECT_MERC; + } + else + { + if ( pSoldier->uiStatusFlags & SOLDIER_MULTI_SELECTED ) { - if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + pSoldier->uiStatusFlags &= (~SOLDIER_MULTI_SELECTED ); + } + else + { + pSoldier->uiStatusFlags |= (SOLDIER_MULTI_SELECTED ); + // Say Confimation... + if( !gGameSettings.fOptions[ TOPTION_MUTE_CONFIRMATIONS ] ) + DoMercBattleSound( pSoldier, BATTLE_SOUND_ATTN1 ); + } + + // OK, if we have a selected guy.. make him part too.... + if ( gusSelectedSoldier != NOBODY ) + { + MercPtrs[ gusSelectedSoldier ]->uiStatusFlags |= (SOLDIER_MULTI_SELECTED ); + } + + gfIgnoreOnSelectedGuy = TRUE; + + EndMultiSoldierSelection( FALSE ); + } + } + } + gfRTClickLeftHoldIntercepted = TRUE; + } + else + { + INT8 bReturnCode; + + bReturnCode = HandleMoveModeInteractiveClick( usMapPos, puiNewEvent ); + + if ( bReturnCode == -1 ) + { + gfRTClickLeftHoldIntercepted = TRUE; + } + else if ( bReturnCode == -2 ) + { + //if ( gGameSettings.fOptions[ TOPTION_RTCONFIRM ] ) + //{ + // *puiNewEvent = C_WAIT_FOR_CONFIRM; + // gfPlotNewMovement = TRUE; + //}/ + //else + { + INT16 sIntTileGridNo; + + if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + { + BeginDisplayTimedCursor( GetInteractiveTileCursor( guiCurrentUICursor, TRUE ), 300 ); + + if ( pSoldier->usAnimState != RUNNING ) + { + *puiNewEvent = C_MOVE_MERC; + } + else + { + if ( GetCurInteractiveTileGridNo( &sIntTileGridNo ) != NULL ) { - // First check if we clicked on a guy, if so, make selected if it's ours - if( FindSoldierFromMouse( &usSoldierIndex, &uiMercFlags ) && ( uiMercFlags & OWNED_MERC ) ) + pSoldier->fUIMovementFast = TRUE; + *puiNewEvent = C_MOVE_MERC; + } + } + fValidDoubleClickPossible = TRUE; + } + } + } + else if ( bReturnCode == 0 ) + { + if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + { + // First check if we clicked on a guy, if so, make selected if it's ours + if( FindSoldierFromMouse( &usSoldierIndex, &uiMercFlags ) && ( uiMercFlags & OWNED_MERC ) ) + { + // Select guy + *puiNewEvent = I_SELECT_MERC; + gfRTClickLeftHoldIntercepted = TRUE; + } + else + { + //if ( FindBestPath( pSoldier, usMapPos, pSoldier->bLevel, pSoldier->usUIMovementMode, NO_COPYROUTE, 0 ) == 0 ) + if ( gsCurrentActionPoints == 0 && !gfUIAllMoveOn && !gTacticalStatus.fAtLeastOneGuyOnMultiSelect ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); + gfRTClickLeftHoldIntercepted = TRUE; + } + else + { + BOOLEAN fResult; + + if ( gusSelectedSoldier != NOBODY ) + { + if ( ( fResult = UIOKMoveDestination( MercPtrs[ gusSelectedSoldier ], usMapPos ) ) == 1 ) { - // Select guy - *puiNewEvent = I_SELECT_MERC; - gfRTClickLeftHoldIntercepted = TRUE; - } - else - { - //if ( FindBestPath( pSoldier, usMapPos, pSoldier->bLevel, pSoldier->usUIMovementMode, NO_COPYROUTE, 0 ) == 0 ) - if ( gsCurrentActionPoints == 0 && !gfUIAllMoveOn && !gTacticalStatus.fAtLeastOneGuyOnMultiSelect ) + if ( gfUIAllMoveOn ) { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); - gfRTClickLeftHoldIntercepted = TRUE; + // ATE: Select everybody in squad and make move! + { +#if 0 + SOLDIERTYPE * pTeamSoldier; + INT32 cnt; + SOLDIERTYPE *pFirstSoldier = NULL; + + // OK, loop through all guys who are 'multi-selected' and + // check if our currently selected guy is amoung the + // lucky few.. if not, change to a guy who is... + cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; + for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++, pTeamSoldier++ ) + { + // Default turn off + pTeamSoldier->uiStatusFlags &= (~SOLDIER_MULTI_SELECTED ); + + // If controllable + if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == MercPtrs[ gusSelectedSoldier ]->bAssignment ) + { + pTeamSoldier->uiStatusFlags |= SOLDIER_MULTI_SELECTED; + } + } + EndMultiSoldierSelection( FALSE ); +#endif + + // Make move! + *puiNewEvent = C_MOVE_MERC; + + fValidDoubleClickPossible = TRUE; + } } else { - BOOLEAN fResult; - - if ( gusSelectedSoldier != NOBODY ) + // We're on terrain in which we can walk, walk + // If we're on terrain, + if ( gGameSettings.fOptions[ TOPTION_RTCONFIRM ] ) { - if ( ( fResult = UIOKMoveDestination( MercPtrs[ gusSelectedSoldier ], usMapPos ) ) == 1 ) - { - if ( gfUIAllMoveOn ) - { - // ATE: Select everybody in squad and make move! - { -#if 0 - SOLDIERTYPE * pTeamSoldier; - INT32 cnt; - SOLDIERTYPE *pFirstSoldier = NULL; - - // OK, loop through all guys who are 'multi-selected' and - // check if our currently selected guy is amoung the - // lucky few.. if not, change to a guy who is... - cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; - for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++, pTeamSoldier++ ) - { - // Default turn off - pTeamSoldier->uiStatusFlags &= (~SOLDIER_MULTI_SELECTED ); - - // If controllable - if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == MercPtrs[ gusSelectedSoldier ]->bAssignment ) - { - pTeamSoldier->uiStatusFlags |= SOLDIER_MULTI_SELECTED; - } - } - EndMultiSoldierSelection( FALSE ); -#endif - - // Make move! - *puiNewEvent = C_MOVE_MERC; - - fValidDoubleClickPossible = TRUE; - } - } - else - { - // We're on terrain in which we can walk, walk - // If we're on terrain, - if ( gGameSettings.fOptions[ TOPTION_RTCONFIRM ] ) - { - *puiNewEvent = C_WAIT_FOR_CONFIRM; - gfPlotNewMovement = TRUE; - } - else - { - *puiNewEvent = C_MOVE_MERC; - fValidDoubleClickPossible = TRUE; - } - } - } - else - { - if ( fResult == 2 ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NOBODY_USING_REMOTE_STR ] ); - } - else - { - //if ( usMapPos != sMoveClickGridNo || pSoldier->uiStatusFlags & SOLDIER_ROBOT ) - //{ - // sMoveClickGridNo = usMapPos; - - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANT_MOVE_THERE_STR ] ); - - // *puiNewEvent = M_CHANGE_TO_HANDMODE; - // gsOverItemsGridNo = usMapPos; - // gsOverItemsLevel = gsInterfaceLevel; - // } - // else - // { - // sMoveClickGridNo = 0; - // *puiNewEvent = M_CHANGE_TO_HANDMODE; - // } - } - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, L"Invalid move destination." ); - - // Goto hand cursor mode... - //*puiNewEvent = M_CHANGE_TO_HANDMODE; - - gfRTClickLeftHoldIntercepted = TRUE; - } + *puiNewEvent = C_WAIT_FOR_CONFIRM; + gfPlotNewMovement = TRUE; + } + else + { + *puiNewEvent = C_MOVE_MERC; + fValidDoubleClickPossible = TRUE; } } } + else + { + if ( fResult == 2 ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NOBODY_USING_REMOTE_STR ] ); + } + else + { + //if ( usMapPos != sMoveClickGridNo || pSoldier->uiStatusFlags & SOLDIER_ROBOT ) + //{ + // sMoveClickGridNo = usMapPos; + + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANT_MOVE_THERE_STR ] ); + + // *puiNewEvent = M_CHANGE_TO_HANDMODE; + // gsOverItemsGridNo = usMapPos; + // gsOverItemsLevel = gsInterfaceLevel; + // } + // else + // { + // sMoveClickGridNo = 0; + // *puiNewEvent = M_CHANGE_TO_HANDMODE; + // } + } + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, L"Invalid move destination." ); + + // Goto hand cursor mode... + //*puiNewEvent = M_CHANGE_TO_HANDMODE; + + gfRTClickLeftHoldIntercepted = TRUE; + } } } } - //gfRTClickLeftHoldIntercepted = TRUE; - } - else - { - gfRTClickLeftHoldIntercepted = TRUE; } + } + } + //gfRTClickLeftHoldIntercepted = TRUE; + } + else + { + gfRTClickLeftHoldIntercepted = TRUE; + } #if 0 - fDone = FALSE; - if( GetSoldier( &pSoldier, gusUIFullTargetID ) && gpItemPointer == NULL ) - { - if( ( guiUIFullTargetFlags & OWNED_MERC ) && ( guiUIFullTargetFlags & VISIBLE_MERC ) && !( guiUIFullTargetFlags & DEAD_MERC ) &&( pSoldier->bAssignment >= ON_DUTY )&&!( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) - { - fShowAssignmentMenu = TRUE; - gfRTClickLeftHoldIntercepted = TRUE; - CreateDestroyAssignmentPopUpBoxes( ); - SetTacticalPopUpAssignmentBoxXY( ); - DetermineBoxPositions( ); - DetermineWhichAssignmentMenusCanBeShown( ); - fFirstClickInAssignmentScreenMask = TRUE; - gfIgnoreScrolling = TRUE; - - fDone = TRUE; - } - else - { - fShowAssignmentMenu = FALSE; - CreateDestroyAssignmentPopUpBoxes( ); - DetermineWhichAssignmentMenusCanBeShown( ); - } - } - - if( fDone == TRUE ) - { - break; - } -#endif - break; - - - case LOOKCURSOR_MODE: - // If we cannot actually do anything, return to movement mode - *puiNewEvent = LC_LOOK; - break; - - case JUMPOVER_MODE: - - *puiNewEvent = JP_JUMP; - break; - - case TALKCURSOR_MODE: - - PauseRT( FALSE ); - - if ( HandleTalkInit( ) ) - { - *puiNewEvent = TA_TALKINGMENU; - } - break; - - case GETTINGITEM_MODE: - - // Remove menu! - // RemoveItemPickupMenu( ); - break; - - case TALKINGMENU_MODE: - - //HandleTalkingMenuEscape( TRUE ); - break; - - case EXITSECTORMENU_MODE: - - RemoveSectorExitMenu( FALSE ); - break; - - case OPENDOOR_MENU_MODE: - - CancelOpenDoorMenu( ); - HandleOpenDoorMenu( ); - *puiNewEvent = A_CHANGE_TO_MOVE; - break; - - case RUBBERBAND_MODE: - - EndRubberBanding( ); - *puiNewEvent = A_CHANGE_TO_MOVE; - break; + fDone = FALSE; + if( GetSoldier( &pSoldier, gusUIFullTargetID ) && gpItemPointer == NULL ) + { + if( ( guiUIFullTargetFlags & OWNED_MERC ) && ( guiUIFullTargetFlags & VISIBLE_MERC ) && !( guiUIFullTargetFlags & DEAD_MERC ) &&( pSoldier->bAssignment >= ON_DUTY )&&!( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) + { + fShowAssignmentMenu = TRUE; + gfRTClickLeftHoldIntercepted = TRUE; + CreateDestroyAssignmentPopUpBoxes( ); + SetTacticalPopUpAssignmentBoxXY( ); + DetermineBoxPositions( ); + DetermineWhichAssignmentMenusCanBeShown( ); + fFirstClickInAssignmentScreenMask = TRUE; + gfIgnoreScrolling = TRUE; + fDone = TRUE; + } + else + { + fShowAssignmentMenu = FALSE; + CreateDestroyAssignmentPopUpBoxes( ); + DetermineWhichAssignmentMenusCanBeShown( ); + } } - } + if( fDone == TRUE ) + { + break; + } +#endif + break; + + + case LOOKCURSOR_MODE: + // If we cannot actually do anything, return to movement mode + *puiNewEvent = LC_LOOK; + break; + + case JUMPOVER_MODE: + + *puiNewEvent = JP_JUMP; + break; + + case TALKCURSOR_MODE: + + PauseRT( FALSE ); + + if ( HandleTalkInit( ) ) + { + *puiNewEvent = TA_TALKINGMENU; + } + break; + + case GETTINGITEM_MODE: + + // Remove menu! + // RemoveItemPickupMenu( ); + break; + + case TALKINGMENU_MODE: + + //HandleTalkingMenuEscape( TRUE ); + break; + + case EXITSECTORMENU_MODE: + + RemoveSectorExitMenu( FALSE ); + break; + + case OPENDOOR_MENU_MODE: + + CancelOpenDoorMenu( ); + HandleOpenDoorMenu( ); + *puiNewEvent = A_CHANGE_TO_MOVE; + break; + + case RUBBERBAND_MODE: + + EndRubberBanding( ); + *puiNewEvent = A_CHANGE_TO_MOVE; + break; + + } } + } } } } + } } } @@ -893,7 +895,7 @@ void QueryRTLeftButton( UINT32 *puiNewEvent ) fDoubleClickIntercepted = FALSE; fCanCheckForSpeechAdvance = FALSE; gfStartLookingForRubberBanding = FALSE; - + // Reset counter RESETCOUNTER( LMOUSECLICK_DELAY_COUNTER ); @@ -933,9 +935,9 @@ void QueryRTRightButton( UINT32 *puiNewEvent ) SOLDIERTYPE *pSoldier; UINT16 usMapPos; - if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) + if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) { - if (!GetMouseMapPos( (INT16 *)&usMapPos ) ) + if (!GetMouseMapPos( &usMapPos ) ) { return; } @@ -963,34 +965,34 @@ void QueryRTRightButton( UINT32 *puiNewEvent ) { switch( gCurrentUIMode ) { - case CONFIRM_MOVE_MODE: - case MOVE_MODE: + case CONFIRM_MOVE_MODE: + case MOVE_MODE: - if ( !gfUIAllMoveOn ) + if ( !gfUIAllMoveOn ) + { + fValidDoubleClickPossible = TRUE; + + // OK, our first right-click is an all-cycle + if ( gfUICanBeginAllMoveCycle ) { - fValidDoubleClickPossible = TRUE; - - // OK, our first right-click is an all-cycle - if ( gfUICanBeginAllMoveCycle ) + // ATE: Here, check if we can do this.... + if ( !UIOKMoveDestination( MercPtrs[ gusSelectedSoldier ], usMapPos ) ) { - // ATE: Here, check if we can do this.... - if ( !UIOKMoveDestination( MercPtrs[ gusSelectedSoldier ], usMapPos ) ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANT_MOVE_THERE_STR ] ); - gfRTClickLeftHoldIntercepted = TRUE; - } - //else if ( gsCurrentActionPoints == 0 ) - //{ - // ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); - // gfRTClickLeftHoldIntercepted = TRUE; - //} - else - { - *puiNewEvent = M_CYCLE_MOVE_ALL; - } + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANT_MOVE_THERE_STR ] ); + gfRTClickLeftHoldIntercepted = TRUE; + } + //else if ( gsCurrentActionPoints == 0 ) + //{ + // ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); + // gfRTClickLeftHoldIntercepted = TRUE; + //} + else + { + *puiNewEvent = M_CYCLE_MOVE_ALL; } - fClickHoldIntercepted = TRUE; } + fClickHoldIntercepted = TRUE; + } } // ATE: Added cancel of burst mode.... @@ -1009,60 +1011,60 @@ void QueryRTRightButton( UINT32 *puiNewEvent ) } else { - // IF HERE, DO A CLICK-HOLD IF IN INTERVAL - if ( COUNTERDONE( RMOUSECLICK_DELAY_COUNTER ) && !fClickHoldIntercepted ) + // IF HERE, DO A CLICK-HOLD IF IN INTERVAL + if ( COUNTERDONE( RMOUSECLICK_DELAY_COUNTER ) && !fClickHoldIntercepted ) + { + if ( gpItemPointer == NULL ) { - if ( gpItemPointer == NULL ) + // Switch on UI mode + switch( gCurrentUIMode ) { - // Switch on UI mode - switch( gCurrentUIMode ) + case IDLE_MODE: + case ACTION_MODE: + case HANDCURSOR_MODE: + case LOOKCURSOR_MODE: + case TALKCURSOR_MODE: + case MOVE_MODE: + + if ( GetSoldier( &pSoldier, gusSelectedSoldier ) ) { - case IDLE_MODE: - case ACTION_MODE: - case HANDCURSOR_MODE: - case LOOKCURSOR_MODE: - case TALKCURSOR_MODE: - case MOVE_MODE: - - if ( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + if ( ( guiUIFullTargetFlags & OWNED_MERC ) && ( guiUIFullTargetFlags & VISIBLE_MERC ) && !( guiUIFullTargetFlags & DEAD_MERC )&&!( pSoldier ? pSoldier->uiStatusFlags & SOLDIER_VEHICLE : 0 ) ) + { + //if( pSoldier->bAssignment >= ON_DUTY ) { - if ( ( guiUIFullTargetFlags & OWNED_MERC ) && ( guiUIFullTargetFlags & VISIBLE_MERC ) && !( guiUIFullTargetFlags & DEAD_MERC )&&!( pSoldier ? pSoldier->uiStatusFlags & SOLDIER_VEHICLE : 0 ) ) - { - //if( pSoldier->bAssignment >= ON_DUTY ) - { - PopupAssignmentMenuInTactical( pSoldier ); - fClickHoldIntercepted = TRUE; - } - break; - } - else - { - fShowAssignmentMenu = FALSE; - CreateDestroyAssignmentPopUpBoxes( ); - DetermineWhichAssignmentMenusCanBeShown( ); - - fShowMilitiaControlMenu = FALSE; - CreateDestroyMilitiaControlPopUpBoxes( ); - DetermineWhichMilitiaControlMenusCanBeShown( ); - } - - // ATE: - if ( !fClickHoldIntercepted ) - { - *puiNewEvent = U_MOVEMENT_MENU; - fClickHoldIntercepted = TRUE; - } - break; + PopupAssignmentMenuInTactical( pSoldier ); + fClickHoldIntercepted = TRUE; } - } + break; + } + else + { + fShowAssignmentMenu = FALSE; + CreateDestroyAssignmentPopUpBoxes( ); + DetermineWhichAssignmentMenusCanBeShown( ); - if ( gCurrentUIMode == ACTION_MODE || gCurrentUIMode == TALKCURSOR_MODE ) - { - PauseRT( FALSE ); + fShowMilitiaControlMenu = FALSE; + CreateDestroyMilitiaControlPopUpBoxes( ); + DetermineWhichMilitiaControlMenusCanBeShown( ); + } + + // ATE: + if ( !fClickHoldIntercepted ) + { + *puiNewEvent = U_MOVEMENT_MENU; + fClickHoldIntercepted = TRUE; + } + break; } } + + if ( gCurrentUIMode == ACTION_MODE || gCurrentUIMode == TALKCURSOR_MODE ) + { + PauseRT( FALSE ); + } } - + } + } } @@ -1076,36 +1078,36 @@ void QueryRTRightButton( UINT32 *puiNewEvent ) // CHECK HERE FOR DOUBLE CLICK EVENTS if ( fValidDoubleClickPossible ) { - fDoubleClickIntercepted = TRUE; + fDoubleClickIntercepted = TRUE; - // Do stuff.... - // OK, check if left button down... - if ( fLeftButtonDown ) + // Do stuff.... + // OK, check if left button down... + if ( fLeftButtonDown ) + { + if ( gpItemPointer == NULL ) { - if ( gpItemPointer == NULL ) + if ( !fClickIntercepted && !fClickHoldIntercepted ) { - if ( !fClickIntercepted && !fClickHoldIntercepted ) + // ATE: + if ( gusSelectedSoldier != NOBODY ) { - // ATE: - if ( gusSelectedSoldier != NOBODY ) + //fIgnoreLeftUp = TRUE; + switch( gCurrentUIMode ) { - //fIgnoreLeftUp = TRUE; - switch( gCurrentUIMode ) - { - case CONFIRM_MOVE_MODE: - case MOVE_MODE: + case CONFIRM_MOVE_MODE: + case MOVE_MODE: - if ( gfUIAllMoveOn ) - { - // OK, now we wish to run! - gfUIAllMoveOn = 2; - } + if ( gfUIAllMoveOn ) + { + // OK, now we wish to run! + gfUIAllMoveOn = 2; } } - } + } } + } } } @@ -1129,14 +1131,14 @@ void QueryRTRightButton( UINT32 *puiNewEvent ) //fIgnoreLeftUp = TRUE; switch( gCurrentUIMode ) { - case CONFIRM_MOVE_MODE: - case MOVE_MODE: + case CONFIRM_MOVE_MODE: + case MOVE_MODE: - if ( gfUIAllMoveOn ) - { - gfUIAllMoveOn = FALSE; - gfUICanBeginAllMoveCycle = TRUE; - } + if ( gfUIAllMoveOn ) + { + gfUIAllMoveOn = FALSE; + gfUICanBeginAllMoveCycle = TRUE; + } } } @@ -1155,54 +1157,54 @@ void QueryRTRightButton( UINT32 *puiNewEvent ) // Switch on UI mode switch( gCurrentUIMode ) { - case IDLE_MODE: + case IDLE_MODE: - break; + break; - case CONFIRM_MOVE_MODE: - case MOVE_MODE: - case TALKCURSOR_MODE: + case CONFIRM_MOVE_MODE: + case MOVE_MODE: + case TALKCURSOR_MODE: - { - // We have here a change to action mode - *puiNewEvent = M_CHANGE_TO_ACTION; - } - fClickIntercepted = TRUE; - break; + { + // We have here a change to action mode + *puiNewEvent = M_CHANGE_TO_ACTION; + } + fClickIntercepted = TRUE; + break; - case ACTION_MODE: + case ACTION_MODE: - // We have here a change to move mode - *puiNewEvent = A_END_ACTION; - fClickIntercepted = TRUE; - break; + // We have here a change to move mode + *puiNewEvent = A_END_ACTION; + fClickIntercepted = TRUE; + break; - case CONFIRM_ACTION_MODE: + case CONFIRM_ACTION_MODE: - if ( GetSoldier( &pSoldier, gusSelectedSoldier ) ) - { - HandleRightClickAdjustCursor( pSoldier, usMapPos ); - } - fClickIntercepted = TRUE; - break; + if ( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + { + HandleRightClickAdjustCursor( pSoldier, usMapPos ); + } + fClickIntercepted = TRUE; + break; - case MENU_MODE: + case MENU_MODE: - // If we get a hit here and we're in menu mode, quit the menu mode - EndMenuEvent( guiCurrentEvent ); - fClickIntercepted = TRUE; - break; + // If we get a hit here and we're in menu mode, quit the menu mode + EndMenuEvent( guiCurrentEvent ); + fClickIntercepted = TRUE; + break; - case HANDCURSOR_MODE: - // If we cannot actually do anything, return to movement mode - *puiNewEvent = A_CHANGE_TO_MOVE; - break; + case HANDCURSOR_MODE: + // If we cannot actually do anything, return to movement mode + *puiNewEvent = A_CHANGE_TO_MOVE; + break; - case LOOKCURSOR_MODE: + case LOOKCURSOR_MODE: - // If we cannot actually do anything, return to movement mode - *puiNewEvent = A_CHANGE_TO_MOVE; - break; + // If we cannot actually do anything, return to movement mode + *puiNewEvent = A_CHANGE_TO_MOVE; + break; } } @@ -1218,7 +1220,7 @@ void QueryRTRightButton( UINT32 *puiNewEvent ) } } - // Reset flag + // Reset flag fRightButtonDown = FALSE; fClickHoldIntercepted = FALSE; fClickIntercepted = FALSE; @@ -1250,12 +1252,12 @@ void GetRTMousePositionInput( UINT32 *puiNewEvent ) static BOOLEAN fOnValidGuy = FALSE; - if (!GetMouseMapPos( (INT16 *)&usMapPos ) ) + if (!GetMouseMapPos( &usMapPos ) ) { return; } - if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) + if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) { // Handle highlighting stuff HandleObjectHighlighting( ); @@ -1263,288 +1265,288 @@ void GetRTMousePositionInput( UINT32 *puiNewEvent ) // Check if we have an item in our hands... if ( gpItemPointer != NULL ) { - *puiNewEvent = A_ON_TERRAIN; - return; + *puiNewEvent = A_ON_TERRAIN; + return; } // Switch on modes switch( gCurrentUIMode ) { - case RUBBERBAND_MODE: + case RUBBERBAND_MODE: - // ATE: Make sure! - if ( gRubberBandActive == FALSE ) - { - *puiNewEvent = M_ON_TERRAIN; - } - else - { - *puiNewEvent = RB_ON_TERRAIN; - } - break; - - case JUMPOVER_MODE: - - // ATE: Make sure! - if ( gsJumpOverGridNo != usMapPos ) - { - *puiNewEvent = A_CHANGE_TO_MOVE; - } - else - { - *puiNewEvent = JP_ON_TERRAIN; - } - break; - - case LOCKUI_MODE: - *puiNewEvent = LU_ON_TERRAIN; - break; - - case IDLE_MODE: - *puiNewEvent = I_ON_TERRAIN; - break; - - case ENEMYS_TURN_MODE: - *puiNewEvent = ET_ON_TERRAIN; - break; - - case LOOKCURSOR_MODE: - *puiNewEvent = LC_ON_TERRAIN; - break; - - case TALKCURSOR_MODE: - - if ( uiMoveTargetSoldierId != NOBODY ) - { - if( gfUIFullTargetFound ) - { - if ( gusUIFullTargetID != uiMoveTargetSoldierId ) - { - *puiNewEvent = A_CHANGE_TO_MOVE; - return; - } - } - else - { - *puiNewEvent = A_CHANGE_TO_MOVE; - return; - } - } - *puiNewEvent = T_ON_TERRAIN; - break; - - case GETTINGITEM_MODE: - - break; - - case TALKINGMENU_MODE: - - if ( HandleTalkingMenu( ) ) - { - *puiNewEvent = A_CHANGE_TO_MOVE; - } - break; - - case EXITSECTORMENU_MODE: - - if ( HandleSectorExitMenu( ) ) - { - *puiNewEvent = A_CHANGE_TO_MOVE; - } - break; - - case OPENDOOR_MENU_MODE: - - if ( HandleOpenDoorMenu( ) ) - { - *puiNewEvent = A_CHANGE_TO_MOVE; - } - break; - - case HANDCURSOR_MODE: - - *puiNewEvent = HC_ON_TERRAIN; - break; - - case MOVE_MODE: - - if ( usMapPos != usOldMapPos ) - { - // Set off ALL move.... - gfUIAllMoveOn = FALSE; - } - - uiMoveTargetSoldierId = NO_SOLDIER; - - // Check for being on terrain - if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) - { - UINT16 usItem; - UINT8 ubItemCursor; - - // Alrighty, check what's in our hands = if a 'friendly thing', like med kit, look for our own guys - usItem = pSoldier->inv[HANDPOS].usItem; - - // get cursor for item - ubItemCursor = GetActionModeCursor( pSoldier ); - - // - if ( IsValidJumpLocation( pSoldier, usMapPos, TRUE ) ) - { - *puiNewEvent = JP_ON_TERRAIN; - gsJumpOverGridNo = usMapPos; - return; - } - else - { - if( gfUIFullTargetFound ) - { - if ( IsValidTalkableNPC( (UINT8)gusUIFullTargetID, FALSE, FALSE, FALSE ) && !_KeyDown( SHIFT ) && !AM_AN_EPC( pSoldier ) && MercPtrs[ gusUIFullTargetID ]->bTeam != ENEMY_TEAM && !ValidQuickExchangePosition( ) ) - { - uiMoveTargetSoldierId = gusUIFullTargetID; - *puiNewEvent = T_CHANGE_TO_TALKING; - return; - } - else if ( ubItemCursor == AIDCURS ) - { - // IF it's an ememy, goto confirm action mode - if ( ( guiUIFullTargetFlags & OWNED_MERC ) && ( guiUIFullTargetFlags & VISIBLE_MERC ) && !( guiUIFullTargetFlags & DEAD_MERC ) ) - { - //uiMoveTargetSoldierId = gusUIFullTargetID; - //*puiNewEvent = A_ON_TERRAIN; - //return; - } - } - else - { - // IF it's an ememy, goto confirm action mode - if ( ( guiUIFullTargetFlags & ENEMY_MERC ) && ( guiUIFullTargetFlags & VISIBLE_MERC ) && !( guiUIFullTargetFlags & DEAD_MERC ) ) - { - uiMoveTargetSoldierId = gusUIFullTargetID; - *puiNewEvent = A_ON_TERRAIN; - return; - } - } - } - } - } + // ATE: Make sure! + if ( gRubberBandActive == FALSE ) + { *puiNewEvent = M_ON_TERRAIN; - break; + } + else + { + *puiNewEvent = RB_ON_TERRAIN; + } + break; - case ACTION_MODE: + case JUMPOVER_MODE: - // First check if we are on a guy, if so, make selected if it's ours - // Check if the guy is visible - guiUITargetSoldierId = NOBODY; + // ATE: Make sure! + if ( gsJumpOverGridNo != usMapPos ) + { + *puiNewEvent = A_CHANGE_TO_MOVE; + } + else + { + *puiNewEvent = JP_ON_TERRAIN; + } + break; - fOnValidGuy = FALSE; + case LOCKUI_MODE: + *puiNewEvent = LU_ON_TERRAIN; + break; - if ( gfUIFullTargetFound ) - //if ( gfUIFullTargetFound ) + case IDLE_MODE: + *puiNewEvent = I_ON_TERRAIN; + break; + + case ENEMYS_TURN_MODE: + *puiNewEvent = ET_ON_TERRAIN; + break; + + case LOOKCURSOR_MODE: + *puiNewEvent = LC_ON_TERRAIN; + break; + + case TALKCURSOR_MODE: + + if ( uiMoveTargetSoldierId != NOBODY ) + { + if( gfUIFullTargetFound ) { - if ( IsValidTargetMerc( (UINT8)gusUIFullTargetID ) ) - { - guiUITargetSoldierId = gusUIFullTargetID; - - if ( MercPtrs[ gusUIFullTargetID ]->bTeam != gbPlayerNum ) - { - fOnValidGuy = TRUE; - } - else - { - if ( gUIActionModeChangeDueToMouseOver ) - { - *puiNewEvent = A_CHANGE_TO_MOVE; - return; - } - } - } - } - else - { - if ( gUIActionModeChangeDueToMouseOver ) + if ( gusUIFullTargetID != uiMoveTargetSoldierId ) { *puiNewEvent = A_CHANGE_TO_MOVE; return; } } - *puiNewEvent = A_ON_TERRAIN; - break; - - case CONFIRM_MOVE_MODE: - - if ( usMapPos != usOldMapPos ) + else { - // Switch event out of confirm mode - // Set off ALL move.... - gfUIAllMoveOn = FALSE; - *puiNewEvent = A_CHANGE_TO_MOVE; + return; } - break; + } + *puiNewEvent = T_ON_TERRAIN; + break; - case CONFIRM_ACTION_MODE: + case GETTINGITEM_MODE: - // DONOT CANCEL IF BURST - if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + break; + + case TALKINGMENU_MODE: + + if ( HandleTalkingMenu( ) ) + { + *puiNewEvent = A_CHANGE_TO_MOVE; + } + break; + + case EXITSECTORMENU_MODE: + + if ( HandleSectorExitMenu( ) ) + { + *puiNewEvent = A_CHANGE_TO_MOVE; + } + break; + + case OPENDOOR_MENU_MODE: + + if ( HandleOpenDoorMenu( ) ) + { + *puiNewEvent = A_CHANGE_TO_MOVE; + } + break; + + case HANDCURSOR_MODE: + + *puiNewEvent = HC_ON_TERRAIN; + break; + + case MOVE_MODE: + + if ( usMapPos != usOldMapPos ) + { + // Set off ALL move.... + gfUIAllMoveOn = FALSE; + } + + uiMoveTargetSoldierId = NO_SOLDIER; + + // Check for being on terrain + if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + { + UINT16 usItem; + UINT8 ubItemCursor; + + // Alrighty, check what's in our hands = if a 'friendly thing', like med kit, look for our own guys + usItem = pSoldier->inv[HANDPOS].usItem; + + // get cursor for item + ubItemCursor = GetActionModeCursor( pSoldier ); + + // + if ( IsValidJumpLocation( pSoldier, usMapPos, TRUE ) ) { - if ( pSoldier->bDoBurst ) + *puiNewEvent = JP_ON_TERRAIN; + gsJumpOverGridNo = usMapPos; + return; + } + else + { + if( gfUIFullTargetFound ) { - pSoldier->sEndGridNo = usMapPos; - - - if ( pSoldier->sEndGridNo != pSoldier->sStartGridNo && fLeftButtonDown ) + if ( IsValidTalkableNPC( (UINT8)gusUIFullTargetID, FALSE, FALSE, FALSE ) && !_KeyDown( SHIFT ) && !AM_AN_EPC( pSoldier ) && MercPtrs[ gusUIFullTargetID ]->bTeam != ENEMY_TEAM && !ValidQuickExchangePosition( ) ) { - pSoldier->fDoSpread = TRUE; - gfBeginBurstSpreadTracking = TRUE; + uiMoveTargetSoldierId = gusUIFullTargetID; + *puiNewEvent = T_CHANGE_TO_TALKING; + return; } - - if ( pSoldier->fDoSpread ) + else if ( ubItemCursor == AIDCURS ) { - // Accumulate gridno - AccumulateBurstLocation( usMapPos ); - - *puiNewEvent = CA_ON_TERRAIN; - break; + // IF it's an ememy, goto confirm action mode + if ( ( guiUIFullTargetFlags & OWNED_MERC ) && ( guiUIFullTargetFlags & VISIBLE_MERC ) && !( guiUIFullTargetFlags & DEAD_MERC ) ) + { + //uiMoveTargetSoldierId = gusUIFullTargetID; + //*puiNewEvent = A_ON_TERRAIN; + //return; + } + } + else + { + // IF it's an ememy, goto confirm action mode + if ( ( guiUIFullTargetFlags & ENEMY_MERC ) && ( guiUIFullTargetFlags & VISIBLE_MERC ) && !( guiUIFullTargetFlags & DEAD_MERC ) ) + { + uiMoveTargetSoldierId = gusUIFullTargetID; + *puiNewEvent = A_ON_TERRAIN; + return; + } } } } + } + *puiNewEvent = M_ON_TERRAIN; + break; - // First check if we are on a guy, if so, make selected if it's ours - if ( gfUIFullTargetFound ) - { - if ( guiUITargetSoldierId != gusUIFullTargetID ) - { - // Switch event out of confirm mode - *puiNewEvent = CA_END_CONFIRM_ACTION; - } - else - { - *puiNewEvent = CA_ON_TERRAIN; - } - } - else + case ACTION_MODE: + + // First check if we are on a guy, if so, make selected if it's ours + // Check if the guy is visible + guiUITargetSoldierId = NOBODY; + + fOnValidGuy = FALSE; + + if ( gfUIFullTargetFound ) + //if ( gfUIFullTargetFound ) + { + if ( IsValidTargetMerc( (UINT8)gusUIFullTargetID ) ) { - if ( ConfirmActionCancel( usMapPos, usOldMapPos ) ) - { - // Switch event out of confirm mode - *puiNewEvent = CA_END_CONFIRM_ACTION; + guiUITargetSoldierId = gusUIFullTargetID; + if ( MercPtrs[ gusUIFullTargetID ]->bTeam != gbPlayerNum ) + { + fOnValidGuy = TRUE; } else { - *puiNewEvent = CA_ON_TERRAIN; + if ( gUIActionModeChangeDueToMouseOver ) + { + *puiNewEvent = A_CHANGE_TO_MOVE; + return; + } } } - break; - + } + else + { + if ( gUIActionModeChangeDueToMouseOver ) + { + *puiNewEvent = A_CHANGE_TO_MOVE; + return; + } + } + *puiNewEvent = A_ON_TERRAIN; + break; + + case CONFIRM_MOVE_MODE: + + if ( usMapPos != usOldMapPos ) + { + // Switch event out of confirm mode + // Set off ALL move.... + gfUIAllMoveOn = FALSE; + + *puiNewEvent = A_CHANGE_TO_MOVE; + } + break; + + case CONFIRM_ACTION_MODE: + + // DONOT CANCEL IF BURST + if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + { + if ( pSoldier->bDoBurst ) + { + pSoldier->sEndGridNo = usMapPos; + + + if ( pSoldier->sEndGridNo != pSoldier->sStartGridNo && fLeftButtonDown ) + { + pSoldier->fDoSpread = TRUE; + gfBeginBurstSpreadTracking = TRUE; + } + + if ( pSoldier->fDoSpread ) + { + // Accumulate gridno + AccumulateBurstLocation( usMapPos ); + + *puiNewEvent = CA_ON_TERRAIN; + break; + } + } + } + + // First check if we are on a guy, if so, make selected if it's ours + if ( gfUIFullTargetFound ) + { + if ( guiUITargetSoldierId != gusUIFullTargetID ) + { + // Switch event out of confirm mode + *puiNewEvent = CA_END_CONFIRM_ACTION; + } + else + { + *puiNewEvent = CA_ON_TERRAIN; + } + } + else + { + if ( ConfirmActionCancel( usMapPos, usOldMapPos ) ) + { + // Switch event out of confirm mode + *puiNewEvent = CA_END_CONFIRM_ACTION; + + } + else + { + *puiNewEvent = CA_ON_TERRAIN; + } + } + break; + } //if ( gCurrentUIMode != CONFIRM_ACTION_MODE ) //{ // if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) // { - // Change refine value back to 1 + // Change refine value back to 1 /// pSoldier->bShownAimTime = REFINE_AIM_1; // } //} diff --git a/Tactical/Rotting Corpses.cpp b/Tactical/Rotting Corpses.cpp index 080a0d62..e966a6ad 100644 --- a/Tactical/Rotting Corpses.cpp +++ b/Tactical/Rotting Corpses.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Tactical All.h" #else + #include "builddefines.h" #include #include #include "wcheck.h" @@ -34,6 +35,14 @@ #include "World Items.h" #include "explosion control.h" #include "GameSettings.h" + #include "Interface Items.h" + #include "Soldier Profile.h" + #include "Soldier macros.h" + #include "Keys.h" + #include "Render Fun.h" + #include "strategic.h" + #include "qarray.h" + #include "Interface.h" #endif #define CORPSE_WARNING_MAX 5 @@ -951,6 +960,13 @@ BOOLEAN TurnSoldierIntoCorpse( SOLDIERTYPE *pSoldier, BOOLEAN fRemoveMerc, BOOLE if( pSoldier->bTeam == ENEMY_TEAM ) Corpse.ubAIWarningValue = 20; + // This should free up ABC for death codes + if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_ATTACK ) + { + DebugAttackBusy( "%%%%%%%%% Freeing up attacker because soldier became a corpse.\n"); + ReduceAttackBusyCount( ); + } + //if we are to call TacticalRemoveSoldier after adding the corpse if( fRemoveMerc ) { diff --git a/Tactical/ShopKeeper Interface.cpp b/Tactical/ShopKeeper Interface.cpp index b5273cf6..e3892a15 100644 --- a/Tactical/ShopKeeper Interface.cpp +++ b/Tactical/ShopKeeper Interface.cpp @@ -45,6 +45,13 @@ #include "MessageBoxScreen.h" #include "LINE.H" #include "Drugs and Alcohol.h" + #include "Map Screen Interface.h" + #include "Soldier macros.h" + #include "armsdealerinvinit.h" + #include "opplist.h" + #include "los.h" + #include "NPC.h" + #include "Soldier Create.h" #endif #include "BuildDefines.h" @@ -2618,8 +2625,8 @@ UINT32 DisplayInvSlot( UINT8 ubSlotNum, UINT16 usItemIndex, UINT16 usPosX, UINT1 usHeight = (UINT32)pTrav->usHeight; usWidth = (UINT32)pTrav->usWidth; - sCenX = usPosX + 7 + (INT16)( abs( SKI_INV_WIDTH - 3.0 - usWidth ) / 2 ) - pTrav->sOffsetX; - sCenY = usPosY + (INT16)( abs( SKI_INV_HEIGHT - (double)usHeight ) / 2 ) - pTrav->sOffsetY; + sCenX = usPosX + 7 + (INT16)( abs( SKI_INV_WIDTH - 3 - usWidth ) / 2 ) - pTrav->sOffsetX; + sCenY = usPosY + (INT16)( abs( SKI_INV_HEIGHT - usHeight ) / 2 ) - pTrav->sOffsetY; //Restore the background region diff --git a/Tactical/Soldier Add.cpp b/Tactical/Soldier Add.cpp index e9b85794..ab57cdad 100644 --- a/Tactical/Soldier Add.cpp +++ b/Tactical/Soldier Add.cpp @@ -18,6 +18,9 @@ #include "fov.h" #include "pathai.h" #include "Random.h" + #include "Render Fun.h" + #include "meanwhile.h" + #include "Exit Grids.h" #endif // Adds a soldier to a world gridno and set's direction diff --git a/Tactical/Soldier Ani.cpp b/Tactical/Soldier Ani.cpp index 27f07510..d7d4fb29 100644 --- a/Tactical/Soldier Ani.cpp +++ b/Tactical/Soldier Ani.cpp @@ -1,60 +1,66 @@ #ifdef PRECOMPILEDHEADERS - #include "Tactical All.h" +#include "Tactical All.h" #else - #include - #include - #include "wcheck.h" - #include "stdlib.h" - #include "debug.h" - #include "MemMan.h" - #include "Overhead Types.h" - #include "Soldier Control.h" - #include "Animation Cache.h" - #include "Animation Data.h" - #include "Animation Control.h" - #include "weapons.h" - #include "soldier ani.h" - #include "Random.h" - #include "video.h" - #include "vobject_blitters.h" - #include "Sound Control.h" - #include "isometric utils.h" - #include "Handle UI.h" - #include "Event Pump.h" - #include "opplist.h" - #include "lighting.h" - #include "ai.h" - #include "renderworld.h" - #include "interactive tiles.h" - #include "points.h" - #include "message.h" - #include "world items.h" - #include "physics.h" - #include "soldier create.h" - #include "dialogue control.h" - #include "soldier functions.h" - #include "rotting corpses.h" - #include "merc entering.h" - #include "soldier add.h" - #include "soldier profile.h" - #include "soldier functions.h" - #include "interface.h" - #include "qarray.h" - #include "soldier macros.h" - #include "Strategic Town Loyalty.h" - #include "Squads.h" - #include "worldman.h" - #include "structure wrap.h" - #include "pathai.h" - #include "pits.h" - #include "text.h" - #include "npc.h" - #include "meanwhile.h" - #include "Explosion Control.h" - #include "fov.h" - #include "campaign.h" - #include "los.h" - #include "GameSettings.h" +#include +#include +#include "wcheck.h" +#include "stdlib.h" +#include "debug.h" +#include "MemMan.h" +#include "Overhead Types.h" +#include "Soldier Control.h" +#include "Animation Cache.h" +#include "Animation Data.h" +#include "Animation Control.h" +#include "weapons.h" +#include "soldier ani.h" +#include "Random.h" +#include "video.h" +#include "vobject_blitters.h" +#include "Sound Control.h" +#include "isometric utils.h" +#include "Handle UI.h" +#include "Event Pump.h" +#include "opplist.h" +#include "lighting.h" +#include "ai.h" +#include "renderworld.h" +#include "interactive tiles.h" +#include "points.h" +#include "message.h" +#include "world items.h" +#include "physics.h" +#include "soldier create.h" +#include "dialogue control.h" +#include "soldier functions.h" +#include "rotting corpses.h" +#include "merc entering.h" +#include "soldier add.h" +#include "soldier profile.h" +#include "soldier functions.h" +#include "interface.h" +#include "qarray.h" +#include "soldier macros.h" +#include "Strategic Town Loyalty.h" +#include "Squads.h" +#include "worldman.h" +#include "structure wrap.h" +#include "pathai.h" +#include "pits.h" +#include "text.h" +#include "npc.h" +#include "meanwhile.h" +#include "Explosion Control.h" +#include "fov.h" +#include "campaign.h" +#include "los.h" +#include "GameSettings.h" +#include "Boxing.h" +#include "drugs and alcohol.h" +#include "Smell.h" +#include "GameSettings.h" +#include "interface dialogue.h" +#include "Strategic Status.h" #endif #define NO_JUMP 0 @@ -95,6 +101,16 @@ extern UINT8 gubInterruptProvoker; extern UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady ); +// Animation code explanations! +// +// 0-399: Actual animation frame indices +// 400-499: Object manipulation codes +// 500-598: Jump to frame x-501, same state. Obvious limit 0-97 +// 600-699: Jump to new state x-600, frame 0 +// 700-798: Play sound +// 800-999: Jump to new state x-700, frame 0 (starts with 100) +// + BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier ) { EV_S_FIREWEAPON SFireWeapon; @@ -116,10 +132,10 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier ) BOOLEAN bOKFireWeapon; BOOLEAN bWeaponJammed; BOOLEAN fFreeUpAttacker=FALSE; - UINT16 usUIMovementMode; + UINT16 usUIMovementMode; - do - { + do + { // Get new frame code sNewAniFrame = gusAnimInst[ pSoldier->usAnimState ][ pSoldier->usAniCode ]; @@ -133,7 +149,7 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier ) if ( pSoldier->iMuzFlash != -1 ) { LightSpriteDestroy( pSoldier->iMuzFlash ); - pSoldier->iMuzFlash = -1; + pSoldier->iMuzFlash = -1; } } else @@ -170,7 +186,7 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier ) UnSetUIBusy( pSoldier->ubID ); SoldierCollapse( pSoldier ); - + pSoldier->bBreathCollapsed = FALSE; return( TRUE ); @@ -181,7 +197,7 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier ) // Check for special code if ( sNewAniFrame < 399 ) { - + // Adjust / set true ani frame // Use -1 because ani files are 1-based, these are 0-based ConvertAniCodeToAniFrame( pSoldier, (INT16)( sNewAniFrame - 1 ) ); @@ -195,1010 +211,572 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier ) // Switch on special code switch( sNewAniFrame ) { - case 402: + case 402: - // DO NOT MOVE FOR THIS FRAME - pSoldier->fPausedMove = TRUE; - break; + // DO NOT MOVE FOR THIS FRAME + pSoldier->fPausedMove = TRUE; + break; - case 403: + case 403: - // MOVE GUY FORWARD SOME VALUE - MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)0.7 ); + // MOVE GUY FORWARD SOME VALUE + MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)0.7 ); - break; + break; - case 404: + case 404: - // MOVE GUY BACKWARD SOME VALUE - // Use same function as forward, but is -ve values! - MoveMercFacingDirection( pSoldier , TRUE, (FLOAT)1 ); - break; + // MOVE GUY BACKWARD SOME VALUE + // Use same function as forward, but is -ve values! + MoveMercFacingDirection( pSoldier , TRUE, (FLOAT)1 ); + break; - case 405: + case 405: - return( TRUE ); + return( TRUE ); - case 406: + case 406: - // Move merc up - if ( pSoldier->bDirection == NORTH ) - { - SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->sHeightAdjustment + 2 ) ); - } - else - { - SetSoldierHeight( pSoldier, (FLOAT)( pSoldier->sHeightAdjustment + 3 ) ); - } - break; - - case 408: - - // CODE: SPECIAL MOVE CLIMB UP ROOF EVENT - - // re-enable sight - gTacticalStatus.uiFlags &= (~DISALLOW_SIGHT); - { - INT16 sXPos, sYPos; - - //usNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc( pSoldier->bDirection ) ); - ConvertMapPosToWorldTileCenter( pSoldier->sTempNewGridNo, &sXPos, &sYPos ); - EVENT_SetSoldierPosition( pSoldier, (FLOAT)sXPos, (FLOAT)sYPos ); - } - // Move two CC directions - EVENT_SetSoldierDirection( pSoldier, gTwoCCDirection[ pSoldier->bDirection ] ); - - EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); - - // Set desired anim height! - pSoldier->ubDesiredHeight = ANIM_CROUCH; - - // Madd - usUIMovementMode = GetMoveStateBasedOnStance( pSoldier, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ); - pSoldier->usUIMovementMode = usUIMovementMode; - - // Move merc up specific height - SetSoldierHeight( pSoldier, (FLOAT)50 ); - - // ATE: Change interface level..... - // CJC: only if we are a player merc - if (pSoldier->bTeam == gbPlayerNum) - { - - if (gTacticalStatus.fAutoBandageMode) - { - // in autobandage, handle as AI, but add roof marker too - FreeUpNPCFromRoofClimb( pSoldier ); - HandlePlacingRoofMarker( pSoldier, pSoldier->sGridNo, TRUE, TRUE ); - } - else - { - // OK, UNSET INTERFACE FIRST - UnSetUIBusy( pSoldier->ubID ); - - if ( pSoldier->ubID == gusSelectedSoldier ) - { - ChangeInterfaceLevel( 1 ); - } - HandlePlacingRoofMarker( pSoldier, pSoldier->sGridNo, TRUE, TRUE ); - } - } - else + // Move merc up + if ( pSoldier->bDirection == NORTH ) + { + SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->sHeightAdjustment + 2 ) ); + } + else + { + SetSoldierHeight( pSoldier, (FLOAT)( pSoldier->sHeightAdjustment + 3 ) ); + } + break; + + case 408: + + // CODE: SPECIAL MOVE CLIMB UP ROOF EVENT + + // re-enable sight + gTacticalStatus.uiFlags &= (~DISALLOW_SIGHT); + { + INT16 sXPos, sYPos; + + //usNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc( pSoldier->bDirection ) ); + ConvertMapPosToWorldTileCenter( pSoldier->sTempNewGridNo, &sXPos, &sYPos ); + EVENT_SetSoldierPosition( pSoldier, (FLOAT)sXPos, (FLOAT)sYPos ); + } + // Move two CC directions + EVENT_SetSoldierDirection( pSoldier, gTwoCCDirection[ pSoldier->bDirection ] ); + + EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); + + // Set desired anim height! + pSoldier->ubDesiredHeight = ANIM_CROUCH; + + // Madd + usUIMovementMode = GetMoveStateBasedOnStance( pSoldier, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ); + pSoldier->usUIMovementMode = usUIMovementMode; + + // Move merc up specific height + SetSoldierHeight( pSoldier, (FLOAT)50 ); + + // ATE: Change interface level..... + // CJC: only if we are a player merc + if (pSoldier->bTeam == gbPlayerNum) + { + + if (gTacticalStatus.fAutoBandageMode) { + // in autobandage, handle as AI, but add roof marker too FreeUpNPCFromRoofClimb( pSoldier ); + HandlePlacingRoofMarker( pSoldier, pSoldier->sGridNo, TRUE, TRUE ); } - - // ATE: Handle sight... - HandleSight( pSoldier,SIGHT_LOOK | SIGHT_RADIO | SIGHT_INTERRUPT ); - break; - - case 409: - - //CODE: MOVE DOWN - SetSoldierHeight( pSoldier, (FLOAT)( pSoldier->sHeightAdjustment - 2 ) ); - break; - - case 410: - - // Move merc down specific height - SetSoldierHeight( pSoldier, (FLOAT)0 ); - break; - - case 411: - - // CODE: SPECIALMOVE CLIMB DOWN EVENT - // Move two C directions - EVENT_SetSoldierDirection( pSoldier, gTwoCDirection[ pSoldier->bDirection ] ); - - EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); - // Adjust height - SetSoldierHeight( pSoldier, (FLOAT)gClimbDownRoofStartDist[ pSoldier->ubBodyType ] ); - // Adjust position - MoveMercFacingDirection( pSoldier , TRUE, (FLOAT)3.5 ); - break; - - case 412: - - // CODE: HANDLING PRONE DOWN - NEED TO MOVE GUY BACKWARDS! - MoveMercFacingDirection( pSoldier , FALSE, (FLOAT).2 ); - break; - - case 413: - - // CODE: HANDLING PRONE UP - NEED TO MOVE GUY FORWARDS! - MoveMercFacingDirection( pSoldier , TRUE, (FLOAT).2 ); - break; - - case 430: - - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: case 430"); - // SHOOT GUN - // MAKE AN EVENT, BUT ONLY DO STUFF IF WE OWN THE GUY! - SFireWeapon.usSoldierID = pSoldier->ubID; - SFireWeapon.uiUniqueId = pSoldier->uiUniqueSoldierIdValue; - SFireWeapon.sTargetGridNo = pSoldier->sTargetGridNo; - SFireWeapon.bTargetLevel = pSoldier->bTargetLevel; - SFireWeapon.bTargetCubeLevel= pSoldier->bTargetCubeLevel; - AddGameEvent( S_FIREWEAPON, 0, &SFireWeapon ); - - //DIGICRAB: Burst UnCap - //Loop around in the animation if we still have burst rounds to fire - if (pSoldier->bDoBurst && (pSoldier->bDoBurst <= ((pSoldier->bDoAutofire)?(pSoldier->bDoAutofire):(GetShotsPerBurst(&pSoldier->inv[HANDPOS]))) || (( pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST && pSoldier->bDoBurst <= Weapon[GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS])].ubShotsPerBurst)) )) + else { - if(pSoldier->usAnimState == 44 || pSoldier->usAnimState == 109 || pSoldier->usAnimState == 108 && pSoldier->usAniCode == 33) //we are standing, crounching or prone, firing the fast shot - pSoldier->usAniCode = 3; - else if(pSoldier->usAnimState == 175 && pSoldier->usAniCode == 37) //we are firing down to something very close, last shot - pSoldier->usAniCode = 14; - } + // OK, UNSET INTERFACE FIRST + UnSetUIBusy( pSoldier->ubID ); - //DIGICRAB: Burst Sound - //This code is stolen from Tactical\Weapons.c - UseGun(...) - if (pSoldier->bDoBurst && pSoldier->iBurstSoundID == NO_SAMPLE && Weapon[ pSoldier->usAttackingWeapon ].sSound != 0 && Item[ pSoldier->usAttackingWeapon ].usItemClass != IC_THROWING_KNIFE ) + if ( pSoldier->ubID == gusSelectedSoldier ) + { + ChangeInterfaceLevel( 1 ); + } + HandlePlacingRoofMarker( pSoldier, pSoldier->sGridNo, TRUE, TRUE ); + } + } + else + { + FreeUpNPCFromRoofClimb( pSoldier ); + } + + // ATE: Handle sight... + HandleSight( pSoldier,SIGHT_LOOK | SIGHT_RADIO | SIGHT_INTERRUPT ); + break; + + case 409: + + //CODE: MOVE DOWN + SetSoldierHeight( pSoldier, (FLOAT)( pSoldier->sHeightAdjustment - 2 ) ); + break; + + case 410: + + // Move merc down specific height + SetSoldierHeight( pSoldier, (FLOAT)0 ); + break; + + case 411: + + // CODE: SPECIALMOVE CLIMB DOWN EVENT + // Move two C directions + EVENT_SetSoldierDirection( pSoldier, gTwoCDirection[ pSoldier->bDirection ] ); + + EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); + // Adjust height + SetSoldierHeight( pSoldier, (FLOAT)gClimbDownRoofStartDist[ pSoldier->ubBodyType ] ); + // Adjust position + MoveMercFacingDirection( pSoldier , TRUE, (FLOAT)3.5 ); + break; + + case 412: + + // CODE: HANDLING PRONE DOWN - NEED TO MOVE GUY BACKWARDS! + MoveMercFacingDirection( pSoldier , FALSE, (FLOAT).2 ); + break; + + case 413: + + // CODE: HANDLING PRONE UP - NEED TO MOVE GUY FORWARDS! + MoveMercFacingDirection( pSoldier , TRUE, (FLOAT).2 ); + break; + + case 430: + + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: case 430"); + // SHOOT GUN + // MAKE AN EVENT, BUT ONLY DO STUFF IF WE OWN THE GUY! + SFireWeapon.usSoldierID = pSoldier->ubID; + SFireWeapon.uiUniqueId = pSoldier->uiUniqueSoldierIdValue; + SFireWeapon.sTargetGridNo = pSoldier->sTargetGridNo; + SFireWeapon.bTargetLevel = pSoldier->bTargetLevel; + SFireWeapon.bTargetCubeLevel= pSoldier->bTargetCubeLevel; + AddGameEvent( S_FIREWEAPON, 0, &SFireWeapon ); + + //DIGICRAB: Burst UnCap + //Loop around in the animation if we still have burst rounds to fire + if (pSoldier->bDoBurst && (pSoldier->bDoBurst <= ((pSoldier->bDoAutofire)?(pSoldier->bDoAutofire):(GetShotsPerBurst(&pSoldier->inv[HANDPOS]))) || (( pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST && pSoldier->bDoBurst <= Weapon[GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS])].ubShotsPerBurst)) )) + { + if(pSoldier->usAnimState == 44 || pSoldier->usAnimState == 109 || pSoldier->usAnimState == 108 && pSoldier->usAniCode == 33) //we are standing, crounching or prone, firing the fast shot + pSoldier->usAniCode = 3; + else if(pSoldier->usAnimState == 175 && pSoldier->usAniCode == 37) //we are firing down to something very close, last shot + pSoldier->usAniCode = 14; + } + + //DIGICRAB: Burst Sound + //This code is stolen from Tactical\Weapons.c - UseGun(...) + if (pSoldier->bDoBurst && pSoldier->iBurstSoundID == NO_SAMPLE && Weapon[ pSoldier->usAttackingWeapon ].sSound != 0 && Item[ pSoldier->usAttackingWeapon ].usItemClass != IC_THROWING_KNIFE ) + { + // Switch on silencer... + INT16 noisefactor = GetPercentNoiseVolume( &pSoldier->inv[ pSoldier->ubAttackingHand ] ); + if( noisefactor < MAX_PERCENT_NOISE_VOLUME_FOR_SILENCED_SOUND || Weapon[ pSoldier->usAttackingWeapon ].ubAttackVolume <= 10 ) { - // Switch on silencer... - INT16 noisefactor = GetPercentNoiseVolume( &pSoldier->inv[ pSoldier->ubAttackingHand ] ); - if( noisefactor < MAX_PERCENT_NOISE_VOLUME_FOR_SILENCED_SOUND || Weapon[ pSoldier->usAttackingWeapon ].ubAttackVolume <= 10 ) - { - INT32 uiSound; + INT32 uiSound; - uiSound = Weapon [ pSoldier->usAttackingWeapon ].silencedSound; - //if ( Weapon[ pSoldier->usAttackingWeapon ].ubCalibre == AMMO9 || Weapon[ pSoldier->usAttackingWeapon ].ubCalibre == AMMO38 || Weapon[ pSoldier->usAttackingWeapon ].ubCalibre == AMMO57 ) - //{ - // uiSound = S_SILENCER_1; - //} - //else - //{ - // uiSound = S_SILENCER_2; - //} + uiSound = Weapon [ pSoldier->usAttackingWeapon ].silencedSound; + //if ( Weapon[ pSoldier->usAttackingWeapon ].ubCalibre == AMMO9 || Weapon[ pSoldier->usAttackingWeapon ].ubCalibre == AMMO38 || Weapon[ pSoldier->usAttackingWeapon ].ubCalibre == AMMO57 ) + //{ + // uiSound = S_SILENCER_1; + //} + //else + //{ + // uiSound = S_SILENCER_2; + //} + + //randomize the rate a bit so that the sound is more believable + PlayJA2Sample( uiSound, 44100-Random(5000)-Random(5000)-Random(5000), SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - //randomize the rate a bit so that the sound is more believable - PlayJA2Sample( uiSound, 44100-Random(5000)-Random(5000)-Random(5000), SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - - } - else - { - INT8 volume = HIGHVOLUME; - if ( noisefactor < 100 ) volume = (volume * noisefactor) / 100; - //randomize the rate a bit so that the sound is more believable - PlayJA2Sample( Weapon[ pSoldier->usAttackingWeapon ].sSound, 44100-Random(5000)-Random(5000)-Random(5000), SoundVolume( volume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - } } + else + { + INT8 volume = HIGHVOLUME; + if ( noisefactor < 100 ) volume = (volume * noisefactor) / 100; + //randomize the rate a bit so that the sound is more believable + PlayJA2Sample( Weapon[ pSoldier->usAttackingWeapon ].sSound, 44100-Random(5000)-Random(5000)-Random(5000), SoundVolume( volume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); + } + } - break; + break; - case 431: + case 431: - // FLASH FRAME WHITE - pSoldier->pForcedShade = White16BPPPalette; - break; + // FLASH FRAME WHITE + pSoldier->pForcedShade = White16BPPPalette; + break; - case 432: + case 432: - // PLAY RANDOM IMPACT SOUND! + // PLAY RANDOM IMPACT SOUND! // PlayJA2Sample( (UINT8)( BULLET_IMPACT_1 + Random(3) ), RATE_11025, MIDVOLUME, 1, MIDDLEPAN ); - // PLAY RANDOM GETTING HIT SOUND + // PLAY RANDOM GETTING HIT SOUND // DoMercBattleSound( pSoldier, BATTLE_SOUND_HIT1 ); + break; + + case 433: + + // CODE: GENERIC HIT! + + CheckForAndHandleSoldierIncompacitated( pSoldier ); + + + break; + + case 434: + + // JUMP TO ANOTHER ANIMATION ( BLOOD ) IF WE WANT BLOOD + uiJumpAddress = pSoldier->usAnimState; + ChangeSoldierState( pSoldier, FLYBACK_HIT_BLOOD_STAND, 0, FALSE ); + return( TRUE ); + break; + + case 435: + + // HOOK FOR A RETURN JUMP + break; + + case 436: + + // Loop through script to find entry address + if ( uiJumpAddress == NO_JUMP ) + { break; + } + usOldAnimState = pSoldier->usAnimState; + pSoldier->usAniCode = 0; - case 433: + do + { + // Get new frame code + anAniFrame = gusAnimInst[ uiJumpAddress ][ pSoldier->usAniCode ]; - // CODE: GENERIC HIT! + if ( anAniFrame == 435 ) + { + // START PROCESSING HERE + ChangeSoldierState( pSoldier, (UINT16)uiJumpAddress, pSoldier->usAniCode, FALSE ); + return( TRUE ); + } + // Adjust frame control pos, and try again + pSoldier->usAniCode++; + } + while( anAniFrame != 999 ); - CheckForAndHandleSoldierIncompacitated( pSoldier ); + uiJumpAddress = NO_JUMP; - - break; - - case 434: - - // JUMP TO ANOTHER ANIMATION ( BLOOD ) IF WE WANT BLOOD - uiJumpAddress = pSoldier->usAnimState; - ChangeSoldierState( pSoldier, FLYBACK_HIT_BLOOD_STAND, 0, FALSE ); + if ( anAniFrame == 999 ) + { + // Fail jump, re-load old anim + ChangeSoldierState( pSoldier, usOldAnimState, 0, FALSE ); return( TRUE ); - break; + } + break; - case 435: + case 437: - // HOOK FOR A RETURN JUMP - break; + // CHANGE DIRECTION AND GET-UP + //sGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)(-1 * DirectionInc( pSoldier->bDirection ) ) ); + //ConvertMapPosToWorldTileCenter( pSoldier->sGridNo, &sXPos, &sYPos ); + //SetSoldierPosition( pSoldier, (FLOAT)sXPos, (FLOAT)sYPos ); - case 436: - // Loop through script to find entry address - if ( uiJumpAddress == NO_JUMP ) + // Reverse direction + EVENT_SetSoldierDirection( pSoldier, gOppositeDirection[ pSoldier->bDirection ] ); + EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); + + ChangeSoldierState( pSoldier, GETUP_FROM_ROLLOVER, 0 , FALSE ); + return( TRUE ); + + case 438: + + //CODE: START HOLD FLASH + pSoldier->fForceShade = TRUE; + break; + + case 439: + + //CODE: END HOLD FLASH + pSoldier->fForceShade = FALSE; + break; + + case 440: + //CODE: Set buddy as dead! + { + BOOLEAN fMadeCorpse; + + // ATE: Piggyback here on stopping the burn sound... + if ( pSoldier->usAnimState == CHARIOTS_OF_FIRE || + pSoldier->usAnimState == BODYEXPLODING ) { - break; + SoundStop( pSoldier->uiPendingActionData1 ); } - usOldAnimState = pSoldier->usAnimState; - pSoldier->usAniCode = 0; - do + + CheckForAndHandleSoldierDeath( pSoldier, &fMadeCorpse ); + + if ( fMadeCorpse ) { - // Get new frame code - anAniFrame = gusAnimInst[ uiJumpAddress ][ pSoldier->usAniCode ]; - - if ( anAniFrame == 435 ) - { - // START PROCESSING HERE - ChangeSoldierState( pSoldier, (UINT16)uiJumpAddress, pSoldier->usAniCode, FALSE ); - return( TRUE ); - } - // Adjust frame control pos, and try again - pSoldier->usAniCode++; + return( FALSE ); } - while( anAniFrame != 999 ); - - uiJumpAddress = NO_JUMP; - - if ( anAniFrame == 999 ) + else { - // Fail jump, re-load old anim - ChangeSoldierState( pSoldier, usOldAnimState, 0, FALSE ); return( TRUE ); } + } + break; + + case 441: + // CODE: Show muzzle flash + if ( pSoldier->bVisible == -1 ) + { break; + } - case 437: + if ( !pSoldier->fMuzzleFlash ) + { + break; + } - // CHANGE DIRECTION AND GET-UP - //sGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)(-1 * DirectionInc( pSoldier->bDirection ) ) ); - //ConvertMapPosToWorldTileCenter( pSoldier->sGridNo, &sXPos, &sYPos ); - //SetSoldierPosition( pSoldier, (FLOAT)sXPos, (FLOAT)sYPos ); + // DO ONLY IF WE'RE AT A GOOD LEVEL + if ( ubAmbientLightLevel < MIN_AMB_LEVEL_FOR_MERC_LIGHTS ) + { + break; + } - - // Reverse direction - EVENT_SetSoldierDirection( pSoldier, gOppositeDirection[ pSoldier->bDirection ] ); - EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); - - ChangeSoldierState( pSoldier, GETUP_FROM_ROLLOVER, 0 , FALSE ); + if( ( pSoldier->iMuzFlash=LightSpriteCreate("L-R03.LHT", 0 ) )==(-1)) + { return( TRUE ); + } - case 438: + LightSpritePower(pSoldier->iMuzFlash, TRUE); + // Get one move forward + { + UINT16 usNewGridNo; + INT16 sXPos, sYPos; - //CODE: START HOLD FLASH - pSoldier->fForceShade = TRUE; + usNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( pSoldier->bDirection ) ); + ConvertGridNoToCenterCellXY( usNewGridNo, &sXPos, &sYPos ); + LightSpritePosition( pSoldier->iMuzFlash, (INT16)(sXPos/CELL_X_SIZE), (INT16)(sYPos/CELL_Y_SIZE)); + + // Start count + pSoldier->bMuzFlashCount = 1; + } + break; + + case 442: + + //CODE: FOR A NON-INTERRUPTABLE SCRIPT - SIGNAL DONE + pSoldier->fInNonintAnim = FALSE; + + // ATE: if it's the begin cower animation, unset ui, cause it could + // be from player changin stance + if ( pSoldier->usAnimState == START_COWER ) + { + UnSetUIBusy( pSoldier->ubID ); + } + break; + + case 443: + + // MOVE GUY FORWARD FOR FENCE HOP ANIMATION + switch( pSoldier->bDirection ) + { + case SOUTH: + case EAST: + + MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)gHopFenceForwardSEDist[ pSoldier->ubBodyType ] ); break; - case 439: - - //CODE: END HOLD FLASH - pSoldier->fForceShade = FALSE; + case NORTH: + case WEST: + MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)gHopFenceForwardNWDist[ pSoldier->ubBodyType ] ); break; + } + break; - case 440: - //CODE: Set buddy as dead! - { - BOOLEAN fMadeCorpse; - - // ATE: Piggyback here on stopping the burn sound... - if ( pSoldier->usAnimState == CHARIOTS_OF_FIRE || - pSoldier->usAnimState == BODYEXPLODING ) - { - SoundStop( pSoldier->uiPendingActionData1 ); - } - - - CheckForAndHandleSoldierDeath( pSoldier, &fMadeCorpse ); - - if ( fMadeCorpse ) - { - return( FALSE ); - } - else - { - return( TRUE ); - } - } - break; - - case 441: - // CODE: Show muzzle flash - if ( pSoldier->bVisible == -1 ) - { - break; - } - - if ( !pSoldier->fMuzzleFlash ) - { - break; - } - - // DO ONLY IF WE'RE AT A GOOD LEVEL - if ( ubAmbientLightLevel < MIN_AMB_LEVEL_FOR_MERC_LIGHTS ) - { - break; - } - - if( ( pSoldier->iMuzFlash=LightSpriteCreate("L-R03.LHT", 0 ) )==(-1)) + case 444: + + // CODE: End Hop Fence + // MOVE TO FORCASTED GRIDNO + sX = CenterX( pSoldier->sForcastGridno ); + sY = CenterY( pSoldier->sForcastGridno ); + + EVENT_InternalSetSoldierPosition( pSoldier, (FLOAT) sX, (FLOAT) sY, FALSE, FALSE, FALSE ); + EVENT_SetSoldierDirection( pSoldier, gTwoCDirection[ pSoldier->bDirection ] ); + pSoldier->sZLevelOverride = -1; + EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); + + + if ( gTacticalStatus.bBoxingState == BOXING_WAITING_FOR_PLAYER || gTacticalStatus.bBoxingState == PRE_BOXING || gTacticalStatus.bBoxingState == BOXING ) + { + BoxingMovementCheck( pSoldier ); + } + + if ( SetOffBombsInGridNo( pSoldier->ubID, pSoldier->sGridNo, FALSE, pSoldier->bLevel )) + { + EVENT_StopMerc( pSoldier, pSoldier->sGridNo, pSoldier->bDirection ); + return( TRUE ); + } + + // If we are at our final destination, goto stance of our movement stance... + // Only in realtime... + //if ( !( gTacticalStatus.uiFlags & INCOMBAT ) ) + // This has to be here to make guys continue along fence path + if ( pSoldier->sGridNo == pSoldier->sFinalDestination ) + { + if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != gAnimControl[ pSoldier->usUIMovementMode ].ubEndHeight ) { + // Goto Stance... + pSoldier->fDontChargeAPsForStanceChange = TRUE; + ChangeSoldierStance( pSoldier, gAnimControl[ pSoldier->usUIMovementMode ].ubEndHeight ); return( TRUE ); } - - LightSpritePower(pSoldier->iMuzFlash, TRUE); - // Get one move forward + else { - UINT16 usNewGridNo; - INT16 sXPos, sYPos; + SoldierGotoStationaryStance( pSoldier ); - usNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( pSoldier->bDirection ) ); - ConvertGridNoToCenterCellXY( usNewGridNo, &sXPos, &sYPos ); - LightSpritePosition( pSoldier->iMuzFlash, (INT16)(sXPos/CELL_X_SIZE), (INT16)(sYPos/CELL_Y_SIZE)); - - // Start count - pSoldier->bMuzFlashCount = 1; + // Set UI Busy + UnSetUIBusy( pSoldier->ubID ); + return( TRUE ); } + } + break; + + case 445: + + // CODE: MOVE GUY FORWARD ONE TILE, BASED ON WHERE WE ARE FACING + switch( pSoldier->bDirection ) + { + case SOUTH: + case EAST: + + MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)gHopFenceForwardFullSEDist[ pSoldier->ubBodyType ] ); break; - case 442: + case NORTH: + case WEST: - //CODE: FOR A NON-INTERRUPTABLE SCRIPT - SIGNAL DONE - pSoldier->fInNonintAnim = FALSE; - - // ATE: if it's the begin cower animation, unset ui, cause it could - // be from player changin stance - if ( pSoldier->usAnimState == START_COWER ) - { - UnSetUIBusy( pSoldier->ubID ); - } + MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)gHopFenceForwardFullNWDist[ pSoldier->ubBodyType ] ); break; - case 443: + } + break; - // MOVE GUY FORWARD FOR FENCE HOP ANIMATION - switch( pSoldier->bDirection ) + case 446: + + // CODE: Turn pause move flag on + pSoldier->uiStatusFlags |= SOLDIER_PAUSEANIMOVE; + break; + + case 447: + + // TRY TO FALL!!! + if ( pSoldier ->fTryingToFall ) + { + INT16 sLastAniFrame; + + // TRY FORWARDS... + // FIRST GRIDNO + sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)( DirectionInc( pSoldier->bDirection ) ) ); + + if ( OKFallDirection( pSoldier, sNewGridNo, pSoldier->bLevel, pSoldier->bDirection, FALLFORWARD_HITDEATH_STOP ) ) { - case SOUTH: - case EAST: + // SECOND GRIDNO + // sNewGridNo = NewGridNo( (UINT16)sNewGridNo, (UINT16)( DirectionInc( pSoldier->bDirection ) ) ); - MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)gHopFenceForwardSEDist[ pSoldier->ubBodyType ] ); - break; - - case NORTH: - case WEST: - MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)gHopFenceForwardNWDist[ pSoldier->ubBodyType ] ); + // if ( OKFallDirection( pSoldier, sNewGridNo, pSoldier->bLevel, pSoldier->bDirection, FALLFORWARD_HITDEATH_STOP ) ) + { + // ALL'S OK HERE... + pSoldier->fTryingToFall = FALSE; break; + } } - break; - case 444: - // CODE: End Hop Fence - // MOVE TO FORCASTED GRIDNO - sX = CenterX( pSoldier->sForcastGridno ); - sY = CenterY( pSoldier->sForcastGridno ); - - EVENT_InternalSetSoldierPosition( pSoldier, (FLOAT) sX, (FLOAT) sY, FALSE, FALSE, FALSE ); - EVENT_SetSoldierDirection( pSoldier, gTwoCDirection[ pSoldier->bDirection ] ); - pSoldier->sZLevelOverride = -1; + // IF HERE, INCREMENT DIRECTION + // ATE: Added Feb1 - can be either direction.... + if ( pSoldier->fFallClockwise ) + { + EVENT_SetSoldierDirection( pSoldier, gOneCDirection[ pSoldier->bDirection ] ); + } + else + { + EVENT_SetSoldierDirection( pSoldier, gOneCCDirection[ pSoldier->bDirection ] ); + } EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); + sLastAniFrame = gusAnimInst[ pSoldier->usAnimState ][ ( pSoldier->usAniCode - 2 ) ]; + ConvertAniCodeToAniFrame( pSoldier, (INT16)( sLastAniFrame ) ); - - if ( gTacticalStatus.bBoxingState == BOXING_WAITING_FOR_PLAYER || gTacticalStatus.bBoxingState == PRE_BOXING || gTacticalStatus.bBoxingState == BOXING ) + if ( pSoldier->bDirection == pSoldier->bStartFallDir ) { - BoxingMovementCheck( pSoldier ); + // GO FORWARD HERE... + pSoldier ->fTryingToFall = FALSE; + break;; } + // IF HERE, RETURN SO WE DONOT INCREMENT DIR + return( TRUE ); + } + break; - if ( SetOffBombsInGridNo( pSoldier->ubID, pSoldier->sGridNo, FALSE, pSoldier->bLevel )) + + case 448: + + // CODE: HANDLE BURST + // FIRST CHECK IF WE'VE REACHED MAX FOR GUN + fStop = FALSE; + + if ( ( pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST && pSoldier->bDoBurst > Weapon[GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS])].ubShotsPerBurst) || (pSoldier->bWeaponMode != WM_ATTACHED_GL_BURST && pSoldier->bDoBurst > ((pSoldier->bDoAutofire)?(pSoldier->bDoAutofire):(GetShotsPerBurst(&pSoldier->inv[HANDPOS])))) ) + { + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because burst size too large"); + fStop = TRUE; + fFreeUpAttacker = TRUE; + } + + // CHECK IF WE HAVE AMMO LEFT, IF NOT, END ANIMATION! + if ( !EnoughAmmo( pSoldier, FALSE, pSoldier->ubAttackingHand ) ) + { + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because not enough ammo"); + fStop = TRUE; + fFreeUpAttacker = TRUE; + if ( pSoldier->bTeam == gbPlayerNum ) { - EVENT_StopMerc( pSoldier, pSoldier->sGridNo, pSoldier->bDirection ); - return( TRUE ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ BURST_FIRE_DEPLETED_CLIP_STR ] ); } - - // If we are at our final destination, goto stance of our movement stance... - // Only in realtime... - //if ( !( gTacticalStatus.uiFlags & INCOMBAT ) ) - // This has to be here to make guys continue along fence path - if ( pSoldier->sGridNo == pSoldier->sFinalDestination ) + } + // Why only check for a jam on the first bullet? + else if (pSoldier->bDoBurst == 1) + { + // CHECK FOR GUN JAM + bWeaponJammed = CheckForGunJam( pSoldier ); + if ( bWeaponJammed == TRUE ) { - if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != gAnimControl[ pSoldier->usUIMovementMode ].ubEndHeight ) - { - // Goto Stance... - pSoldier->fDontChargeAPsForStanceChange = TRUE; - ChangeSoldierStance( pSoldier, gAnimControl[ pSoldier->usUIMovementMode ].ubEndHeight ); - return( TRUE ); - } - else - { - SoldierGotoStationaryStance( pSoldier ); - - // Set UI Busy - UnSetUIBusy( pSoldier->ubID ); - return( TRUE ); - } - } - break; - - case 445: - - // CODE: MOVE GUY FORWARD ONE TILE, BASED ON WHERE WE ARE FACING - switch( pSoldier->bDirection ) - { - case SOUTH: - case EAST: - - MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)gHopFenceForwardFullSEDist[ pSoldier->ubBodyType ] ); - break; - - case NORTH: - case WEST: - - MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)gHopFenceForwardFullNWDist[ pSoldier->ubBodyType ] ); - break; - - } - break; - - case 446: - - // CODE: Turn pause move flag on - pSoldier->uiStatusFlags |= SOLDIER_PAUSEANIMOVE; - break; - - case 447: - - // TRY TO FALL!!! - if ( pSoldier ->fTryingToFall ) - { - INT16 sLastAniFrame; - - // TRY FORWARDS... - // FIRST GRIDNO - sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)( DirectionInc( pSoldier->bDirection ) ) ); - - if ( OKFallDirection( pSoldier, sNewGridNo, pSoldier->bLevel, pSoldier->bDirection, FALLFORWARD_HITDEATH_STOP ) ) - { - // SECOND GRIDNO - // sNewGridNo = NewGridNo( (UINT16)sNewGridNo, (UINT16)( DirectionInc( pSoldier->bDirection ) ) ); - - // if ( OKFallDirection( pSoldier, sNewGridNo, pSoldier->bLevel, pSoldier->bDirection, FALLFORWARD_HITDEATH_STOP ) ) - { - // ALL'S OK HERE... - pSoldier->fTryingToFall = FALSE; - break; - } - } - - - // IF HERE, INCREMENT DIRECTION - // ATE: Added Feb1 - can be either direction.... - if ( pSoldier->fFallClockwise ) - { - EVENT_SetSoldierDirection( pSoldier, gOneCDirection[ pSoldier->bDirection ] ); - } - else - { - EVENT_SetSoldierDirection( pSoldier, gOneCCDirection[ pSoldier->bDirection ] ); - } - EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); - sLastAniFrame = gusAnimInst[ pSoldier->usAnimState ][ ( pSoldier->usAniCode - 2 ) ]; - ConvertAniCodeToAniFrame( pSoldier, (INT16)( sLastAniFrame ) ); - - if ( pSoldier->bDirection == pSoldier->bStartFallDir ) - { - // GO FORWARD HERE... - pSoldier ->fTryingToFall = FALSE; - break;; - } - // IF HERE, RETURN SO WE DONOT INCREMENT DIR - return( TRUE ); - } - break; - - - case 448: - - // CODE: HANDLE BURST - // FIRST CHECK IF WE'VE REACHED MAX FOR GUN - fStop = FALSE; - - if ( ( pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST && pSoldier->bDoBurst > Weapon[GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS])].ubShotsPerBurst) || (pSoldier->bWeaponMode != WM_ATTACHED_GL_BURST && pSoldier->bDoBurst > ((pSoldier->bDoAutofire)?(pSoldier->bDoAutofire):(GetShotsPerBurst(&pSoldier->inv[HANDPOS])))) ) - { - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because burst size too large"); + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because weapon jammed"); fStop = TRUE; fFreeUpAttacker = TRUE; - } + // stop shooting! + // Yeah, but what does this have to do with that? + // pSoldier->bBulletsLeft = 0; + + // OK, Stop burst sound... + if ( pSoldier->iBurstSoundID != NO_SAMPLE ) + { + SoundStop( pSoldier->iBurstSoundID ); + } - // CHECK IF WE HAVE AMMO LEFT, IF NOT, END ANIMATION! - if ( !EnoughAmmo( pSoldier, FALSE, pSoldier->ubAttackingHand ) ) - { - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because not enough ammo"); - fStop = TRUE; - fFreeUpAttacker = TRUE; if ( pSoldier->bTeam == gbPlayerNum ) { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ BURST_FIRE_DEPLETED_CLIP_STR ] ); + PlayJA2Sample( S_DRYFIRE1, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Gun jammed!" ); } + + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - aborting start of attack due to burst gun jam") ); + FreeUpAttacker( ); } - else if (pSoldier->bDoBurst == 1) - { - // CHECK FOR GUN JAM - bWeaponJammed = CheckForGunJam( pSoldier ); - if ( bWeaponJammed == TRUE ) - { - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: Burst case 448, stopping because weapon jammed"); - fStop = TRUE; - fFreeUpAttacker = TRUE; - // stop shooting! - pSoldier->bBulletsLeft = 0; - - // OK, Stop burst sound... - if ( pSoldier->iBurstSoundID != NO_SAMPLE ) - { - SoundStop( pSoldier->iBurstSoundID ); - } - - if ( pSoldier->bTeam == gbPlayerNum ) - { - PlayJA2Sample( S_DRYFIRE1, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Gun jammed!" ); - } - - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - aborting start of attack due to burst gun jam") ); - FreeUpAttacker( pSoldier->ubID ); - } - else if ( bWeaponJammed == 255 ) - { - // Play intermediate animation... - if ( HandleUnjamAnimation( pSoldier ) ) - { - return( TRUE ); - } - } - } - - if ( fStop ) - { - if(pSoldier->bDoAutofire) //reset the autofire cursor after firing - { - pSoldier->autofireLastStep = FALSE; - pSoldier->bDoAutofire = 1; - } - - pSoldier->fDoSpread = FALSE; - pSoldier->bDoBurst = 1; -// pSoldier->fBurstCompleted = TRUE; - if ( fFreeUpAttacker ) - { -// DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - aborting start of attack") ); -// FreeUpAttacker( pSoldier->ubID ); - } - - // ATE; Reduce it due to animation being stopped... - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - Burst animation ended") ); - ReduceAttackBusyCount( pSoldier->ubID, FALSE ); - - - if ( CheckForImproperFireGunEnd( pSoldier ) ) - { - return( TRUE ); - } - - // END: GOTO AIM STANCE BASED ON HEIGHT - // If we are a robot - we need to do stuff different here - if ( AM_A_ROBOT( pSoldier ) ) - { - ChangeSoldierState( pSoldier, STANDING, 0 , FALSE ); - } - else - { - switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) - { - case ANIM_STAND: - ChangeSoldierState( pSoldier, AIM_RIFLE_STAND, 0 , FALSE ); - break; - - case ANIM_PRONE: - ChangeSoldierState( pSoldier, AIM_RIFLE_PRONE, 0 , FALSE ); - break; - - case ANIM_CROUCH: - ChangeSoldierState( pSoldier, AIM_RIFLE_CROUCH, 0 , FALSE ); - break; - - } - } - return( TRUE ); - } - - // MOVETO CURRENT SPREAD LOCATION - if ( pSoldier->fDoSpread ) - { - if ( pSoldier->sSpreadLocations[ pSoldier->fDoSpread - 1 ] != 0 ) - { - EVENT_SetSoldierDirection( pSoldier, (INT8)GetDirectionToGridNoFromGridNo( pSoldier->sGridNo, pSoldier->sSpreadLocations[ pSoldier->fDoSpread - 1 ] ) ); - EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); - } - } - break; - - case 449: - - //CODE: FINISH BURST - pSoldier->fDoSpread = FALSE; - pSoldier->bDoBurst = 1; -// pSoldier->fBurstCompleted = TRUE; - break; - - case 450: - - //CODE: BEGINHOPFENCE - // MOVE TWO FACGIN GRIDNOS - sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)( DirectionInc( pSoldier->bDirection ) ) ); - sNewGridNo = NewGridNo( (UINT16)sNewGridNo, (UINT16)( DirectionInc( pSoldier->bDirection ) ) ); - pSoldier->sForcastGridno = sNewGridNo; - break; - - - case 451: - - // CODE: MANAGE START z-buffer override - switch( pSoldier->bDirection ) - { - case NORTH: - case WEST: - - pSoldier->sZLevelOverride = TOPMOST_Z_LEVEL; - break; - } - break; - - case 452: - - // CODE: MANAGE END z-buffer override - switch( pSoldier->bDirection ) - { - case SOUTH: - case EAST: - - pSoldier->sZLevelOverride = TOPMOST_Z_LEVEL; - break; - - case NORTH: - case WEST: - - pSoldier->sZLevelOverride = -1; - break; - - } - break; - - case 453: - - //CODE: FALLOFF ROOF ( BACKWARDS ) - MOVE BACK SOME! - // Use same function as forward, but is -ve values! - MoveMercFacingDirection( pSoldier , TRUE, (FLOAT)gFalloffBackwardsDist[ pSoldier->ubBodyType ] ); - break; - - case 454: - - // CODE: HANDLE CLIMBING ROOF, - // Move merc up - if ( pSoldier->bDirection == NORTH ) - { - SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment + gClimbUpRoofDist[ pSoldier->ubBodyType ] ) ); - } - else - { - SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment + gClimbUpRoofDist[ pSoldier->ubBodyType ] ) ); - } - break; - - case 455: - - // MOVE GUY FORWARD SOME VALUE - MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)gClimbUpRoofLATDist[ pSoldier->ubBodyType ] ); - - // MOVE DOWN SOME VALUE TOO! - SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment - gClimbUpRoofDistGoingLower[ pSoldier->ubBodyType ] ) ); - - break; - - case 456: - - // CODE: HANDLE CLIMBING ROOF, - // Move merc DOWN - if ( pSoldier->bDirection == NORTH ) - { - SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment - gClimbUpRoofDist[ pSoldier->ubBodyType ] ) ); - } - else - { - SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment - gClimbUpRoofDist[ pSoldier->ubBodyType ] ) ); - } - break; - - case 457: - - // CODE: CHANGCE STANCE TO STANDING - SendChangeSoldierStanceEvent( pSoldier, ANIM_STAND ); - break; - - case 459: - - // CODE: CHANGE ATTACKING TO FIRST HAND - pSoldier->ubAttackingHand = HANDPOS; - pSoldier->usAttackingWeapon = pSoldier->inv[pSoldier->ubAttackingHand].usItem; - // Adjust fReloading to FALSE - pSoldier->fReloading = FALSE; - break; - - case 458: - - // CODE: CHANGE ATTACKING TO SECOND HAND - pSoldier->ubAttackingHand = SECONDHANDPOS; - pSoldier->usAttackingWeapon = pSoldier->inv[pSoldier->ubAttackingHand].usItem; - // Adjust fReloading to FALSE - pSoldier->fReloading = FALSE; - break; - - case 460: - case 461: - - //CODE: THORW ITEM - // Launch ITem! - if ( pSoldier->pTempObject != NULL && pSoldier->pThrowParams != NULL ) - { - // ATE: If we are armmed... - if ( pSoldier->pThrowParams->ubActionCode == THROW_ARM_ITEM ) - { - //AXP 25.03.2007: MinAPsToThrow now actually returns the real cost, not 0 - // ATE: Deduct points! - DeductPoints( pSoldier, MinAPsToThrow( pSoldier, pSoldier->sTargetGridNo, FALSE ), 0 ); - } - else - { - // ATE: Deduct points! - DeductPoints( pSoldier, AP_TOSS_ITEM, 0 ); - } - - 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 ); - - // Remove object - //RemoveObjFrom( &(pSoldier->inv[ HANDPOS ] ), 0 ); - - // Update UI - DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); - - MemFree( pSoldier->pTempObject ); - pSoldier->pTempObject = NULL; - - MemFree( pSoldier->pThrowParams ); - pSoldier->pThrowParams = NULL; - } - break; - - case 462: - - // CODE: MOVE UP FROM CLIFF CLIMB - pSoldier->dHeightAdjustment += (float)2.1; - pSoldier->sHeightAdjustment = (INT16)pSoldier->dHeightAdjustment; - // Move over some... - //MoveMercFacingDirection( pSoldier , FALSE, (FLOAT)0.5 ); - break; - - case 463: - - // MOVE GUY FORWARD SOME VALUE - // Creature move - MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)1.5 ); - break; - - case 464: - - // CODE: END CLIFF CLIMB - pSoldier->dHeightAdjustment = (float)0; - pSoldier->sHeightAdjustment = (INT16)pSoldier->dHeightAdjustment; - - // Set new gridno - { - INT16 sTempGridNo, sNewX, sNewY; - - //Get Next GridNo; - sTempGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (INT16)( DirectionInc(pSoldier->bDirection ) ) ); - - // Get center XY - ConvertGridNoToCenterCellXY( sTempGridNo, &sNewX, &sNewY ); - - // Set position - EVENT_SetSoldierPosition( pSoldier, sNewX, sNewY ); - - // Move two CC directions - EVENT_SetSoldierDirection( pSoldier, gTwoCCDirection[ pSoldier->bDirection ] ); - EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); - - // Set desired anim height! - pSoldier->ubDesiredHeight = ANIM_CROUCH; - pSoldier->sFinalDestination = pSoldier->sGridNo; - - } - break; - - case 465: - - // CODE: SET GUY TO LIFE OF 0 - pSoldier->bLife = 0; - break; - - case 466: - - // CODE: ADJUST TO OUR DEST HEIGHT - if ( pSoldier->sHeightAdjustment != pSoldier->sDesiredHeight ) - { - INT16 sDiff = pSoldier->sHeightAdjustment - pSoldier->sDesiredHeight; - - if ( abs( sDiff ) > 4 ) - { - if ( sDiff > 0 ) - { - // Adjust! - SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment - 2 ) ); - } - else - { - // Adjust! - SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment + 2 ) ); - } - } - else - { - // Adjust! - SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->sDesiredHeight) ); - } - } - else - { - // Goto eating animation - if ( pSoldier->sDesiredHeight == 0 ) - { - ChangeSoldierState( pSoldier, CROW_EAT, 0 , FALSE ); - } - else - { - // We should leave now! - TacticalRemoveSoldier( pSoldier->ubID ); - return( FALSE ); - } - return( TRUE ); - } - break; - - case 467: - - ///CODE: FOR HELIDROP, SET DIRECTION - EVENT_SetSoldierDirection( pSoldier, EAST ); - EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); - - gfIngagedInDrop = FALSE; - - // OK, now get a sweetspot ( not the place we are now! ) - // sNewGridNo = FindGridNoFromSweetSpotExcludingSweetSpot( pSoldier, pSoldier->sGridNo, 5, &ubNewDirection ); - //sNewGridNo = FindRandomGridNoFromSweetSpotExcludingSweetSpot( pSoldier, pSoldier->sGridNo, 3, &ubNewDirection ); - - sNewGridNo = FindGridNoFromSweetSpotExcludingSweetSpotInQuardent( pSoldier, pSoldier->sGridNo, 3, &ubNewDirection, SOUTHEAST ); - - // Check for merc arrives quotes... - HandleMercArrivesQuotes( pSoldier ); - - // Find a path to it! - EVENT_GetNewSoldierPath( pSoldier, sNewGridNo, WALKING ); - - return( TRUE ); - break; - - case 468: - - // CODE: End PUNCH - { - BOOLEAN fNPCPunch = FALSE; - - // ATE: Put some code in for NPC punches... - if ( pSoldier->uiStatusFlags & SOLDIER_NPC_DOING_PUNCH ) - { - fNPCPunch = TRUE; - - // Turn off - pSoldier->uiStatusFlags &= (~SOLDIER_NPC_DOING_PUNCH ); - - // Trigger approach... - TriggerNPCWithGivenApproach( pSoldier->ubProfile, (UINT8)pSoldier->uiPendingActionData4, FALSE ); - } - - - // Are we a martial artist? - { - BOOLEAN fMartialArtist = FALSE; - - if ( pSoldier->ubProfile != NO_PROFILE ) - { - if ( gMercProfiles[ pSoldier->ubProfile ].bSkillTrait == MARTIALARTS || gMercProfiles[ pSoldier->ubProfile ].bSkillTrait2 == MARTIALARTS ) - { - fMartialArtist = TRUE; - } - } - - if ( gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_CROUCH ) - { - if ( fNPCPunch ) - { - ChangeSoldierStance( pSoldier, ANIM_STAND ); - return( TRUE ); - } - else - { - ChangeSoldierState( pSoldier, CROUCHING, 0, FALSE ); - return( TRUE ); - } - } - else - { - if ( fMartialArtist && !AreInMeanwhile( ) ) - { - ChangeSoldierState( pSoldier, NINJA_BREATH, 0, FALSE ); - return( TRUE ); - } - else - { - ChangeSoldierState( pSoldier, PUNCH_BREATH, 0, FALSE ); - return( TRUE ); - } - } - } - } - break; - - case 469: - - // CODE: Begin martial artist attack - DoNinjaAttack( pSoldier ); - return( TRUE ); - break; - - case 470: - - // CODE: CHECK FOR OK WEAPON SHOT! - bOKFireWeapon = OKFireWeapon( pSoldier ); - - if ( bOKFireWeapon == FALSE ) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Fire Weapon: Gun Cannot fire, code 470") ); - - // OK, SKIP x # OF FRAMES - // Skip 3 frames, ( a third ia added at the end of switch.. ) For a total of 4 - pSoldier->usAniCode += 4; - - // Reduce by a bullet... - pSoldier->bBulletsLeft--; - - PlayJA2Sample( S_DRYFIRE1, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - - // Free-up! - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - gun failed to fire") ); - FreeUpAttacker( pSoldier->ubID ); - - } - else if ( bOKFireWeapon == 255 ) + else if ( bWeaponJammed == 255 ) { // Play intermediate animation... if ( HandleUnjamAnimation( pSoldier ) ) @@ -1206,743 +784,1191 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier ) return( TRUE ); } } - break; + } - case 471: - - // CODE: Turn pause move flag off - pSoldier->uiStatusFlags &= (~SOLDIER_PAUSEANIMOVE); - break; - - case 472: - + if ( fStop ) + { + if(pSoldier->bDoAutofire) //reset the autofire cursor after firing { - BOOLEAN fGoBackToAimAfterHit; - - // Save old flag, then reset. If we do nothing special here, at least go back - // to aim if we were. - fGoBackToAimAfterHit = pSoldier->fGoBackToAimAfterHit; - pSoldier->fGoBackToAimAfterHit = FALSE; - - if ( !( pSoldier->uiStatusFlags & SOLDIER_TURNINGFROMHIT ) ) - { - switch( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) - { - case ANIM_STAND: - - // OK, we can do some cool things here - first is to make guy walkl back a bit... - // ChangeSoldierState( pSoldier, STANDING_HIT_BEGINCROUCHDOWN, 0, FALSE ); - // return( TRUE ); - break; - - } - } - - // CODE: HANDLE ANY RANDOM HIT VARIATIONS WE WISH TO DO..... - if ( fGoBackToAimAfterHit ) - { - if ( pSoldier->bLife >= OKLIFE ) - { - InternalSoldierReadyWeapon( pSoldier, pSoldier->bDirection, FALSE ); - } - return( TRUE ); - } + pSoldier->autofireLastStep = FALSE; + pSoldier->bDoAutofire = 1; } - break; - case 473: + pSoldier->fDoSpread = FALSE; + pSoldier->bDoBurst = 1; + // pSoldier->fBurstCompleted = TRUE; + if ( fFreeUpAttacker ) + { + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - aborting start of attack") ); + // FreeUpAttacker( pSoldier->ubID ); + } + + // ATE; Reduce it due to animation being stopped... + // 0verhaul: No longer necessary or desired + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - Burst animation ended") ); + // ReduceAttackBusyCount( pSoldier->ubID, FALSE ); + - // CODE: CHECK IF WE HAVE JUST JAMMED / OUT OF AMMO, DONOT CONTINUE, BUT - // GOTO STATIONARY ANIM if ( CheckForImproperFireGunEnd( pSoldier ) ) { return( TRUE ); } - break; - case 474: - - // CODE: GETUP FROM SLEEP - ChangeSoldierStance( pSoldier, ANIM_STAND ); - return( TRUE ); - - case 475: - - // CODE: END CLIMB DOWN ROOF - pSoldier->ubDesiredHeight = ANIM_STAND; - pSoldier->sFinalDestination = pSoldier->sGridNo; - - // re-enable sight - gTacticalStatus.uiFlags &= (~DISALLOW_SIGHT); - - // ATE: Change interface level..... - // CJC: only if we are a player merc - if ( (pSoldier->bTeam == gbPlayerNum) && !gTacticalStatus.fAutoBandageMode) + // END: GOTO AIM STANCE BASED ON HEIGHT + // If we are a robot - we need to do stuff different here + // 0verhaul: Ya know, if the robot simply used the same animation for standing and rifle standing, + // we probably wouldn't need this special case code. + if ( AM_A_ROBOT( pSoldier ) ) { - if ( pSoldier->ubID == gusSelectedSoldier ) - { - ChangeInterfaceLevel( 0 ); - } - // OK, UNSET INTERFACE FIRST - UnSetUIBusy( pSoldier->ubID ); + ChangeSoldierState( pSoldier, STANDING, 0 , FALSE ); } else { - FreeUpNPCFromRoofClimb( pSoldier ); - } - pSoldier->usUIMovementMode = WALKING; - - // ATE: Handle sight... - HandleSight( pSoldier,SIGHT_LOOK | SIGHT_RADIO | SIGHT_INTERRUPT ); - break; - - case 476: - - // CODE: GOTO PREVIOUS ANIMATION - ChangeSoldierState( pSoldier, ( pSoldier->sPendingActionData2 ), (UINT8)( pSoldier->uiPendingActionData1 + 1 ), FALSE ); - return( TRUE ); - break; - - - case 477: - - // CODE: Locate to target ( if an AI guy.. ) - if ( gTacticalStatus.uiFlags & TURNBASED && (gTacticalStatus.uiFlags & INCOMBAT ) ) - { - if ( pSoldier->bTeam != gbPlayerNum ) + switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - // only locate if the enemy is visible or he's aiming at a player - if ( pSoldier->bVisible != -1 || (pSoldier->ubTargetID != NOBODY && MercPtrs[ pSoldier->ubTargetID ]->bTeam == gbPlayerNum) ) + case ANIM_STAND: + ChangeSoldierState( pSoldier, AIM_RIFLE_STAND, 0 , FALSE ); + break; + + case ANIM_PRONE: + ChangeSoldierState( pSoldier, AIM_RIFLE_PRONE, 0 , FALSE ); + break; + + case ANIM_CROUCH: + ChangeSoldierState( pSoldier, AIM_RIFLE_CROUCH, 0 , FALSE ); + break; + + } + } + return( TRUE ); + } + + // MOVETO CURRENT SPREAD LOCATION + if ( pSoldier->fDoSpread ) + { + if ( pSoldier->sSpreadLocations[ pSoldier->fDoSpread - 1 ] != 0 ) + { + EVENT_SetSoldierDirection( pSoldier, (INT8)GetDirectionToGridNoFromGridNo( pSoldier->sGridNo, pSoldier->sSpreadLocations[ pSoldier->fDoSpread - 1 ] ) ); + EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); + } + } + break; + + case 449: + + //CODE: FINISH BURST + pSoldier->fDoSpread = FALSE; + pSoldier->bDoBurst = 1; + // pSoldier->fBurstCompleted = TRUE; + break; + + case 450: + + //CODE: BEGINHOPFENCE + // MOVE TWO FACGIN GRIDNOS + sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)( DirectionInc( pSoldier->bDirection ) ) ); + sNewGridNo = NewGridNo( (UINT16)sNewGridNo, (UINT16)( DirectionInc( pSoldier->bDirection ) ) ); + pSoldier->sForcastGridno = sNewGridNo; + break; + + + case 451: + + // CODE: MANAGE START z-buffer override + switch( pSoldier->bDirection ) + { + case NORTH: + case WEST: + + pSoldier->sZLevelOverride = TOPMOST_Z_LEVEL; + break; + } + break; + + case 452: + + // CODE: MANAGE END z-buffer override + switch( pSoldier->bDirection ) + { + case SOUTH: + case EAST: + + pSoldier->sZLevelOverride = TOPMOST_Z_LEVEL; + break; + + case NORTH: + case WEST: + + pSoldier->sZLevelOverride = -1; + break; + + } + break; + + case 453: + + //CODE: FALLOFF ROOF ( BACKWARDS ) - MOVE BACK SOME! + // Use same function as forward, but is -ve values! + MoveMercFacingDirection( pSoldier , TRUE, (FLOAT)gFalloffBackwardsDist[ pSoldier->ubBodyType ] ); + break; + + case 454: + + // CODE: HANDLE CLIMBING ROOF, + // Move merc up + if ( pSoldier->bDirection == NORTH ) + { + SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment + gClimbUpRoofDist[ pSoldier->ubBodyType ] ) ); + } + else + { + SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment + gClimbUpRoofDist[ pSoldier->ubBodyType ] ) ); + } + break; + + case 455: + + // MOVE GUY FORWARD SOME VALUE + MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)gClimbUpRoofLATDist[ pSoldier->ubBodyType ] ); + + // MOVE DOWN SOME VALUE TOO! + SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment - gClimbUpRoofDistGoingLower[ pSoldier->ubBodyType ] ) ); + + break; + + case 456: + + // CODE: HANDLE CLIMBING ROOF, + // Move merc DOWN + if ( pSoldier->bDirection == NORTH ) + { + SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment - gClimbUpRoofDist[ pSoldier->ubBodyType ] ) ); + } + else + { + SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment - gClimbUpRoofDist[ pSoldier->ubBodyType ] ) ); + } + break; + + case 457: + + // CODE: CHANGCE STANCE TO STANDING + SendChangeSoldierStanceEvent( pSoldier, ANIM_STAND ); + break; + + case 459: + + // CODE: CHANGE ATTACKING TO FIRST HAND + pSoldier->ubAttackingHand = HANDPOS; + pSoldier->usAttackingWeapon = pSoldier->inv[pSoldier->ubAttackingHand].usItem; + // Adjust fReloading to FALSE + pSoldier->fReloading = FALSE; + break; + + case 458: + + // CODE: CHANGE ATTACKING TO SECOND HAND + pSoldier->ubAttackingHand = SECONDHANDPOS; + pSoldier->usAttackingWeapon = pSoldier->inv[pSoldier->ubAttackingHand].usItem; + // Adjust fReloading to FALSE + pSoldier->fReloading = FALSE; + break; + + case 460: + case 461: + + //CODE: THORW ITEM + // Launch ITem! + if ( pSoldier->pTempObject != NULL && pSoldier->pThrowParams != NULL ) + { + // ATE: If we are armmed... + if ( pSoldier->pThrowParams->ubActionCode == THROW_ARM_ITEM ) + { + //AXP 25.03.2007: MinAPsToThrow now actually returns the real cost, not 0 + // ATE: Deduct points! + DeductPoints( pSoldier, MinAPsToThrow( pSoldier, pSoldier->sTargetGridNo, FALSE ), 0 ); + } + else + { + // ATE: Deduct points! + DeductPoints( pSoldier, AP_TOSS_ITEM, 0 ); + } + + 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 ); + + // Remove object + //RemoveObjFrom( &(pSoldier->inv[ HANDPOS ] ), 0 ); + + // Update UI + DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); + + MemFree( pSoldier->pTempObject ); + pSoldier->pTempObject = NULL; + + MemFree( pSoldier->pThrowParams ); + pSoldier->pThrowParams = NULL; + } + break; + + case 462: + + // CODE: MOVE UP FROM CLIFF CLIMB + pSoldier->dHeightAdjustment += (float)2.1; + pSoldier->sHeightAdjustment = (INT16)pSoldier->dHeightAdjustment; + // Move over some... + //MoveMercFacingDirection( pSoldier , FALSE, (FLOAT)0.5 ); + break; + + case 463: + + // MOVE GUY FORWARD SOME VALUE + // Creature move + MoveMercFacingDirection( pSoldier, FALSE, (FLOAT)1.5 ); + break; + + case 464: + + // CODE: END CLIFF CLIMB + pSoldier->dHeightAdjustment = (float)0; + pSoldier->sHeightAdjustment = (INT16)pSoldier->dHeightAdjustment; + + // Set new gridno + { + INT16 sTempGridNo, sNewX, sNewY; + + //Get Next GridNo; + sTempGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (INT16)( DirectionInc(pSoldier->bDirection ) ) ); + + // Get center XY + ConvertGridNoToCenterCellXY( sTempGridNo, &sNewX, &sNewY ); + + // Set position + EVENT_SetSoldierPosition( pSoldier, sNewX, sNewY ); + + // Move two CC directions + EVENT_SetSoldierDirection( pSoldier, gTwoCCDirection[ pSoldier->bDirection ] ); + EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); + + // Set desired anim height! + pSoldier->ubDesiredHeight = ANIM_CROUCH; + pSoldier->sFinalDestination = pSoldier->sGridNo; + + } + break; + + case 465: + + // CODE: SET GUY TO LIFE OF 0 + pSoldier->bLife = 0; + break; + + case 466: + + // CODE: ADJUST TO OUR DEST HEIGHT + if ( pSoldier->sHeightAdjustment != pSoldier->sDesiredHeight ) + { + INT16 sDiff = pSoldier->sHeightAdjustment - pSoldier->sDesiredHeight; + + if ( abs( sDiff ) > 4 ) + { + if ( sDiff > 0 ) + { + // Adjust! + SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment - 2 ) ); + } + else + { + // Adjust! + SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->dHeightAdjustment + 2 ) ); + } + } + else + { + // Adjust! + SetSoldierHeight( pSoldier, (FLOAT)(pSoldier->sDesiredHeight) ); + } + } + else + { + // Goto eating animation + if ( pSoldier->sDesiredHeight == 0 ) + { + ChangeSoldierState( pSoldier, CROW_EAT, 0 , FALSE ); + } + else + { + // We should leave now! + TacticalRemoveSoldier( pSoldier->ubID ); + return( FALSE ); + } + return( TRUE ); + } + break; + + case 467: + + ///CODE: FOR HELIDROP, SET DIRECTION + EVENT_SetSoldierDirection( pSoldier, EAST ); + EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); + + gfIngagedInDrop = FALSE; + + // OK, now get a sweetspot ( not the place we are now! ) + // sNewGridNo = FindGridNoFromSweetSpotExcludingSweetSpot( pSoldier, pSoldier->sGridNo, 5, &ubNewDirection ); + //sNewGridNo = FindRandomGridNoFromSweetSpotExcludingSweetSpot( pSoldier, pSoldier->sGridNo, 3, &ubNewDirection ); + + sNewGridNo = FindGridNoFromSweetSpotExcludingSweetSpotInQuardent( pSoldier, pSoldier->sGridNo, 3, &ubNewDirection, SOUTHEAST ); + + // Check for merc arrives quotes... + HandleMercArrivesQuotes( pSoldier ); + + // Find a path to it! + EVENT_GetNewSoldierPath( pSoldier, sNewGridNo, WALKING ); + + return( TRUE ); + break; + + case 468: + + // CODE: End PUNCH + { + BOOLEAN fNPCPunch = FALSE; + + // ATE: Put some code in for NPC punches... + if ( pSoldier->uiStatusFlags & SOLDIER_NPC_DOING_PUNCH ) + { + fNPCPunch = TRUE; + + // Turn off + pSoldier->uiStatusFlags &= (~SOLDIER_NPC_DOING_PUNCH ); + + // Trigger approach... + TriggerNPCWithGivenApproach( pSoldier->ubProfile, (UINT8)pSoldier->uiPendingActionData4, FALSE ); + } + + + // Are we a martial artist? + { + BOOLEAN fMartialArtist = FALSE; + + if ( pSoldier->ubProfile != NO_PROFILE ) + { + if ( gMercProfiles[ pSoldier->ubProfile ].bSkillTrait == MARTIALARTS || gMercProfiles[ pSoldier->ubProfile ].bSkillTrait2 == MARTIALARTS ) { - LocateGridNo( pSoldier->sTargetGridNo ); + fMartialArtist = TRUE; } } - } - break; - case 478: - - // CODE: Decide to turn from hit....... - { - INT8 bNewDirection; - UINT32 uiChance; - - // ONLY DO THIS IF CERTAIN CONDITIONS ARISE! - // For one, only do for mercs! - if ( pSoldier->ubBodyType <= REGFEMALE ) + if ( gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_CROUCH ) { - // Secondly, don't if we are going to collapse - if ( pSoldier->bLife >= OKLIFE && pSoldier->bBreath > 0 && pSoldier->bLevel == 0 ) + if ( fNPCPunch ) { - // Save old direction - pSoldier->uiPendingActionData1 = pSoldier->bDirection; - - // If we got a head shot...more chance of turning... - if ( pSoldier->ubHitLocation != AIM_SHOT_HEAD ) - { - uiChance = Random( 100 ); - - // 30 % chance to change direction one way - if ( uiChance < 30 ) - { - bNewDirection = gOneCDirection[ pSoldier->bDirection ]; - } - // 30 % chance to change direction the other way - else if ( uiChance >= 30 && uiChance < 60 ) - { - bNewDirection = gOneCCDirection[ pSoldier->bDirection ]; - } - // 30 % normal.... - else - { - bNewDirection = pSoldier->bDirection; - } - - EVENT_SetSoldierDirection( pSoldier, bNewDirection ); - EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); - - } - else - { - // OK, 50% chance here to turn... - uiChance = Random( 100 ); - - if ( uiChance < 50 ) - { - // OK, pick a larger direction to goto.... - pSoldier->uiStatusFlags |= SOLDIER_TURNINGFROMHIT; - - // Pick evenly between both - if ( Random( 50 ) < 25 ) - { - bNewDirection = gOneCDirection[ pSoldier->bDirection ]; - bNewDirection = gOneCDirection[ bNewDirection ]; - bNewDirection = gOneCDirection[ bNewDirection ]; - } - else - { - bNewDirection = gOneCCDirection[ pSoldier->bDirection ]; - bNewDirection = gOneCCDirection[ bNewDirection ]; - bNewDirection = gOneCCDirection[ bNewDirection ]; - } - - EVENT_SetSoldierDesiredDirection( pSoldier, bNewDirection ); - } - } - } - } - break; - } - - case 479: - - // CODE: Return to old direction...... - if ( pSoldier->ubBodyType <= REGFEMALE ) - { - // Secondly, don't if we are going to collapse - //if ( pSoldier->bLife >= OKLIFE && pSoldier->bBreath > 0 ) - //{ - /// if ( !( pSoldier->uiStatusFlags & SOLDIER_TURNINGFROMHIT ) ) - // { - /// pSoldier->bDirection = (INT8)pSoldier->uiPendingActionData1; - // pSoldier->bDesiredDirection = (INT8)pSoldier->uiPendingActionData1; - // } - //} - } - break; - - case 480: - - // CODE: FORCE FREE ATTACKER - // Release attacker - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, code 480") ); - - ReleaseSoldiersAttacker( pSoldier ); - - //FREEUP GETTING HIT FLAG - pSoldier->fGettingHit = FALSE; - break; - - case 481: - - // CODE: CUT FENCE... - CutWireFence( pSoldier->sTargetGridNo ); - break; - - case 482: - - // CODE: END CRIPPLE KICKOUT... - KickOutWheelchair( pSoldier ); - break; - - case 483: - - // CODE: HANDLE DROP BOMB... - HandleSoldierDropBomb( pSoldier, pSoldier->sPendingActionData2 ); - break; - - case 484: - - // CODE: HANDLE REMOTE... - HandleSoldierUseRemote( pSoldier, pSoldier->sPendingActionData2 ); - break; - - case 485: - - // CODE: Try steal..... - UseHandToHand( pSoldier, pSoldier->sPendingActionData2, TRUE ); - //jackaians: - //if we are not waiting for the pickup menu to be displayed - if (guiPendingOverrideEvent != G_GETTINGITEM) - { - PreventFromTheFreezingBug(pSoldier); - } - break; - - case 486: - - // CODE: GIVE ITEM - SoldierGiveItemFromAnimation( pSoldier ); - if (pSoldier->ubProfile != NO_PROFILE && pSoldier->ubProfile >= FIRST_NPC ) - { - TriggerNPCWithGivenApproach( pSoldier->ubProfile, APPROACH_DONE_GIVING_ITEM, FALSE ); - } - break; - - case 487: - - // CODE: DROP ITEM - SoldierHandleDropItem( pSoldier ); - break; - - case 489: - - - //CODE: REMOVE GUY FRMO WORLD DUE TO EXPLOSION - //ChangeSoldierState( pSoldier, RAISE_RIFLE, 0 , FALSE ); - //return( TRUE ); - //Delete guy - //TacticalRemoveSoldier( pSoldier->ubID ); - //return( FALSE ); - break; - - case 490: - - // CODE: HANDLE END ITEM PICKUP - //LOOK INTO HAND, RAISE RIFLE IF WE HAVE ONE.... - /* - if ( pSoldier->inv[ HANDPOS ].usItem != NOTHING ) - { - // CHECK IF GUN - if ( Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass == IC_GUN ) - { - if ( Weapon[ pSoldier->inv[ HANDPOS ].usItem ].ubWeaponClass != HANDGUNCLASS ) - { - // RAISE - ChangeSoldierState( pSoldier, RAISE_RIFLE, 0 , FALSE ); + ChangeSoldierStance( pSoldier, ANIM_STAND ); return( TRUE ); } + else + { + ChangeSoldierState( pSoldier, CROUCHING, 0, FALSE ); + return( TRUE ); + } + } + else + { + if ( fMartialArtist && !AreInMeanwhile( ) ) + { + ChangeSoldierState( pSoldier, NINJA_BREATH, 0, FALSE ); + return( TRUE ); + } + else + { + ChangeSoldierState( pSoldier, PUNCH_BREATH, 0, FALSE ); + return( TRUE ); + } + } + } + } + break; + + case 469: + + // CODE: Begin martial artist attack + DoNinjaAttack( pSoldier ); + return( TRUE ); + break; + + case 470: + + // CODE: CHECK FOR OK WEAPON SHOT! + bOKFireWeapon = OKFireWeapon( pSoldier ); + + if ( bOKFireWeapon == FALSE ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Fire Weapon: Gun Cannot fire, code 470") ); + + // OK, SKIP x # OF FRAMES + // Skip 3 frames, ( a third ia added at the end of switch.. ) For a total of 4 + pSoldier->usAniCode += 4; + + // Reduce by a bullet... + // pSoldier->bBulletsLeft--; + + PlayJA2Sample( S_DRYFIRE1, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); + + // Free-up! + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - gun failed to fire") ); + FreeUpAttacker( ); + + } + else if ( bOKFireWeapon == 255 ) + { + // Play intermediate animation... + if ( HandleUnjamAnimation( pSoldier ) ) + { + return( TRUE ); + } + } + break; + + case 471: + + // CODE: Turn pause move flag off + pSoldier->uiStatusFlags &= (~SOLDIER_PAUSEANIMOVE); + break; + + case 472: + + { + BOOLEAN fGoBackToAimAfterHit; + + // Save old flag, then reset. If we do nothing special here, at least go back + // to aim if we were. + fGoBackToAimAfterHit = pSoldier->fGoBackToAimAfterHit; + pSoldier->fGoBackToAimAfterHit = FALSE; + + if ( !( pSoldier->uiStatusFlags & SOLDIER_TURNINGFROMHIT ) ) + { + switch( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) + { + case ANIM_STAND: + + // OK, we can do some cool things here - first is to make guy walkl back a bit... + // ChangeSoldierState( pSoldier, STANDING_HIT_BEGINCROUCHDOWN, 0, FALSE ); + // return( TRUE ); + break; } - } - */ - break; - case 491: - - // CODE: HANDLE RANDOM BREATH ANIMATION - //if ( pSoldier->bLife > INJURED_CHANGE_THREASHOLD ) - if ( pSoldier->bLife >= OKLIFE ) + // CODE: HANDLE ANY RANDOM HIT VARIATIONS WE WISH TO DO..... + if ( fGoBackToAimAfterHit ) { - // Increment time from last update - pSoldier->uiTimeOfLastRandomAction++; - - if ( pSoldier->uiTimeOfLastRandomAction > TIME_FOR_RANDOM_ANIM_CHECK || pSoldier->bLife < INJURED_CHANGE_THREASHOLD || GetDrunkLevel( pSoldier ) >= BORDERLINE ) + if ( pSoldier->bLife >= OKLIFE ) { - pSoldier->uiTimeOfLastRandomAction = 0; + InternalSoldierReadyWeapon( pSoldier, pSoldier->bDirection, FALSE ); + } + return( TRUE ); + } + } + break; - // Don't do any in water! - if ( !MercInWater( pSoldier ) ) + case 473: + + // CODE: CHECK IF WE HAVE JUST JAMMED / OUT OF AMMO, DONOT CONTINUE, BUT + // GOTO STATIONARY ANIM + if ( CheckForImproperFireGunEnd( pSoldier ) ) + { + return( TRUE ); + } + break; + + case 474: + + // CODE: GETUP FROM SLEEP + ChangeSoldierStance( pSoldier, ANIM_STAND ); + return( TRUE ); + + case 475: + + // CODE: END CLIMB DOWN ROOF + pSoldier->ubDesiredHeight = ANIM_STAND; + pSoldier->sFinalDestination = pSoldier->sGridNo; + + // re-enable sight + gTacticalStatus.uiFlags &= (~DISALLOW_SIGHT); + + // ATE: Change interface level..... + // CJC: only if we are a player merc + if ( (pSoldier->bTeam == gbPlayerNum) && !gTacticalStatus.fAutoBandageMode) + { + if ( pSoldier->ubID == gusSelectedSoldier ) + { + ChangeInterfaceLevel( 0 ); + } + // OK, UNSET INTERFACE FIRST + UnSetUIBusy( pSoldier->ubID ); + } + else + { + FreeUpNPCFromRoofClimb( pSoldier ); + } + pSoldier->usUIMovementMode = WALKING; + + // ATE: Handle sight... + HandleSight( pSoldier,SIGHT_LOOK | SIGHT_RADIO | SIGHT_INTERRUPT ); + break; + + case 476: + + // CODE: GOTO PREVIOUS ANIMATION + ChangeSoldierState( pSoldier, ( pSoldier->sPendingActionData2 ), (UINT8)( pSoldier->uiPendingActionData1 + 1 ), FALSE ); + return( TRUE ); + break; + + + case 477: + + // CODE: Locate to target ( if an AI guy.. ) + if ( gTacticalStatus.uiFlags & TURNBASED && (gTacticalStatus.uiFlags & INCOMBAT ) ) + { + if ( pSoldier->bTeam != gbPlayerNum ) + { + // only locate if the enemy is visible or he's aiming at a player + if ( pSoldier->bVisible != -1 || (pSoldier->ubTargetID != NOBODY && MercPtrs[ pSoldier->ubTargetID ]->bTeam == gbPlayerNum) ) + { + LocateGridNo( pSoldier->sTargetGridNo ); + } + } + } + break; + + case 478: + + // CODE: Decide to turn from hit....... + { + INT8 bNewDirection; + UINT32 uiChance; + + // ONLY DO THIS IF CERTAIN CONDITIONS ARISE! + // For one, only do for mercs! + if ( pSoldier->ubBodyType <= REGFEMALE ) + { + // Secondly, don't if we are going to collapse + if ( pSoldier->bLife >= OKLIFE && pSoldier->bBreath > 0 && pSoldier->bLevel == 0 ) + { + // Save old direction + pSoldier->uiPendingActionData1 = pSoldier->bDirection; + + // If we got a head shot...more chance of turning... + if ( pSoldier->ubHitLocation != AIM_SHOT_HEAD ) { - // OK, make a dice roll - ubDiceRoll = (UINT8)Random( 100 ); + uiChance = Random( 100 ); - // Determine what is in our hand; - usItem = pSoldier->inv[ HANDPOS ].usItem; - - // Default to nothing in hand ( nothing in quotes, we do have something but not just visible ) - ubRandomHandIndex = RANDOM_ANIM_NOTHINGINHAND; - - if ( usItem != NOTHING ) + // 30 % chance to change direction one way + if ( uiChance < 30 ) { - if ( Item[ usItem ].usItemClass == IC_GUN ) - { -// if ( (Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) - if ( (Item[ usItem ].twohanded ) ) - { - // Set to rifle - ubRandomHandIndex = RANDOM_ANIM_RIFLEINHAND; - } - else - { - // Don't EVER do a trivial anim... - break; - } - } + bNewDirection = gOneCDirection[ pSoldier->bDirection ]; + } + // 30 % chance to change direction the other way + else if ( uiChance >= 30 && uiChance < 60 ) + { + bNewDirection = gOneCCDirection[ pSoldier->bDirection ]; + } + // 30 % normal.... + else + { + bNewDirection = pSoldier->bDirection; } - // Check which animation to play.... - for ( cnt = 0; cnt < MAX_RANDOM_ANIMS_PER_BODYTYPE; cnt++ ) + EVENT_SetSoldierDirection( pSoldier, bNewDirection ); + EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); + + } + else + { + // OK, 50% chance here to turn... + uiChance = Random( 100 ); + + if ( uiChance < 50 ) { - pAnimDef = &( gRandomAnimDefs[ pSoldier->ubBodyType ][ cnt ] ); + // OK, pick a larger direction to goto.... + pSoldier->uiStatusFlags |= SOLDIER_TURNINGFROMHIT; + // This becomes an attack busy situation + gTacticalStatus.ubAttackBusyCount++; + DebugAttackBusy( String( "Soldier turning from a hit. Increasing attack busy. Now %d\n", gTacticalStatus.ubAttackBusyCount ) ); - if ( pAnimDef->sAnimID != 0 ) + // Pick evenly between both + if ( Random( 50 ) < 25 ) { - // If it's an injured animation and we are not in the threashold.... - if ( ( pAnimDef->ubFlags & RANDOM_ANIM_INJURED ) && pSoldier->bLife >= INJURED_CHANGE_THREASHOLD ) + bNewDirection = gOneCDirection[ pSoldier->bDirection ]; + bNewDirection = gOneCDirection[ bNewDirection ]; + bNewDirection = gOneCDirection[ bNewDirection ]; + } + else + { + bNewDirection = gOneCCDirection[ pSoldier->bDirection ]; + bNewDirection = gOneCCDirection[ bNewDirection ]; + bNewDirection = gOneCCDirection[ bNewDirection ]; + } + + EVENT_SetSoldierDesiredDirection( pSoldier, bNewDirection ); + } + } + } + } + break; + } + + case 479: + + // CODE: Return to old direction...... + if ( pSoldier->ubBodyType <= REGFEMALE ) + { + // Secondly, don't if we are going to collapse + //if ( pSoldier->bLife >= OKLIFE && pSoldier->bBreath > 0 ) + //{ + /// if ( !( pSoldier->uiStatusFlags & SOLDIER_TURNINGFROMHIT ) ) + // { + /// pSoldier->bDirection = (INT8)pSoldier->uiPendingActionData1; + // pSoldier->bDesiredDirection = (INT8)pSoldier->uiPendingActionData1; + // } + //} + } + break; + + case 480: + + // 0verhaul: This is handled in the ReduceAttackBusyCount call + // CODE: FORCE FREE ATTACKER + // Release attacker + //DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, code 480") ); + + //ReleaseSoldiersAttacker( pSoldier ); + + //FREEUP GETTING HIT FLAG + //pSoldier->fGettingHit = FALSE; + break; + + case 481: + + // CODE: CUT FENCE... + CutWireFence( pSoldier->sTargetGridNo ); + break; + + case 482: + + // CODE: END CRIPPLE KICKOUT... + KickOutWheelchair( pSoldier ); + break; + + case 483: + + // CODE: HANDLE DROP BOMB... + HandleSoldierDropBomb( pSoldier, pSoldier->sPendingActionData2 ); + break; + + case 484: + + // CODE: HANDLE REMOTE... + HandleSoldierUseRemote( pSoldier, pSoldier->sPendingActionData2 ); + break; + + case 485: + + // CODE: Try steal..... + UseHandToHand( pSoldier, pSoldier->sPendingActionData2, TRUE ); + //jackaians: + //if we are not waiting for the pickup menu to be displayed + if (guiPendingOverrideEvent != G_GETTINGITEM) + { + PreventFromTheFreezingBug(pSoldier); + } + break; + + case 486: + + // CODE: GIVE ITEM + SoldierGiveItemFromAnimation( pSoldier ); + if (pSoldier->ubProfile != NO_PROFILE && pSoldier->ubProfile >= FIRST_NPC ) + { + TriggerNPCWithGivenApproach( pSoldier->ubProfile, APPROACH_DONE_GIVING_ITEM, FALSE ); + } + break; + + case 487: + + // CODE: DROP ITEM + SoldierHandleDropItem( pSoldier ); + break; + + case 489: + + + //CODE: REMOVE GUY FRMO WORLD DUE TO EXPLOSION + //ChangeSoldierState( pSoldier, RAISE_RIFLE, 0 , FALSE ); + //return( TRUE ); + //Delete guy + //TacticalRemoveSoldier( pSoldier->ubID ); + //return( FALSE ); + break; + + case 490: + + // CODE: HANDLE END ITEM PICKUP + //LOOK INTO HAND, RAISE RIFLE IF WE HAVE ONE.... + /* + if ( pSoldier->inv[ HANDPOS ].usItem != NOTHING ) + { + // CHECK IF GUN + if ( Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass == IC_GUN ) + { + if ( Weapon[ pSoldier->inv[ HANDPOS ].usItem ].ubWeaponClass != HANDGUNCLASS ) + { + // RAISE + ChangeSoldierState( pSoldier, RAISE_RIFLE, 0 , FALSE ); + return( TRUE ); + } + + } + + } + */ + break; + + case 491: + + // CODE: HANDLE RANDOM BREATH ANIMATION + //if ( pSoldier->bLife > INJURED_CHANGE_THREASHOLD ) + if ( pSoldier->bLife >= OKLIFE ) + { + // Increment time from last update + pSoldier->uiTimeOfLastRandomAction++; + + if ( pSoldier->uiTimeOfLastRandomAction > TIME_FOR_RANDOM_ANIM_CHECK || pSoldier->bLife < INJURED_CHANGE_THREASHOLD || GetDrunkLevel( pSoldier ) >= BORDERLINE ) + { + pSoldier->uiTimeOfLastRandomAction = 0; + + // Don't do any in water! + if ( !MercInWater( pSoldier ) ) + { + // OK, make a dice roll + ubDiceRoll = (UINT8)Random( 100 ); + + // Determine what is in our hand; + usItem = pSoldier->inv[ HANDPOS ].usItem; + + // Default to nothing in hand ( nothing in quotes, we do have something but not just visible ) + ubRandomHandIndex = RANDOM_ANIM_NOTHINGINHAND; + + if ( usItem != NOTHING ) + { + if ( Item[ usItem ].usItemClass == IC_GUN ) + { + // if ( (Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) + if ( (Item[ usItem ].twohanded ) ) + { + // Set to rifle + ubRandomHandIndex = RANDOM_ANIM_RIFLEINHAND; + } + else + { + // Don't EVER do a trivial anim... + break; + } + } + } + + // Check which animation to play.... + for ( cnt = 0; cnt < MAX_RANDOM_ANIMS_PER_BODYTYPE; cnt++ ) + { + pAnimDef = &( gRandomAnimDefs[ pSoldier->ubBodyType ][ cnt ] ); + + if ( pAnimDef->sAnimID != 0 ) + { + // If it's an injured animation and we are not in the threashold.... + if ( ( pAnimDef->ubFlags & RANDOM_ANIM_INJURED ) && pSoldier->bLife >= INJURED_CHANGE_THREASHOLD ) + { + continue; + } + + // If we need to do an injured one, don't do any others... + if ( !( pAnimDef->ubFlags & RANDOM_ANIM_INJURED ) && pSoldier->bLife < INJURED_CHANGE_THREASHOLD ) + { + continue; + } + + // If it's a drunk animation and we are not in the threashold.... + if ( ( pAnimDef->ubFlags & RANDOM_ANIM_DRUNK ) && GetDrunkLevel( pSoldier ) < BORDERLINE ) + { + continue; + } + + // If we need to do an injured one, don't do any others... + if ( !( pAnimDef->ubFlags & RANDOM_ANIM_DRUNK ) && GetDrunkLevel( pSoldier ) >= BORDERLINE ) + { + continue; + } + + // Check if it's our hand + if ( pAnimDef->ubHandRestriction != RANDOM_ANIM_IRRELEVENTINHAND && pAnimDef->ubHandRestriction != ubRandomHandIndex ) + { + continue; + } + + // Check if it's casual and we're in combat and it's not our guy + if ( ( pAnimDef->ubFlags & RANDOM_ANIM_CASUAL ) ) + { + // If he's a bad guy, do not do it! + if ( pSoldier->bTeam != gbPlayerNum || ( gTacticalStatus.uiFlags & INCOMBAT ) ) { continue; } + } - // If we need to do an injured one, don't do any others... - if ( !( pAnimDef->ubFlags & RANDOM_ANIM_INJURED ) && pSoldier->bLife < INJURED_CHANGE_THREASHOLD ) - { - continue; - } + // If we are an alternate big guy and have been told to use a normal big merc ani... + if ( ( pAnimDef->ubFlags & RANDOM_ANIM_FIRSTBIGMERC ) && ( pSoldier->uiAnimSubFlags & SUB_ANIM_BIGGUYTHREATENSTANCE ) ) + { + continue; + } - // If it's a drunk animation and we are not in the threashold.... - if ( ( pAnimDef->ubFlags & RANDOM_ANIM_DRUNK ) && GetDrunkLevel( pSoldier ) < BORDERLINE ) - { - continue; - } + // If we are a normal big guy and have been told to use an alternate big merc ani... + if ( ( pAnimDef->ubFlags & RANDOM_ANIM_SECONDBIGMERC ) && !( pSoldier->uiAnimSubFlags & SUB_ANIM_BIGGUYTHREATENSTANCE ) ) + { + continue; + } - // If we need to do an injured one, don't do any others... - if ( !( pAnimDef->ubFlags & RANDOM_ANIM_DRUNK ) && GetDrunkLevel( pSoldier ) >= BORDERLINE ) + // Check if it's the proper height + if ( pAnimDef->ubAnimHeight == gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) + { + // OK, If we rolled a value that lies within the range for this random animation, use this one! + if ( ubDiceRoll >= pAnimDef->ubStartRoll && ubDiceRoll <= pAnimDef->ubEndRoll ) { - continue; - } - - // Check if it's our hand - if ( pAnimDef->ubHandRestriction != RANDOM_ANIM_IRRELEVENTINHAND && pAnimDef->ubHandRestriction != ubRandomHandIndex ) - { - continue; - } - - // Check if it's casual and we're in combat and it's not our guy - if ( ( pAnimDef->ubFlags & RANDOM_ANIM_CASUAL ) ) - { - // If he's a bad guy, do not do it! - if ( pSoldier->bTeam != gbPlayerNum || ( gTacticalStatus.uiFlags & INCOMBAT ) ) + // Are we playing a sound + if ( pAnimDef->sAnimID == RANDOM_ANIM_SOUND ) { - continue; - } - } - - // If we are an alternate big guy and have been told to use a normal big merc ani... - if ( ( pAnimDef->ubFlags & RANDOM_ANIM_FIRSTBIGMERC ) && ( pSoldier->uiAnimSubFlags & SUB_ANIM_BIGGUYTHREATENSTANCE ) ) - { - continue; - } - - // If we are a normal big guy and have been told to use an alternate big merc ani... - if ( ( pAnimDef->ubFlags & RANDOM_ANIM_SECONDBIGMERC ) && !( pSoldier->uiAnimSubFlags & SUB_ANIM_BIGGUYTHREATENSTANCE ) ) - { - continue; - } - - // Check if it's the proper height - if ( pAnimDef->ubAnimHeight == gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) - { - // OK, If we rolled a value that lies within the range for this random animation, use this one! - if ( ubDiceRoll >= pAnimDef->ubStartRoll && ubDiceRoll <= pAnimDef->ubEndRoll ) - { - // Are we playing a sound - if ( pAnimDef->sAnimID == RANDOM_ANIM_SOUND ) + if ( pSoldier->ubBodyType == COW ) { - if ( pSoldier->ubBodyType == COW ) - { - if ( Random( 2 ) == 1 ) - { - if ( ( gTacticalStatus.uiFlags & INCOMBAT ) && pSoldier->bVisible == -1 ) - { - // DO this every 10th time or so... - if ( Random( 100 ) < 10 ) - { - // Play sound - PlayJA2SampleFromFile( pAnimDef->zSoundFile, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - } - } - else - { + if ( Random( 2 ) == 1 ) + { + if ( ( gTacticalStatus.uiFlags & INCOMBAT ) && pSoldier->bVisible == -1 ) + { + // DO this every 10th time or so... + if ( Random( 100 ) < 10 ) + { + // Play sound + PlayJA2SampleFromFile( pAnimDef->zSoundFile, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); + } + } + else + { - // Play sound - PlayJA2SampleFromFile( pAnimDef->zSoundFile, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - } - } - } - else - { - // Play sound - PlayJA2SampleFromFile( pAnimDef->zSoundFile, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - } + // Play sound + PlayJA2SampleFromFile( pAnimDef->zSoundFile, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); + } + } } else { - ChangeSoldierState( pSoldier, pAnimDef->sAnimID, 0 , FALSE ); + // Play sound + PlayJA2SampleFromFile( pAnimDef->zSoundFile, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); } - return( TRUE ); } + else + { + ChangeSoldierState( pSoldier, pAnimDef->sAnimID, 0 , FALSE ); + } + return( TRUE ); } } } - } + } } - break; + } + break; - case 492: + case 492: - - // SIGNAL DODGE! - // ATE: Only do if we're not inspecial case... - if ( !( pSoldier->uiStatusFlags & SOLDIER_NPC_DOING_PUNCH ) ) - { - SOLDIERTYPE *pTSoldier; - UINT32 uiMercFlags; - UINT16 usSoldierIndex; - if ( FindSoldier( pSoldier->sTargetGridNo, &usSoldierIndex, &uiMercFlags, FIND_SOLDIER_GRIDNO ) ) - { - GetSoldier( &pTSoldier, usSoldierIndex ); + // SIGNAL DODGE! + // ATE: Only do if we're not inspecial case... + if ( !( pSoldier->uiStatusFlags & SOLDIER_NPC_DOING_PUNCH ) ) + { + SOLDIERTYPE *pTSoldier; + UINT32 uiMercFlags; + UINT16 usSoldierIndex; - // IF WE ARE AN ANIMAL, CAR, MONSTER, DONT'T DODGE - if ( IS_MERC_BODY_TYPE( pTSoldier ) ) + if ( FindSoldier( pSoldier->sTargetGridNo, &usSoldierIndex, &uiMercFlags, FIND_SOLDIER_GRIDNO ) ) + { + GetSoldier( &pTSoldier, usSoldierIndex ); + + // IF WE ARE AN ANIMAL, CAR, MONSTER, DONT'T DODGE + if ( IS_MERC_BODY_TYPE( pTSoldier ) ) + { + // ONLY DODGE IF WE ARE SEEN + if ( pTSoldier->bOppList[ pSoldier->ubID ] != 0 || pTSoldier->bTeam == pSoldier->bTeam ) { - // ONLY DODGE IF WE ARE SEEN - if ( pTSoldier->bOppList[ pSoldier->ubID ] != 0 || pTSoldier->bTeam == pSoldier->bTeam ) + if ( gAnimControl[ pTSoldier->usAnimState ].ubHeight == ANIM_STAND ) { - if ( gAnimControl[ pTSoldier->usAnimState ].ubHeight == ANIM_STAND ) + // OK, stop merc.... + EVENT_StopMerc( pTSoldier, pTSoldier->sGridNo, pTSoldier->bDirection ); + + if ( pTSoldier->bTeam != gbPlayerNum ) { - // OK, stop merc.... - EVENT_StopMerc( pTSoldier, pTSoldier->sGridNo, pTSoldier->bDirection ); - - if ( pTSoldier->bTeam != gbPlayerNum ) - { - CancelAIAction( pTSoldier, TRUE ); - } - - // Turn towards the person! - EVENT_SetSoldierDesiredDirection( pTSoldier, GetDirectionFromGridNo( pSoldier->sGridNo, pTSoldier ) ); - - // PLAY SOLDIER'S DODGE ANIMATION - ChangeSoldierState( pTSoldier, DODGE_ONE, 0 , FALSE ); + CancelAIAction( pTSoldier, TRUE ); } + + // Turn towards the person! + EVENT_SetSoldierDesiredDirection( pTSoldier, GetDirectionFromGridNo( pSoldier->sGridNo, pTSoldier ) ); + + // PLAY SOLDIER'S DODGE ANIMATION + ChangeSoldierState( pTSoldier, DODGE_ONE, 0 , FALSE ); } } } } - break; + } + break; - case 493: + case 493: - //CODE: PICKUP ITEM! - // CHECK IF THIS EVENT HAS BEEN SETUP - //if ( pSoldier->ubPendingAction == MERC_PICKUPITEM ) - //{ - // DROP ITEM - HandleSoldierPickupItem( pSoldier, pSoldier->uiPendingActionData1, (INT16)(pSoldier->uiPendingActionData4 ), pSoldier->bPendingActionData3 ); - // EVENT HAS BEEN HANDLED - pSoldier->ubPendingAction = NO_PENDING_ACTION; + //CODE: PICKUP ITEM! + // CHECK IF THIS EVENT HAS BEEN SETUP + //if ( pSoldier->ubPendingAction == MERC_PICKUPITEM ) + //{ + // DROP ITEM + HandleSoldierPickupItem( pSoldier, pSoldier->uiPendingActionData1, (INT16)(pSoldier->uiPendingActionData4 ), pSoldier->bPendingActionData3 ); + // EVENT HAS BEEN HANDLED + pSoldier->ubPendingAction = NO_PENDING_ACTION; - //} - //else - //{ - // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Soldier Ani: CODE 493 Error, Pickup item action called but not setup" ); - //} - break; + //} + //else + //{ + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Soldier Ani: CODE 493 Error, Pickup item action called but not setup" ); + //} + break; - case 494: + case 494: - //CODE: OPEN STRUCT! - // CHECK IF THIS EVENT HAS BEEN SETUP - //if ( pSoldier->ubPendingAction == MERC_OPENSTRUCT ) - //{ - SoldierHandleInteractiveObject( pSoldier ); + //CODE: OPEN STRUCT! + // CHECK IF THIS EVENT HAS BEEN SETUP + //if ( pSoldier->ubPendingAction == MERC_OPENSTRUCT ) + //{ + SoldierHandleInteractiveObject( pSoldier ); - // EVENT HAS BEEN HANDLED - pSoldier->ubPendingAction = NO_PENDING_ACTION; + // EVENT HAS BEEN HANDLED + pSoldier->ubPendingAction = NO_PENDING_ACTION; - //} - //else - //{ - // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Soldier Ani: CODE 494 Error, OPen door action called but not setup" ); - //} - break; - - case 495: + //} + //else + //{ + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Soldier Ani: CODE 494 Error, OPen door action called but not setup" ); + //} + break; - if (pSoldier->bAction == AI_ACTION_UNLOCK_DOOR || (pSoldier->bAction == AI_ACTION_LOCK_DOOR && !(pSoldier->fAIFlags & AI_LOCK_DOOR_INCLUDES_CLOSE) ) ) - { - // EVENT HAS BEEN HANDLED - pSoldier->ubPendingAction = NO_PENDING_ACTION; + case 495: - // do nothing here - } - else - { + if (pSoldier->bAction == AI_ACTION_UNLOCK_DOOR || (pSoldier->bAction == AI_ACTION_LOCK_DOOR && !(pSoldier->fAIFlags & AI_LOCK_DOOR_INCLUDES_CLOSE) ) ) + { + // EVENT HAS BEEN HANDLED + pSoldier->ubPendingAction = NO_PENDING_ACTION; - pSoldier->fAIFlags &= ~(AI_LOCK_DOOR_INCLUDES_CLOSE); + // do nothing here + } + else + { - pSoldier->ubDoorOpeningNoise = DoorOpeningNoise( pSoldier ); + pSoldier->fAIFlags &= ~(AI_LOCK_DOOR_INCLUDES_CLOSE); - if ( SoldierHandleInteractiveObject( pSoldier ) ) - { - // HANDLE SIGHT! - //HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO | SIGHT_INTERRUPT ); + pSoldier->ubDoorOpeningNoise = DoorOpeningNoise( pSoldier ); - InitOpplistForDoorOpening(); - - MakeNoise( pSoldier->ubID, pSoldier->sGridNo, pSoldier->bLevel, gpWorldLevelData[pSoldier->sGridNo].ubTerrainID, pSoldier->ubDoorOpeningNoise, NOISE_CREAKING ); - // gfDelayResolvingBestSighting = FALSE; - - gubInterruptProvoker = pSoldier->ubID; - AllTeamsLookForAll( TRUE ); - - // ATE: Now, check AI guy to cancel what he was going.... - HandleSystemNewAISituation( pSoldier, TRUE ); - } - - // EVENT HAS BEEN HANDLED - pSoldier->ubPendingAction = NO_PENDING_ACTION; - - } - - - break; - - case 496: - // CODE: GOTO PREVIOUS ANIMATION - ChangeSoldierState( pSoldier, pSoldier->usOldAniState, pSoldier->sOldAniCode, FALSE ); - return( TRUE ); - - case 497: - - // CODE: CHECK FOR UNCONSCIOUS OR DEATH - // IF 496 - GOTO PREVIOUS ANIMATION, OTHERWISE PAUSE ANIMATION - if ( pSoldier->bLife == 0 ) + if ( SoldierHandleInteractiveObject( pSoldier ) ) { + // HANDLE SIGHT! + //HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO | SIGHT_INTERRUPT ); - //HandleSoldierDeath( pSoldier ); + InitOpplistForDoorOpening(); - // If guy is now dead, and we have not played death sound before, play - if ( pSoldier->bLife == 0 && !pSoldier->fDeadSoundPlayed ) - { - if ( pSoldier->usAnimState != JFK_HITDEATH ) - { - DoMercBattleSound( pSoldier, BATTLE_SOUND_DIE1 ); - pSoldier->fDeadSoundPlayed = TRUE; - } - } + MakeNoise( pSoldier->ubID, pSoldier->sGridNo, pSoldier->bLevel, gpWorldLevelData[pSoldier->sGridNo].ubTerrainID, pSoldier->ubDoorOpeningNoise, NOISE_CREAKING ); + // gfDelayResolvingBestSighting = FALSE; - if ( gGameSettings.fOptions[ TOPTION_BLOOD_N_GORE ] ) + gubInterruptProvoker = pSoldier->ubID; + AllTeamsLookForAll( TRUE ); + + // ATE: Now, check AI guy to cancel what he was going.... + HandleSystemNewAISituation( pSoldier, TRUE ); + } + + // EVENT HAS BEEN HANDLED + pSoldier->ubPendingAction = NO_PENDING_ACTION; + + } + + + break; + + case 496: + // CODE: GOTO PREVIOUS ANIMATION + ChangeSoldierState( pSoldier, pSoldier->usOldAniState, pSoldier->sOldAniCode, FALSE ); + return( TRUE ); + + case 497: + + // CODE: CHECK FOR UNCONSCIOUS OR DEATH + // IF 496 - GOTO PREVIOUS ANIMATION, OTHERWISE PAUSE ANIMATION + if ( pSoldier->bLife == 0 ) + { + + //HandleSoldierDeath( pSoldier ); + + // If guy is now dead, and we have not played death sound before, play + if ( pSoldier->bLife == 0 && !pSoldier->fDeadSoundPlayed ) + { + if ( pSoldier->usAnimState != JFK_HITDEATH ) { - // If we are dead, play some death animations!! - switch( pSoldier->usAnimState ) - { - case FLYBACK_HIT: - ChangeSoldierState( pSoldier, FLYBACK_HIT_DEATH, 0, FALSE ); - break; - - case GENERIC_HIT_DEATHTWITCHNB: - case FALLFORWARD_FROMHIT_STAND: - case ENDFALLFORWARD_FROMHIT_CROUCH: - - ChangeSoldierState( pSoldier, GENERIC_HIT_DEATH, 0, FALSE ); - break; - - case FALLBACK_HIT_DEATHTWITCHNB: - case FALLBACK_HIT_STAND: - ChangeSoldierState( pSoldier, FALLBACK_HIT_DEATH, 0, FALSE ); - break; - - case PRONE_HIT_DEATHTWITCHNB: - case PRONE_LAY_FROMHIT: - - ChangeSoldierState( pSoldier, PRONE_HIT_DEATH, 0, FALSE ); - break; - - case FALLOFF: - ChangeSoldierState( pSoldier, FALLOFF_DEATH, 0, FALSE ); - break; - - case FALLFORWARD_ROOF: - ChangeSoldierState( pSoldier, FALLOFF_FORWARD_DEATH, 0, FALSE); - break; - - case ADULTMONSTER_DYING: - ChangeSoldierState( pSoldier, ADULTMONSTER_DYING_STOP, 0, FALSE); - break; - - case LARVAE_DIE: - ChangeSoldierState( pSoldier, LARVAE_DIE_STOP, 0, FALSE); - break; - - case QUEEN_DIE: - ChangeSoldierState( pSoldier, QUEEN_DIE_STOP, 0, FALSE); - break; - - case INFANT_DIE: - ChangeSoldierState( pSoldier, INFANT_DIE_STOP, 0, FALSE); - break; - - case CRIPPLE_DIE: - ChangeSoldierState( pSoldier, CRIPPLE_DIE_STOP, 0, FALSE); - break; - - case ROBOTNW_DIE: - ChangeSoldierState( pSoldier, ROBOTNW_DIE_STOP, 0, FALSE); - break; - - case CRIPPLE_DIE_FLYBACK: - ChangeSoldierState( pSoldier, CRIPPLE_DIE_FLYBACK_STOP, 0, FALSE); - break; - - default: - // IF we are here - something is wrong - we should have a death animation here - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Soldier Ani: Death sequence needed for animation %d", pSoldier->usAnimState ) ); - - } + DoMercBattleSound( pSoldier, BATTLE_SOUND_DIE1 ); + pSoldier->fDeadSoundPlayed = TRUE; } - else + } + + if ( gGameSettings.fOptions[ TOPTION_BLOOD_N_GORE ] ) + { + // If we are dead, play some death animations!! + switch( pSoldier->usAnimState ) { - BOOLEAN fMadeCorpse; + case FLYBACK_HIT: + ChangeSoldierState( pSoldier, FLYBACK_HIT_DEATH, 0, FALSE ); + break; - CheckForAndHandleSoldierDeath( pSoldier, &fMadeCorpse ); + case GENERIC_HIT_DEATHTWITCHNB: + case FALLFORWARD_FROMHIT_STAND: + case ENDFALLFORWARD_FROMHIT_CROUCH: + + ChangeSoldierState( pSoldier, GENERIC_HIT_DEATH, 0, FALSE ); + break; + + case FALLBACK_HIT_DEATHTWITCHNB: + case FALLBACK_HIT_STAND: + ChangeSoldierState( pSoldier, FALLBACK_HIT_DEATH, 0, FALSE ); + break; + + case PRONE_HIT_DEATHTWITCHNB: + case PRONE_LAY_FROMHIT: + + ChangeSoldierState( pSoldier, PRONE_HIT_DEATH, 0, FALSE ); + break; + + case FALLOFF: + ChangeSoldierState( pSoldier, FALLOFF_DEATH, 0, FALSE ); + break; + + case FALLFORWARD_ROOF: + ChangeSoldierState( pSoldier, FALLOFF_FORWARD_DEATH, 0, FALSE); + break; + + case ADULTMONSTER_DYING: + ChangeSoldierState( pSoldier, ADULTMONSTER_DYING_STOP, 0, FALSE); + break; + + case LARVAE_DIE: + ChangeSoldierState( pSoldier, LARVAE_DIE_STOP, 0, FALSE); + break; + + case QUEEN_DIE: + ChangeSoldierState( pSoldier, QUEEN_DIE_STOP, 0, FALSE); + break; + + case INFANT_DIE: + ChangeSoldierState( pSoldier, INFANT_DIE_STOP, 0, FALSE); + break; + + case CRIPPLE_DIE: + ChangeSoldierState( pSoldier, CRIPPLE_DIE_STOP, 0, FALSE); + break; + + case ROBOTNW_DIE: + ChangeSoldierState( pSoldier, ROBOTNW_DIE_STOP, 0, FALSE); + break; + + case CRIPPLE_DIE_FLYBACK: + ChangeSoldierState( pSoldier, CRIPPLE_DIE_FLYBACK_STOP, 0, FALSE); + break; + + default: + // IF we are here - something is wrong - we should have a death animation here + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Soldier Ani: Death sequence needed for animation %d", pSoldier->usAnimState ) ); - // ATE: Needs to be FALSE! - return( FALSE ); } - return( TRUE ); - } else { - // We can safely be here as well.. ( ie - next turn we may be able to get up ) - // DO SOME CHECKS HERE TO FREE UP ATTACKERS IF WE ARE WAITING AT SPECIFIC ANIMATIONS - if ( ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_HITFINISH ) ) - { - gfPotentialTeamChangeDuringDeath = TRUE; + BOOLEAN fMadeCorpse; - // Release attacker - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, code 497 = check for death") ); - ReleaseSoldiersAttacker( pSoldier ); + CheckForAndHandleSoldierDeath( pSoldier, &fMadeCorpse ); - // ATE: OK - the above call can potentially - // render the soldier bactive to false - check heare - if ( !pSoldier->bActive ) - { - return( FALSE ); - } - - gfPotentialTeamChangeDuringDeath = FALSE; - - // FREEUP GETTING HIT FLAG - pSoldier->fGettingHit = FALSE; - } - - HandleCheckForDeathCommonCode( pSoldier ); - - return( TRUE ); + // ATE: Needs to be FALSE! + return( FALSE ); } - break; + return( TRUE ); - case 498: - - // CONDITONAL JUMP - // If we have a pending animation, play it, else continue - if ( pSoldier->usPendingAnimation != NO_PENDING_ANIMATION ) + } + else + { + // We can safely be here as well.. ( ie - next turn we may be able to get up ) + // DO SOME CHECKS HERE TO FREE UP ATTACKERS IF WE ARE WAITING AT SPECIFIC ANIMATIONS + if ( ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_HITFINISH ) ) { - ChangeSoldierState( pSoldier, pSoldier->usPendingAnimation, 0, FALSE ); - pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; - return( TRUE ); - } - break; + gfPotentialTeamChangeDuringDeath = TRUE; + + // 0verhaul: This is now already handled + // Release attacker + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, code 497 = check for death") ); + // ReleaseSoldiersAttacker( pSoldier ); + + // ATE: OK - the above call can potentially + // render the soldier bactive to false - check heare + if ( !pSoldier->bActive ) + { + return( FALSE ); + } + + gfPotentialTeamChangeDuringDeath = FALSE; + + // FREEUP GETTING HIT FLAG + pSoldier->fGettingHit = FALSE; + } + + HandleCheckForDeathCommonCode( pSoldier ); + + return( TRUE ); + } + break; + + case 498: + + // CONDITONAL JUMP + // If we have a pending animation, play it, else continue + if ( pSoldier->usPendingAnimation != NO_PENDING_ANIMATION ) + { + ChangeSoldierState( pSoldier, pSoldier->usPendingAnimation, 0, FALSE ); + pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; + return( TRUE ); + } + break; // JUMP TO NEXT STATIONARY ANIMATION ACCORDING TO HEIGHT - case 499: + case 499: - if (!(pSoldier->uiStatusFlags & SOLDIER_PC)) + if (!(pSoldier->uiStatusFlags & SOLDIER_PC)) + { + if ( pSoldier->bAction == AI_ACTION_PULL_TRIGGER ) { - if ( pSoldier->bAction == AI_ACTION_PULL_TRIGGER ) + if ( pSoldier->usAnimState == AI_PULL_SWITCH && gTacticalStatus.ubAttackBusyCount == 0 && gubElementsOnExplosionQueue == 0 ) { - if ( pSoldier->usAnimState == AI_PULL_SWITCH && gTacticalStatus.ubAttackBusyCount == 0 && gubElementsOnExplosionQueue == 0 ) - { - FreeUpNPCFromPendingAction( pSoldier ); - } + FreeUpNPCFromPendingAction( pSoldier ); } - else if ( pSoldier->bAction == AI_ACTION_PENDING_ACTION + } + else if ( pSoldier->bAction == AI_ACTION_PENDING_ACTION || pSoldier->bAction == AI_ACTION_OPEN_OR_CLOSE_DOOR || pSoldier->bAction == AI_ACTION_YELLOW_ALERT || pSoldier->bAction == AI_ACTION_RED_ALERT @@ -1950,193 +1976,194 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier ) || pSoldier->bAction == AI_ACTION_CREATURE_CALL || pSoldier->bAction == AI_ACTION_UNLOCK_DOOR || pSoldier->bAction == AI_ACTION_LOCK_DOOR ) + { + if ( pSoldier->usAnimState == PICKUP_ITEM || pSoldier->usAnimState == ADJACENT_GET_ITEM || pSoldier->usAnimState == DROP_ITEM || pSoldier->usAnimState == END_OPEN_DOOR || pSoldier->usAnimState == END_OPEN_DOOR_CROUCHED || pSoldier->usAnimState == CLOSE_DOOR || pSoldier->usAnimState == MONSTER_UP || pSoldier->usAnimState == AI_RADIO || pSoldier->usAnimState == AI_CR_RADIO || pSoldier->usAnimState == END_OPENSTRUCT || pSoldier->usAnimState == END_OPENSTRUCT_CROUCHED || pSoldier->usAnimState == QUEEN_CALL ) { - if ( pSoldier->usAnimState == PICKUP_ITEM || pSoldier->usAnimState == ADJACENT_GET_ITEM || pSoldier->usAnimState == DROP_ITEM || pSoldier->usAnimState == END_OPEN_DOOR || pSoldier->usAnimState == END_OPEN_DOOR_CROUCHED || pSoldier->usAnimState == CLOSE_DOOR || pSoldier->usAnimState == MONSTER_UP || pSoldier->usAnimState == AI_RADIO || pSoldier->usAnimState == AI_CR_RADIO || pSoldier->usAnimState == END_OPENSTRUCT || pSoldier->usAnimState == END_OPENSTRUCT_CROUCHED || pSoldier->usAnimState == QUEEN_CALL ) - { - FreeUpNPCFromPendingAction( pSoldier ); - } + FreeUpNPCFromPendingAction( pSoldier ); + } + } + } + + ubDesiredHeight = pSoldier->ubDesiredHeight; + + // Check if we are at the desired height + if ( pSoldier->ubDesiredHeight == gAnimControl[ pSoldier->usAnimState ].ubEndHeight || pSoldier->ubDesiredHeight == NO_DESIRED_HEIGHT ) + { + // Adjust movement mode...... + if ( pSoldier->bTeam == gbPlayerNum && !pSoldier->fContinueMoveAfterStanceChange ) + { + usUIMovementMode = GetMoveStateBasedOnStance( pSoldier, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ); + + // ATE: if we are currently running but have been told to walk, don't! + if ( pSoldier->usUIMovementMode == RUNNING && usUIMovementMode == WALKING ) + { + // No! + } + else + { + pSoldier->usUIMovementMode = usUIMovementMode; } } - ubDesiredHeight = pSoldier->ubDesiredHeight; - // Check if we are at the desired height - if ( pSoldier->ubDesiredHeight == gAnimControl[ pSoldier->usAnimState ].ubEndHeight || pSoldier->ubDesiredHeight == NO_DESIRED_HEIGHT ) - { - // Adjust movement mode...... - if ( pSoldier->bTeam == gbPlayerNum && !pSoldier->fContinueMoveAfterStanceChange ) + pSoldier->ubDesiredHeight = NO_DESIRED_HEIGHT; + + // 0verhaul: This is moved to the animation state transition code to make sure it isn't sidestepped. + // if (pSoldier->fChangingStanceDueToSuppression) + // { + // pSoldier->fChangingStanceDueToSuppression = FALSE; + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - end of suppression stance change") ); + // ReduceAttackBusyCount( pSoldier->ubSuppressorID, FALSE ); + // } + + if ( pSoldier->usPendingAnimation == NO_PENDING_ANIMATION && ( pSoldier->fTurningFromPronePosition != 3 ) && ( pSoldier->fTurningFromPronePosition != 1 ) ) + { + if ( gTacticalStatus.ubAttackBusyCount == 0 ) { - usUIMovementMode = GetMoveStateBasedOnStance( pSoldier, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ); + // OK, UNSET INTERFACE FIRST + UnSetUIBusy( pSoldier->ubID ); + // ( before we could get interrupted potentially by an interrupt ) + } + } - // ATE: if we are currently running but have been told to walk, don't! - if ( pSoldier->usUIMovementMode == RUNNING && usUIMovementMode == WALKING ) - { - // No! - } - else - { - pSoldier->usUIMovementMode = usUIMovementMode; - } + // Check to see if we have changed stance and need to update visibility + if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_STANCECHANGEANIM) + { + if ( pSoldier->usPendingAnimation == NO_PENDING_ANIMATION && gTacticalStatus.ubAttackBusyCount == 0 && pSoldier->fTurningFromPronePosition != 3 && pSoldier->fTurningFromPronePosition != 1 ) + { + HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO | SIGHT_INTERRUPT ); + } + else + { + HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO ); } - - pSoldier->ubDesiredHeight = NO_DESIRED_HEIGHT; - - if (pSoldier->fChangingStanceDueToSuppression) + // Keep ui busy if we are now in a hidden interrupt + // say we're prone and we crouch, we may get a hidden + // interrupt and in such a case we'd really like the UI + // still locked + if ( gfHiddenInterrupt ) { - pSoldier->fChangingStanceDueToSuppression = FALSE; - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - end of suppression stance change") ); - ReduceAttackBusyCount( pSoldier->ubSuppressorID, FALSE ); + guiPendingOverrideEvent = LA_BEGINUIOURTURNLOCK; + HandleTacticalUI( ); } - if ( pSoldier->usPendingAnimation == NO_PENDING_ANIMATION && ( pSoldier->fTurningFromPronePosition != 3 ) && ( pSoldier->fTurningFromPronePosition != 1 ) ) - { - if ( gTacticalStatus.ubAttackBusyCount == 0 ) - { - // OK, UNSET INTERFACE FIRST - UnSetUIBusy( pSoldier->ubID ); - // ( before we could get interrupted potentially by an interrupt ) - } - } + // ATE: Now, check AI guy to cancel what he was going.... + HandleSystemNewAISituation( pSoldier, TRUE ); + } - // Check to see if we have changed stance and need to update visibility - if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_STANCECHANGEANIM) + // Have we finished opening doors? + if ( pSoldier->usAnimState == END_OPEN_DOOR || pSoldier->usAnimState == END_OPEN_DOOR_CROUCHED || pSoldier->usAnimState == CRIPPLE_CLOSE_DOOR || pSoldier->usAnimState == CRIPPLE_END_OPEN_DOOR ) + { + // Are we told to continue movement...? + if ( pSoldier->bEndDoorOpenCode == 1 ) { - if ( pSoldier->usPendingAnimation == NO_PENDING_ANIMATION && gTacticalStatus.ubAttackBusyCount == 0 && pSoldier->fTurningFromPronePosition != 3 && pSoldier->fTurningFromPronePosition != 1 ) + // OK, set this value to 2 such that once we are into a new gridno, + // we close the door! + pSoldier->bEndDoorOpenCode = 2; + + // yes.. + EVENT_GetNewSoldierPath( pSoldier, pSoldier->sFinalDestination, pSoldier->usUIMovementMode ); + + if ( !( gAnimControl[ pSoldier->usAnimState ].uiFlags & ( ANIM_MOVING ) ) ) { - HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO | SIGHT_INTERRUPT ); - } - else - { - HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO ); - } - - // Keep ui busy if we are now in a hidden interrupt - // say we're prone and we crouch, we may get a hidden - // interrupt and in such a case we'd really like the UI - // still locked - if ( gfHiddenInterrupt ) - { - guiPendingOverrideEvent = LA_BEGINUIOURTURNLOCK; - HandleTacticalUI( ); - } - - // ATE: Now, check AI guy to cancel what he was going.... - HandleSystemNewAISituation( pSoldier, TRUE ); - } - - // Have we finished opening doors? - if ( pSoldier->usAnimState == END_OPEN_DOOR || pSoldier->usAnimState == END_OPEN_DOOR_CROUCHED || pSoldier->usAnimState == CRIPPLE_CLOSE_DOOR || pSoldier->usAnimState == CRIPPLE_END_OPEN_DOOR ) - { - // Are we told to continue movement...? - if ( pSoldier->bEndDoorOpenCode == 1 ) - { - // OK, set this value to 2 such that once we are into a new gridno, - // we close the door! - pSoldier->bEndDoorOpenCode = 2; - - // yes.. - EVENT_GetNewSoldierPath( pSoldier, pSoldier->sFinalDestination, pSoldier->usUIMovementMode ); - - if ( !( gAnimControl[ pSoldier->usAnimState ].uiFlags & ( ANIM_MOVING ) ) ) + if ( pSoldier->sAbsoluteFinalDestination != NOWHERE ) { - if ( pSoldier->sAbsoluteFinalDestination != NOWHERE ) - { - CancelAIAction( pSoldier, FORCE ); - } - } - - // OK, this code, pSoldier->bEndDoorOpenCode will be set to 0 if anythiing - // cuases guy to stop - StopMerc() will set it... - - return( TRUE ); + CancelAIAction( pSoldier, FORCE ); + } } - } - // Check if we should contine into a moving animation - if ( pSoldier->usPendingAnimation != NO_PENDING_ANIMATION ) - { - UINT16 usPendingAnimation = pSoldier->usPendingAnimation; + // OK, this code, pSoldier->bEndDoorOpenCode will be set to 0 if anythiing + // cuases guy to stop - StopMerc() will set it... - pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; - ChangeSoldierState( pSoldier, usPendingAnimation, 0, FALSE ); return( TRUE ); } + } - // Alrighty, do we wish to continue - if ( pSoldier->fContinueMoveAfterStanceChange ) - { - // OK, if the code is == 2, get the path and try to move.... - if ( pSoldier->fContinueMoveAfterStanceChange == 2 ) - { - pSoldier->usPathIndex++; + // Check if we should contine into a moving animation + if ( pSoldier->usPendingAnimation != NO_PENDING_ANIMATION ) + { + UINT16 usPendingAnimation = pSoldier->usPendingAnimation; - if ( pSoldier->usPathIndex > pSoldier->usPathDataSize ) - { - pSoldier->usPathIndex = pSoldier->usPathDataSize; - } - - if ( pSoldier->usPathIndex == pSoldier->usPathDataSize ) - { - // Stop, don't do anything..... - } - else - { - EVENT_InitNewSoldierAnim( pSoldier, pSoldier->usUIMovementMode, 0 , FALSE ); - - // UNSET LOCK PENDING ACTION COUNTER FLAG - pSoldier->uiStatusFlags &= ( ~SOLDIER_LOCKPENDINGACTIONCOUNTER ); - - } - } - else - { - SelectMoveAnimationFromStance( pSoldier ); - } - - pSoldier->fContinueMoveAfterStanceChange = FALSE; - return( TRUE ); - } - SoldierGotoStationaryStance( pSoldier ); + pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; + ChangeSoldierState( pSoldier, usPendingAnimation, 0, FALSE ); return( TRUE ); } - else + + // Alrighty, do we wish to continue + if ( pSoldier->fContinueMoveAfterStanceChange ) { - ubCurrentHeight = gAnimControl[ pSoldier->usAnimState ].ubEndHeight; + // OK, if the code is == 2, get the path and try to move.... + if ( pSoldier->fContinueMoveAfterStanceChange == 2 ) + { + pSoldier->usPathIndex++; - // We need to go more, continue - if ( ubDesiredHeight == ANIM_STAND && ubCurrentHeight == ANIM_CROUCH ) - { - // Return here because if now, we will skipp a few frames - ChangeSoldierState( pSoldier, KNEEL_UP, 0 , FALSE ); - return( TRUE ); + if ( pSoldier->usPathIndex > pSoldier->usPathDataSize ) + { + pSoldier->usPathIndex = pSoldier->usPathDataSize; + } + + if ( pSoldier->usPathIndex == pSoldier->usPathDataSize ) + { + // Stop, don't do anything..... + } + else + { + EVENT_InitNewSoldierAnim( pSoldier, pSoldier->usUIMovementMode, 0 , FALSE ); + + // UNSET LOCK PENDING ACTION COUNTER FLAG + pSoldier->uiStatusFlags &= ( ~SOLDIER_LOCKPENDINGACTIONCOUNTER ); + + } } - if ( ubDesiredHeight == ANIM_CROUCH && ubCurrentHeight == ANIM_STAND ) + else { - // Return here because if now, we will skipp a few frames - ChangeSoldierState( pSoldier, KNEEL_DOWN, 0 , FALSE ); - return( TRUE ); - } - else if ( ubDesiredHeight == ANIM_PRONE && ubCurrentHeight == ANIM_CROUCH ) - { - // Return here because if now, we will skipp a few frames - ChangeSoldierState( pSoldier, PRONE_DOWN, 0 , FALSE ); - return( TRUE ); - } - else if ( ubDesiredHeight == ANIM_CROUCH && ubCurrentHeight == ANIM_PRONE ) - { - // Return here because if now, we will skipp a few frames - ChangeSoldierState( pSoldier, PRONE_UP, 0 , FALSE ); - return( TRUE ); + SelectMoveAnimationFromStance( pSoldier ); } + + pSoldier->fContinueMoveAfterStanceChange = FALSE; + return( TRUE ); } - // IF we are here - something is wrong - we should have a death animation here - #ifdef JA2BETAVERSION - ScreenMsg( FONT_ORANGE, MSG_BETAVERSION, L"Soldier Ani: GOTO Stance not chained properly: %d %d %d", ubDesiredHeight, ubCurrentHeight, pSoldier->usAnimState ); - #endif - SoldierGotoStationaryStance( pSoldier ); return( TRUE ); + } + else + { + ubCurrentHeight = gAnimControl[ pSoldier->usAnimState ].ubEndHeight; + + // We need to go more, continue + if ( ubDesiredHeight == ANIM_STAND && ubCurrentHeight == ANIM_CROUCH ) + { + // Return here because if now, we will skipp a few frames + ChangeSoldierState( pSoldier, KNEEL_UP, 0 , FALSE ); + return( TRUE ); + } + if ( ubDesiredHeight == ANIM_CROUCH && ubCurrentHeight == ANIM_STAND ) + { + // Return here because if now, we will skipp a few frames + ChangeSoldierState( pSoldier, KNEEL_DOWN, 0 , FALSE ); + return( TRUE ); + } + else if ( ubDesiredHeight == ANIM_PRONE && ubCurrentHeight == ANIM_CROUCH ) + { + // Return here because if now, we will skipp a few frames + ChangeSoldierState( pSoldier, PRONE_DOWN, 0 , FALSE ); + return( TRUE ); + } + else if ( ubDesiredHeight == ANIM_CROUCH && ubCurrentHeight == ANIM_PRONE ) + { + // Return here because if now, we will skipp a few frames + ChangeSoldierState( pSoldier, PRONE_UP, 0 , FALSE ); + return( TRUE ); + } + } + // IF we are here - something is wrong - we should have a death animation here +#ifdef JA2BETAVERSION + ScreenMsg( FONT_ORANGE, MSG_BETAVERSION, L"Soldier Ani: GOTO Stance not chained properly: %d %d %d", ubDesiredHeight, ubCurrentHeight, pSoldier->usAnimState ); +#endif + + SoldierGotoStationaryStance( pSoldier ); + return( TRUE ); } // Adjust frame control pos, and try again @@ -2171,642 +2198,646 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier ) { switch( sNewAniFrame ) { - case 702: - // Play fall to knees sound - PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( FALL_1 + Random(2) ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); - break; + case 702: + // Play fall to knees sound + PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( FALL_1 + Random(2) ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); + break; - case 703: - case 704: + case 703: + case 704: - // Play footprints - PlaySoldierFootstepSound( pSoldier ); - break; + // Play footprints + PlaySoldierFootstepSound( pSoldier ); + break; - case 705: - // PLay body splat sound - PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)BODY_SPLAT_1, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + case 705: + // PLay body splat sound + PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)BODY_SPLAT_1, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - case 706: - // PLay head splat - PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)HEADSPLAT_1, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) , TRUE ); - break; + case 706: + // PLay head splat + PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)HEADSPLAT_1, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) , TRUE ); + break; - case 707: - // PLay creature battle cry - PlayJA2StreamingSample( (UINT8)CREATURE_BATTLECRY_1, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - break; + case 707: + // PLay creature battle cry + PlayJA2StreamingSample( (UINT8)CREATURE_BATTLECRY_1, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); + break; - case 708: + case 708: - // PLay lock n' load sound for gun.... - // Get LNL sound for current gun + // PLay lock n' load sound for gun.... + // Get LNL sound for current gun + { + UINT16 usItem; + UINT16 usSoundID; + + usItem = pSoldier->inv[ HANDPOS ].usItem; + + if ( usItem != NOTHING ) { - UINT16 usItem; - UINT16 usSoundID; + usSoundID = Weapon[ usItem ].sLocknLoadSound; - usItem = pSoldier->inv[ HANDPOS ].usItem; - - if ( usItem != NOTHING ) + if ( usSoundID != 0 ) { - usSoundID = Weapon[ usItem ].sLocknLoadSound; - - if ( usSoundID != 0 ) - { - PlayJA2Sample( usSoundID, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - } + PlayJA2Sample( usSoundID, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); } } - break; + } + break; - case 709: + case 709: - // Knife throw sound... - PlayJA2Sample( Weapon[ THROWING_KNIFE ].sSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - break; + // Knife throw sound... + PlayJA2Sample( Weapon[ THROWING_KNIFE ].sSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); + break; - case 710: + case 710: - // Monster footstep in + // Monster footstep in + if ( SoldierOnScreen( pSoldier->ubID ) ) + { + PlaySoldierJA2Sample( pSoldier->ubID, ACR_STEP_1, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + } + break; + + case 711: + + // Monster footstep in + if ( SoldierOnScreen( pSoldier->ubID ) ) + { + PlaySoldierJA2Sample( pSoldier->ubID, ACR_STEP_2, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + } + break; + + case 712: + + // Monster footstep in + if ( SoldierOnScreen( pSoldier->ubID ) ) + { + PlaySoldierJA2Sample( pSoldier->ubID, LCR_MOVEMENT, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + } + break; + + case 713: + + // Monster footstep in + if ( pSoldier->ubBodyType == INFANT_MONSTER ) + { if ( SoldierOnScreen( pSoldier->ubID ) ) { - PlaySoldierJA2Sample( pSoldier->ubID, ACR_STEP_1, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + PlaySoldierJA2Sample( pSoldier->ubID, BCR_DRAGGING, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); } - break; + } + break; - case 711: + case 714: - // Monster footstep in - if ( SoldierOnScreen( pSoldier->ubID ) ) + // Lunges.... + PlaySoldierJA2Sample( pSoldier->ubID, ACR_LUNGE, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; + + case 715: + + // Swipe + PlaySoldierJA2Sample( pSoldier->ubID, ACR_SWIPE, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; + + case 716: + + // Eat flesh + PlaySoldierJA2Sample( pSoldier->ubID, ACR_EATFLESH, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; + + case 717: + + // Battle cry + { + INT32 iSoundID=0; + BOOLEAN fDoCry = FALSE; + + //if ( SoldierOnScreen( pSoldier->ubID ) ) { - PlaySoldierJA2Sample( pSoldier->ubID, ACR_STEP_2, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - } - break; - - case 712: - - // Monster footstep in - if ( SoldierOnScreen( pSoldier->ubID ) ) - { - PlaySoldierJA2Sample( pSoldier->ubID, LCR_MOVEMENT, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - } - break; - - case 713: - - // Monster footstep in - if ( pSoldier->ubBodyType == INFANT_MONSTER ) - { - if ( SoldierOnScreen( pSoldier->ubID ) ) + switch( pSoldier->usActionData ) { - PlaySoldierJA2Sample( pSoldier->ubID, BCR_DRAGGING, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + case CALL_1_PREY: + + if ( pSoldier->ubBodyType == QUEENMONSTER ) + { + iSoundID = LQ_SMELLS_THREAT; + } + else + { + iSoundID = ACR_SMEEL_PREY; + } + fDoCry = TRUE; + break; + + case CALL_MULTIPLE_PREY: + + if ( pSoldier->ubBodyType == QUEENMONSTER ) + { + iSoundID = LQ_SMELLS_THREAT; + } + else + { + iSoundID = ACR_SMELL_THREAT; + } + fDoCry = TRUE; + break; + + case CALL_ATTACKED: + + if ( pSoldier->ubBodyType == QUEENMONSTER ) + { + iSoundID = LQ_ENRAGED_ATTACK; + } + else + { + iSoundID = ACR_SMELL_THREAT; + } + fDoCry = TRUE; + break; + + case CALL_CRIPPLED: + + if ( pSoldier->ubBodyType == QUEENMONSTER ) + { + iSoundID = LQ_CRIPPLED; + } + else + { + iSoundID = ACR_CRIPPLED; + } + fDoCry = TRUE; + break; + } + + if ( fDoCry ) + { + PlayJA2Sample( iSoundID, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); } } - break; + } + break; - case 714: - - // Lunges.... - PlaySoldierJA2Sample( pSoldier->ubID, ACR_LUNGE, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; - - case 715: - - // Swipe - PlaySoldierJA2Sample( pSoldier->ubID, ACR_SWIPE, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; - - case 716: - - // Eat flesh - PlaySoldierJA2Sample( pSoldier->ubID, ACR_EATFLESH, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; - - case 717: - - // Battle cry - { - INT32 iSoundID=0; - BOOLEAN fDoCry = FALSE; - - //if ( SoldierOnScreen( pSoldier->ubID ) ) - { - switch( pSoldier->usActionData ) - { - case CALL_1_PREY: - - if ( pSoldier->ubBodyType == QUEENMONSTER ) - { - iSoundID = LQ_SMELLS_THREAT; - } - else - { - iSoundID = ACR_SMEEL_PREY; - } - fDoCry = TRUE; - break; - - case CALL_MULTIPLE_PREY: - - if ( pSoldier->ubBodyType == QUEENMONSTER ) - { - iSoundID = LQ_SMELLS_THREAT; - } - else - { - iSoundID = ACR_SMELL_THREAT; - } - fDoCry = TRUE; - break; - - case CALL_ATTACKED: - - if ( pSoldier->ubBodyType == QUEENMONSTER ) - { - iSoundID = LQ_ENRAGED_ATTACK; - } - else - { - iSoundID = ACR_SMELL_THREAT; - } - fDoCry = TRUE; - break; - - case CALL_CRIPPLED: - - if ( pSoldier->ubBodyType == QUEENMONSTER ) - { - iSoundID = LQ_CRIPPLED; - } - else - { - iSoundID = ACR_CRIPPLED; - } - fDoCry = TRUE; - break; - } - - if ( fDoCry ) - { - PlayJA2Sample( iSoundID, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - } - } - } - break; - - case 718: + case 718: - PlaySoldierJA2Sample( pSoldier->ubID, LQ_RUPTURING, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + PlaySoldierJA2Sample( pSoldier->ubID, LQ_RUPTURING, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - case 719: + case 719: - // Spit attack start sound... - PlaySoldierJA2Sample( pSoldier->ubID, LQ_ENRAGED_ATTACK, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + // Spit attack start sound... + PlaySoldierJA2Sample( pSoldier->ubID, LQ_ENRAGED_ATTACK, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - case 720: + case 720: - // Spit attack start sound... - PlaySoldierJA2Sample( pSoldier->ubID, LQ_WHIP_ATTACK, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + // Spit attack start sound... + PlaySoldierJA2Sample( pSoldier->ubID, LQ_WHIP_ATTACK, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - case 721: - // Play fall from knees to ground... - PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( FALL_TO_GROUND_1 + Random(3) ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); - if ( pSoldier->usAnimState == FALLFORWARD_FROMHIT_STAND ) - { - CheckEquipmentForFragileItemDamage( pSoldier, 20 ); - } - break; + case 721: + // Play fall from knees to ground... + PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( FALL_TO_GROUND_1 + Random(3) ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); + if ( pSoldier->usAnimState == FALLFORWARD_FROMHIT_STAND ) + { + CheckEquipmentForFragileItemDamage( pSoldier, 20 ); + } + break; - case 722: - // Play fall heavy - PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( HEAVY_FALL_1 ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); - if ( pSoldier->usAnimState == FALLFORWARD_FROMHIT_CROUCH ) - { - CheckEquipmentForFragileItemDamage( pSoldier, 15 ); - } - break; + case 722: + // Play fall heavy + PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( HEAVY_FALL_1 ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); + if ( pSoldier->usAnimState == FALLFORWARD_FROMHIT_CROUCH ) + { + CheckEquipmentForFragileItemDamage( pSoldier, 15 ); + } + break; - case 723: + case 723: - // Play armpit noise... - PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( IDLE_ARMPIT ), RATE_11025, SoundVolume( LOWVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + // Play armpit noise... + PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( IDLE_ARMPIT ), RATE_11025, SoundVolume( LOWVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - case 724: + case 724: - // Play ass scratch - // PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( IDLE_SCRATCH ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + // Play ass scratch + // PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( IDLE_SCRATCH ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - case 725: + case 725: - // Play back crack - PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( IDLE_BACKCRACK ), RATE_11025, SoundVolume( LOWVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + // Play back crack + PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( IDLE_BACKCRACK ), RATE_11025, SoundVolume( LOWVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - case 726: + case 726: - // Kickin door - PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( KICKIN_DOOR ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + // Kickin door + PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( KICKIN_DOOR ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - case 727: + case 727: - // Swoosh - PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( SWOOSH_1 + Random( 6 ) ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + // Swoosh + PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( SWOOSH_1 + Random( 6 ) ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - case 728: + case 728: - // Creature fall - PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( ACR_FALL_1 ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + // Creature fall + PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( ACR_FALL_1 ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - case 729: + case 729: - // grab roof.... - PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( GRAB_ROOF ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + // grab roof.... + PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( GRAB_ROOF ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - case 730: + case 730: - // end climb roof.... - PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( LAND_ON_ROOF ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + // end climb roof.... + PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( LAND_ON_ROOF ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - case 731: + case 731: - // Stop climb roof.. - PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( FALL_TO_GROUND_1 + Random(3) ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + // Stop climb roof.. + PlaySoldierJA2Sample( pSoldier->ubID, (UINT8)( FALL_TO_GROUND_1 + Random(3) ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - case 732: + case 732: - // Play die sound - DoMercBattleSound( pSoldier, BATTLE_SOUND_DIE1 ); - pSoldier->fDeadSoundPlayed = TRUE; - break; + // Play die sound + DoMercBattleSound( pSoldier, BATTLE_SOUND_DIE1 ); + pSoldier->fDeadSoundPlayed = TRUE; + break; - case 750: + case 750: - // CODE: Move Vehicle UP - if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) - { + // CODE: Move Vehicle UP + if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) + { // SetSoldierHeight( pSoldier, (FLOAT)( pSoldier->sHeightAdjustment + 1 ) ); - } - break; + } + break; - case 751: + case 751: - // CODE: Move vehicle down - if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) + // CODE: Move vehicle down + if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) + { + // SetSoldierHeight( pSoldier, (FLOAT)( pSoldier->sHeightAdjustment - 1 ) ); + } + break; + + case 752: + + // Code: decapitate + DecapitateCorpse( pSoldier, pSoldier->sTargetGridNo, pSoldier->bTargetLevel ); + break; + + case 753: + + // code: freeup attcker + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., CODE FROM ANIMATION %s ( %d )", gAnimControl[ pSoldier->usAnimState ].zAnimStr, pSoldier->usAnimState ) ); + DebugAttackBusy( String("@@@@@@@ Reducing attacker busy count..., CODE FROM ANIMATION %s ( %d )\n", gAnimControl[ pSoldier->usAnimState ].zAnimStr, pSoldier->usAnimState ) ); + // ReduceAttackBusyCount( pSoldier->ubID, FALSE ); + + // ATE: Here, reduce again if creaturequeen tentical attack... + // Uh, why not add a second 753 code to the queen swipe instead of adding code to make things more complex? + if ( pSoldier->usAnimState == QUEEN_SWIPE ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count for end of queen swipe\n" ) ); + DebugAttackBusy( "@@@@@@@ Reducing attacker busy count for end of queen swipe" ); + // ReduceAttackBusyCount( pSoldier->ubID, FALSE ); + } + break; + + case 754: + + HandleFallIntoPitFromAnimation( pSoldier->ubID ); + break; + + case 755 : + + DishoutQueenSwipeDamage( pSoldier ); + break; + + case 756: + + // Reload robot.... + { + UINT8 ubPerson; + SOLDIERTYPE *pRobot; + + // Get pointer... + ubPerson = WhoIsThere2( pSoldier->sPendingActionData2, pSoldier->bLevel ); + + if ( ubPerson != NOBODY && MercPtrs[ ubPerson ]->uiStatusFlags & SOLDIER_ROBOT ) { - // SetSoldierHeight( pSoldier, (FLOAT)( pSoldier->sHeightAdjustment - 1 ) ); - } - break; + pRobot = MercPtrs[ ubPerson ]; - case 752: + ReloadGun( pRobot, &(pRobot->inv[ HANDPOS ] ), pSoldier->pTempObject ); - // Code: decapitate - DecapitateCorpse( pSoldier, pSoldier->sTargetGridNo, pSoldier->bTargetLevel ); - break; - - case 753: - - // code: freeup attcker - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., CODE FROM ANIMATION %s ( %d )", gAnimControl[ pSoldier->usAnimState ].zAnimStr, pSoldier->usAnimState ) ); - ReduceAttackBusyCount( pSoldier->ubID, FALSE ); - - // ATE: Here, reduce again if creaturequeen tentical attack... - if ( pSoldier->usAnimState == QUEEN_SWIPE ) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count for end of queen swipe\n" ) ); - ReduceAttackBusyCount( pSoldier->ubID, FALSE ); - } - break; - - case 754: - - HandleFallIntoPitFromAnimation( pSoldier->ubID ); - break; - - case 755 : - - DishoutQueenSwipeDamage( pSoldier ); - break; - - case 756: - - // Reload robot.... - { - UINT8 ubPerson; - SOLDIERTYPE *pRobot; - - // Get pointer... - ubPerson = WhoIsThere2( pSoldier->sPendingActionData2, pSoldier->bLevel ); - - if ( ubPerson != NOBODY && MercPtrs[ ubPerson ]->uiStatusFlags & SOLDIER_ROBOT ) + // OK, check what was returned and place in inventory if it's non-zero + if ( pSoldier->pTempObject->usItem != NOTHING ) { - pRobot = MercPtrs[ ubPerson ]; - - ReloadGun( pRobot, &(pRobot->inv[ HANDPOS ] ), pSoldier->pTempObject ); - - // OK, check what was returned and place in inventory if it's non-zero - if ( pSoldier->pTempObject->usItem != NOTHING ) - { - // Add to inv.. - AutoPlaceObject( pSoldier, pSoldier->pTempObject, TRUE ); - } - - MemFree( pSoldier->pTempObject ); - pSoldier->pTempObject = NULL; + // Add to inv.. + AutoPlaceObject( pSoldier, pSoldier->pTempObject, TRUE ); } - } - break; - - case 757: - - // INcrement attacker busy count.... - gTacticalStatus.ubAttackBusyCount++; - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!! Incrementing attacker busy count..., CODE FROM ANIMATION %s ( %d ) : Count now %d", gAnimControl[ pSoldier->usAnimState ].zAnimStr, pSoldier->usAnimState, gTacticalStatus.ubAttackBusyCount ) ); - break; - - case 758: - - // Trigger after slap... - TriggerNPCWithGivenApproach( QUEEN, APPROACH_DONE_SLAPPED , TRUE ); - break; - - case 759: - - // Getting hit by slap - { - SOLDIERTYPE *pTarget; - - pTarget = FindSoldierByProfileID( ELLIOT, FALSE ); - - if ( pTarget ) - { - EVENT_InitNewSoldierAnim( pTarget, SLAP_HIT, 0 , FALSE ); - - // Play noise.... - //PlaySoldierJA2Sample( pTarget->ubID, ( S_SLAP_IMPACT ), RATE_11025, SoundVolume( HIGHVOLUME, pTarget->sGridNo ), 1, SoundDir( pTarget->sGridNo ), TRUE ); - - //DoMercBattleSound( pTarget, (INT8)( BATTLE_SOUND_HIT1 + Random( 2 ) ) ); - - } - } - break; - - case 760: - - // Get some blood..... - // Corpse Id is from pending action data - GetBloodFromCorpse( pSoldier ); - // Dirty interface.... - DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); - break; - - case 761: - - { - // Dish out damage! - EVENT_SoldierGotHit( MercPtrs[ pSoldier->uiPendingActionData4 ], TAKE_DAMAGE_BLADE, (INT16) 25, (INT16) 25, gOppositeDirection[ pSoldier->bDirection ], 50, pSoldier->ubID, 0, ANIM_PRONE, 0, 0 ); - } - break; - - case 762: - { - // CODE: Set off Trigger - INT8 bPanicTrigger; - - bPanicTrigger = ClosestPanicTrigger( pSoldier ); - SetOffPanicBombs( pSoldier->ubID, bPanicTrigger ); - // any AI guy has been specially given keys for this, now take them - // away - pSoldier->bHasKeys = pSoldier->bHasKeys >> 1; - - } - break; - - case 763: - - // CODE: Drop item at gridno - if ( pSoldier->pTempObject != NULL ) - { - if ( pSoldier->bVisible != -1 ) - { - PlayJA2Sample( THROW_IMPACT_2, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - } - - AddItemToPool( pSoldier->sPendingActionData2, pSoldier->pTempObject, 1, pSoldier->bLevel, 0 , -1 ); - NotifySoldiersToLookforItems( ); MemFree( pSoldier->pTempObject ); pSoldier->pTempObject = NULL; } - break; - - case 764: + } + break; - PlaySoldierJA2Sample( pSoldier->ubID, PICKING_LOCK, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + case 757: - case 765: + // INcrement attacker busy count.... +// gTacticalStatus.ubAttackBusyCount++; + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!! Incrementing attacker busy count..., CODE FROM ANIMATION %s ( %d ) : Count now %d", gAnimControl[ pSoldier->usAnimState ].zAnimStr, pSoldier->usAnimState, gTacticalStatus.ubAttackBusyCount ) ); + DebugAttackBusy( String("!!!!! CODE FROM ANIMATION %s ( %d )\n", gAnimControl[ pSoldier->usAnimState ].zAnimStr, pSoldier->usAnimState ) ); + break; - // Flyback hit - do blood! - // PLace in existing tile and one back... + case 758: + + // Trigger after slap... + TriggerNPCWithGivenApproach( QUEEN, APPROACH_DONE_SLAPPED , TRUE ); + break; + + case 759: + + // Getting hit by slap + { + SOLDIERTYPE *pTarget; + + pTarget = FindSoldierByProfileID( ELLIOT, FALSE ); + + if ( pTarget ) { - INT16 sNewGridNo; + EVENT_InitNewSoldierAnim( pTarget, SLAP_HIT, 0 , FALSE ); - InternalDropBlood( pSoldier->sGridNo, pSoldier->bLevel, 0, (UINT8)(MAXBLOODQUANTITY), 1 ); + // Play noise.... + //PlaySoldierJA2Sample( pTarget->ubID, ( S_SLAP_IMPACT ), RATE_11025, SoundVolume( HIGHVOLUME, pTarget->sGridNo ), 1, SoundDir( pTarget->sGridNo ), TRUE ); - // Move forward one gridno.... - sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)( DirectionInc( gOppositeDirection[ pSoldier->bDirection ] ) ) ); - - InternalDropBlood( sNewGridNo, pSoldier->bLevel, 0, (UINT8)(MAXBLOODQUANTITY), 1 ); + //DoMercBattleSound( pTarget, (INT8)( BATTLE_SOUND_HIT1 + Random( 2 ) ) ); } - break; + } + break; - case 766: + case 760: - // Say COOL quote - DoMercBattleSound( pSoldier, BATTLE_SOUND_COOL1 ); - break; + // Get some blood..... + // Corpse Id is from pending action data + GetBloodFromCorpse( pSoldier ); + // Dirty interface.... + DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); + break; - case 767: + case 761: - // Slap sound effect - PlaySoldierJA2Sample( pSoldier->ubID, SLAP_2, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); - break; + { + // Dish out damage! + EVENT_SoldierGotHit( MercPtrs[ pSoldier->uiPendingActionData4 ], TAKE_DAMAGE_BLADE, (INT16) 25, (INT16) 25, gOppositeDirection[ pSoldier->bDirection ], 50, pSoldier->ubID, 0, ANIM_PRONE, 0, 0 ); + } + break; - case 768: + case 762: + { + // CODE: Set off Trigger + INT8 bPanicTrigger; - // OK, after ending first aid, stand up if not in combat.... - if ( NumCapableEnemyInSector( ) == 0 ) + bPanicTrigger = ClosestPanicTrigger( pSoldier ); + SetOffPanicBombs( pSoldier->ubID, bPanicTrigger ); + // any AI guy has been specially given keys for this, now take them + // away + pSoldier->bHasKeys = pSoldier->bHasKeys >> 1; + + } + break; + + case 763: + + // CODE: Drop item at gridno + if ( pSoldier->pTempObject != NULL ) + { + if ( pSoldier->bVisible != -1 ) { - // Stand up... - ChangeSoldierStance( pSoldier, ANIM_STAND ); - return( FALSE ); + PlayJA2Sample( THROW_IMPACT_2, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); } - break; - case 769: + AddItemToPool( pSoldier->sPendingActionData2, pSoldier->pTempObject, 1, pSoldier->bLevel, 0 , -1 ); + NotifySoldiersToLookforItems( ); - // ATE: LOOK HERE FOR CODE IN INTERNALS FOR - // REFUELING A VEHICLE - // THE GAS_CAN IS IN THE MERCS MAIN HAND AT THIS TIME - { - UINT8 ubPerson; - SOLDIERTYPE *pVehicle; + MemFree( pSoldier->pTempObject ); + pSoldier->pTempObject = NULL; + } + break; - // Get pointer to vehicle... - ubPerson = WhoIsThere2( pSoldier->sPendingActionData2, pSoldier->bLevel ); - pVehicle = MercPtrs[ ubPerson ]; + case 764: - // this is a ubID for soldiertype.... - AddFuelToVehicle( pSoldier, pVehicle ); + PlaySoldierJA2Sample( pSoldier->ubID, PICKING_LOCK, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - fInterfacePanelDirty = DIRTYLEVEL2; - } - break; + case 765: - case 770: + // Flyback hit - do blood! + // PLace in existing tile and one back... + { + INT16 sNewGridNo; - PlayJA2Sample( USE_WIRE_CUTTERS, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); - break; - - case 771: + InternalDropBlood( pSoldier->sGridNo, pSoldier->bLevel, 0, (UINT8)(MAXBLOODQUANTITY), 1 ); - PlayJA2Sample( BLOODCAT_ATTACK, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); - break; + // Move forward one gridno.... + sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)( DirectionInc( gOppositeDirection[ pSoldier->bDirection ] ) ) ); - case 772: + InternalDropBlood( sNewGridNo, pSoldier->bLevel, 0, (UINT8)(MAXBLOODQUANTITY), 1 ); - //CODE: FOR A REALTIME NON-INTERRUPTABLE SCRIPT - SIGNAL DONE - pSoldier->fRTInNonintAnim = FALSE; - break; + } + break; - case 773: + case 766: - // Kneel up... - if ( !pSoldier->bStealthMode ) - { - PlaySoldierJA2Sample( pSoldier->ubID, KNEEL_UP_SOUND, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - } - break; + // Say COOL quote + DoMercBattleSound( pSoldier, BATTLE_SOUND_COOL1 ); + break; - case 774: + case 767: - // Kneel down.. - if ( !pSoldier->bStealthMode ) - { - PlaySoldierJA2Sample( pSoldier->ubID, KNEEL_DOWN_SOUND, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - } - break; + // Slap sound effect + PlaySoldierJA2Sample( pSoldier->ubID, SLAP_2, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); + break; - case 775: + case 768: - // prone up.. - if ( !pSoldier->bStealthMode ) - { - PlaySoldierJA2Sample( pSoldier->ubID, PRONE_UP_SOUND, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - } - break; + // OK, after ending first aid, stand up if not in combat.... + if ( NumCapableEnemyInSector( ) == 0 ) + { + // Stand up... + ChangeSoldierStance( pSoldier, ANIM_STAND ); + return( FALSE ); + } + break; - case 776: + case 769: - // prone down.. - if ( !pSoldier->bStealthMode ) - { - PlaySoldierJA2Sample( pSoldier->ubID, PRONE_DOWN_SOUND, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - } - break; + // ATE: LOOK HERE FOR CODE IN INTERNALS FOR + // REFUELING A VEHICLE + // THE GAS_CAN IS IN THE MERCS MAIN HAND AT THIS TIME + { + UINT8 ubPerson; + SOLDIERTYPE *pVehicle; - case 777: + // Get pointer to vehicle... + ubPerson = WhoIsThere2( pSoldier->sPendingActionData2, pSoldier->bLevel ); + pVehicle = MercPtrs[ ubPerson ]; - // picking something up - if ( !pSoldier->bStealthMode ) - { - PlaySoldierJA2Sample( pSoldier->ubID, PICKING_SOMETHING_UP, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - } - break; + // this is a ubID for soldiertype.... + AddFuelToVehicle( pSoldier, pVehicle ); - case 778: - if ( !pSoldier->bStealthMode ) - { - PlaySoldierJA2Sample( pSoldier->ubID, ENTER_DEEP_WATER_1, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - } - break; + fInterfacePanelDirty = DIRTYLEVEL2; + } + break; - case 779: + case 770: - PlaySoldierJA2Sample( pSoldier->ubID, COW_FALL, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + PlayJA2Sample( USE_WIRE_CUTTERS, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); + break; - case 780: + case 771: - PlaySoldierJA2Sample( pSoldier->ubID, COW_HIT_SND, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + PlayJA2Sample( BLOODCAT_ATTACK, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); + break; - case 781: + case 772: - PlaySoldierJA2Sample( pSoldier->ubID, ACR_DIE_PART2, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); - break; + //CODE: FOR A REALTIME NON-INTERRUPTABLE SCRIPT - SIGNAL DONE + pSoldier->fRTInNonintAnim = FALSE; + break; - case 782: + case 773: - PlaySoldierJA2Sample( pSoldier->ubID, CREATURE_DISSOLVE_1, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); - break; + // Kneel up... + if ( !pSoldier->bStealthMode ) + { + PlaySoldierJA2Sample( pSoldier->ubID, KNEEL_UP_SOUND, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + } + break; - case 784: + case 774: - PlaySoldierJA2Sample( pSoldier->ubID, CREATURE_FALL, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); - break; + // Kneel down.. + if ( !pSoldier->bStealthMode ) + { + PlaySoldierJA2Sample( pSoldier->ubID, KNEEL_DOWN_SOUND, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + } + break; - case 785: + case 775: - if ( Random( 5 ) == 0 ) - { - PlaySoldierJA2Sample( pSoldier->ubID, CROW_PECKING_AT_FLESH, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - } - break; + // prone up.. + if ( !pSoldier->bStealthMode ) + { + PlaySoldierJA2Sample( pSoldier->ubID, PRONE_UP_SOUND, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + } + break; - case 786: + case 776: - PlaySoldierJA2Sample( pSoldier->ubID, CROW_FLYING_AWAY, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + // prone down.. + if ( !pSoldier->bStealthMode ) + { + PlaySoldierJA2Sample( pSoldier->ubID, PRONE_DOWN_SOUND, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + } + break; - case 787: + case 777: - PlaySoldierJA2Sample( pSoldier->ubID, SLAP_1, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); - break; + // picking something up + if ( !pSoldier->bStealthMode ) + { + PlaySoldierJA2Sample( pSoldier->ubID, PICKING_SOMETHING_UP, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + } + break; - case 788: + case 778: + if ( !pSoldier->bStealthMode ) + { + PlaySoldierJA2Sample( pSoldier->ubID, ENTER_DEEP_WATER_1, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + } + break; - PlaySoldierJA2Sample( pSoldier->ubID, MORTAR_START, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + case 779: - case 789: + PlaySoldierJA2Sample( pSoldier->ubID, COW_FALL, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - PlaySoldierJA2Sample( pSoldier->ubID, MORTAR_LOAD, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + case 780: - case 790: + PlaySoldierJA2Sample( pSoldier->ubID, COW_HIT_SND, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; - PlaySoldierJA2Sample( pSoldier->ubID, COW_FALL_2, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + case 781: - case 791: + PlaySoldierJA2Sample( pSoldier->ubID, ACR_DIE_PART2, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); + break; - PlaySoldierJA2Sample( pSoldier->ubID, FENCE_OPEN, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + case 782: + + PlaySoldierJA2Sample( pSoldier->ubID, CREATURE_DISSOLVE_1, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); + break; + + case 784: + + PlaySoldierJA2Sample( pSoldier->ubID, CREATURE_FALL, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); + break; + + case 785: + + if ( Random( 5 ) == 0 ) + { + PlaySoldierJA2Sample( pSoldier->ubID, CROW_PECKING_AT_FLESH, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + } + break; + + case 786: + + PlaySoldierJA2Sample( pSoldier->ubID, CROW_FLYING_AWAY, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; + + case 787: + + PlaySoldierJA2Sample( pSoldier->ubID, SLAP_1, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), FALSE ); + break; + + case 788: + + PlaySoldierJA2Sample( pSoldier->ubID, MORTAR_START, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; + + case 789: + + PlaySoldierJA2Sample( pSoldier->ubID, MORTAR_LOAD, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; + + case 790: + + PlaySoldierJA2Sample( pSoldier->ubID, COW_FALL_2, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; + + case 791: + + PlaySoldierJA2Sample( pSoldier->ubID, FENCE_OPEN, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + break; } // Adjust frame control pos, and try again @@ -2817,13 +2848,13 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier ) // Go to start, by default pSoldier->usAniCode = 0; - + } - // Loop here until we break on a real item! - } while ( TRUE ); + // Loop here until we break on a real item! + } while ( TRUE ); - // We're done + // We're done return( TRUE ); } @@ -2841,19 +2872,19 @@ BOOLEAN ShouldMercSayHappyWithGunQuote( SOLDIERTYPE *pSoldier ) return( FALSE ); } - // is it a gun? - if ( Item[ pSoldier->usAttackingWeapon ].usItemClass & IC_GUN ) - { - // Is our weapon powerfull enough? - if ( Weapon[ pSoldier->usAttackingWeapon ].ubDeadliness > MIN_DEADLINESS_FOR_LIKE_GUN_QUOTE ) - { - // 20 % chance? - if ( Random( 100 ) < 20 ) - { - return( TRUE ); - } - } - } + // is it a gun? + if ( Item[ pSoldier->usAttackingWeapon ].usItemClass & IC_GUN ) + { + // Is our weapon powerfull enough? + if ( Weapon[ pSoldier->usAttackingWeapon ].ubDeadliness > MIN_DEADLINESS_FOR_LIKE_GUN_QUOTE ) + { + // 20 % chance? + if ( Random( 100 ) < 20 ) + { + return( TRUE ); + } + } + } } return( FALSE ); @@ -2864,13 +2895,13 @@ void SayBuddyWitnessedQuoteFromKill( SOLDIERTYPE *pKillerSoldier, INT16 sGridNo, { UINT8 ubMercsInSector[ 20 ] = { 0 }; INT8 bBuddyIndex[ 20 ] = { -1 }; - INT8 bTempBuddyIndex; + INT8 bTempBuddyIndex; UINT8 ubNumMercs = 0; UINT8 ubChosenMerc; SOLDIERTYPE *pTeamSoldier; INT32 cnt; INT16 sDistVisible = FALSE; - UINT16 usQuoteNum; + UINT16 usQuoteNum; // Loop through all our guys and randomly say one from someone in our sector @@ -2883,86 +2914,86 @@ void SayBuddyWitnessedQuoteFromKill( SOLDIERTYPE *pKillerSoldier, INT16 sGridNo, // Add guy if he's a candidate... if ( OK_INSECTOR_MERC( pTeamSoldier ) && !AM_AN_EPC( pTeamSoldier ) && !( pTeamSoldier->uiStatusFlags & SOLDIER_GASSED ) && !(AM_A_ROBOT( pTeamSoldier )) && !pTeamSoldier->fMercAsleep && pTeamSoldier->sGridNo != NOWHERE ) { - // Are we a buddy of killer? + // Are we a buddy of killer? bTempBuddyIndex = WhichBuddy( pTeamSoldier->ubProfile, pKillerSoldier->ubProfile ); - if ( bTempBuddyIndex != -1 ) - { - switch( bTempBuddyIndex ) - { - case 0: - if ( pTeamSoldier->usQuoteSaidExtFlags & SOLDIER_QUOTE_SAID_BUDDY_1_WITNESSED ) - { - continue; - } - break; + if ( bTempBuddyIndex != -1 ) + { + switch( bTempBuddyIndex ) + { + case 0: + if ( pTeamSoldier->usQuoteSaidExtFlags & SOLDIER_QUOTE_SAID_BUDDY_1_WITNESSED ) + { + continue; + } + break; - case 1: - if ( pTeamSoldier->usQuoteSaidExtFlags & SOLDIER_QUOTE_SAID_BUDDY_2_WITNESSED ) - { - continue; - } - break; + case 1: + if ( pTeamSoldier->usQuoteSaidExtFlags & SOLDIER_QUOTE_SAID_BUDDY_2_WITNESSED ) + { + continue; + } + break; - case 2: - if ( pTeamSoldier->usQuoteSaidExtFlags & SOLDIER_QUOTE_SAID_BUDDY_3_WITNESSED ) - { - continue; - } - break; - } + case 2: + if ( pTeamSoldier->usQuoteSaidExtFlags & SOLDIER_QUOTE_SAID_BUDDY_3_WITNESSED ) + { + continue; + } + break; + } - // TO LOS check to killed - // Can we see location of killer? - sDistVisible = DistanceVisible( pTeamSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, pKillerSoldier->sGridNo, pKillerSoldier->bLevel, pKillerSoldier ); - if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, pKillerSoldier->sGridNo, pKillerSoldier->bLevel, (UINT8)3, (UINT8) sDistVisible, TRUE ) == 0 ) - { - continue; - } + // TO LOS check to killed + // Can we see location of killer? + sDistVisible = DistanceVisible( pTeamSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, pKillerSoldier->sGridNo, pKillerSoldier->bLevel, pKillerSoldier ); + if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, pKillerSoldier->sGridNo, pKillerSoldier->bLevel, (UINT8)3, (UINT8) sDistVisible, TRUE ) == 0 ) + { + continue; + } - // Can we see location of killed? - sDistVisible = DistanceVisible( pTeamSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sGridNo, bLevel, pTeamSoldier ); - if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, bLevel, (UINT8)3, (UINT8) sDistVisible, TRUE ) == 0 ) - { - continue; - } + // Can we see location of killed? + sDistVisible = DistanceVisible( pTeamSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sGridNo, bLevel, pTeamSoldier ); + if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, bLevel, (UINT8)3, (UINT8) sDistVisible, TRUE ) == 0 ) + { + continue; + } - // OK, a good candidate... - ubMercsInSector[ ubNumMercs ] = (UINT8)cnt; - bBuddyIndex[ ubNumMercs ] = bTempBuddyIndex; - ubNumMercs++; - } + // OK, a good candidate... + ubMercsInSector[ ubNumMercs ] = (UINT8)cnt; + bBuddyIndex[ ubNumMercs ] = bTempBuddyIndex; + ubNumMercs++; + } } } // If we are > 0 if ( ubNumMercs > 0 ) { - // Do random check here... - if ( Random( 100 ) < 20 ) - { - ubChosenMerc = (UINT8)Random( ubNumMercs ); + // Do random check here... + if ( Random( 100 ) < 20 ) + { + ubChosenMerc = (UINT8)Random( ubNumMercs ); - switch( bBuddyIndex[ ubChosenMerc ] ) - { - case 0: - usQuoteNum = QUOTE_BUDDY_1_GOOD; - MercPtrs[ ubMercsInSector[ ubChosenMerc ] ]->usQuoteSaidExtFlags |= SOLDIER_QUOTE_SAID_BUDDY_1_WITNESSED; - break; + switch( bBuddyIndex[ ubChosenMerc ] ) + { + case 0: + usQuoteNum = QUOTE_BUDDY_1_GOOD; + MercPtrs[ ubMercsInSector[ ubChosenMerc ] ]->usQuoteSaidExtFlags |= SOLDIER_QUOTE_SAID_BUDDY_1_WITNESSED; + break; - case 1: - usQuoteNum = QUOTE_BUDDY_2_GOOD; - MercPtrs[ ubMercsInSector[ ubChosenMerc ] ]->usQuoteSaidExtFlags |= SOLDIER_QUOTE_SAID_BUDDY_2_WITNESSED; - break; + case 1: + usQuoteNum = QUOTE_BUDDY_2_GOOD; + MercPtrs[ ubMercsInSector[ ubChosenMerc ] ]->usQuoteSaidExtFlags |= SOLDIER_QUOTE_SAID_BUDDY_2_WITNESSED; + break; - case 2: - usQuoteNum = QUOTE_LEARNED_TO_LIKE_WITNESSED; - MercPtrs[ ubMercsInSector[ ubChosenMerc ] ]->usQuoteSaidExtFlags |= SOLDIER_QUOTE_SAID_BUDDY_3_WITNESSED; - break; - } - TacticalCharacterDialogue( MercPtrs[ ubMercsInSector[ ubChosenMerc ] ], usQuoteNum ); - } + case 2: + usQuoteNum = QUOTE_LEARNED_TO_LIKE_WITNESSED; + MercPtrs[ ubMercsInSector[ ubChosenMerc ] ]->usQuoteSaidExtFlags |= SOLDIER_QUOTE_SAID_BUDDY_3_WITNESSED; + break; + } + TacticalCharacterDialogue( MercPtrs[ ubMercsInSector[ ubChosenMerc ] ], usQuoteNum ); + } } } @@ -3024,7 +3055,7 @@ void HandleKilledQuote( SOLDIERTYPE *pKilledSoldier, SOLDIERTYPE *pKillerSoldier //Randomliy say it! if ( Random( 100 ) < 40 ) { - TacticalCharacterDialogue( pKillerSoldier, QUOTE_HEADSHOT ); + TacticalCharacterDialogue( pKillerSoldier, QUOTE_HEADSHOT ); } else { @@ -3059,7 +3090,7 @@ void HandleKilledQuote( SOLDIERTYPE *pKilledSoldier, SOLDIERTYPE *pKillerSoldier if ( ubNumMercs > 0 ) { ubChosenMerc = (UINT8)Random( ubNumMercs ); - + // We have a random chance of not saying our we killed a guy quote if ( Random( 100 ) < 50 ) { @@ -3099,23 +3130,23 @@ void HandleKilledQuote( SOLDIERTYPE *pKilledSoldier, SOLDIERTYPE *pKillerSoldier // Are we happy with our gun? if ( ShouldMercSayHappyWithGunQuote( pKillerSoldier ) ) { - TacticalCharacterDialogue( pKillerSoldier, QUOTE_SATISFACTION_WITH_GUN_AFTER_KILL ); - pKillerSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_LIKESGUN; + TacticalCharacterDialogue( pKillerSoldier, QUOTE_SATISFACTION_WITH_GUN_AFTER_KILL ); + pKillerSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_LIKESGUN; } else - // Randomize between laugh, quote... + // Randomize between laugh, quote... { if ( Random( 100 ) < 33 && pKilledSoldier->ubBodyType != BLOODCAT ) { - // If it's a creature...... - if ( pKilledSoldier->uiStatusFlags & SOLDIER_MONSTER ) - { - TacticalCharacterDialogue( pKillerSoldier, QUOTE_KILLED_A_CREATURE ); - } - else - { - TacticalCharacterDialogue( pKillerSoldier, QUOTE_KILLED_AN_ENEMY ); - } + // If it's a creature...... + if ( pKilledSoldier->uiStatusFlags & SOLDIER_MONSTER ) + { + TacticalCharacterDialogue( pKillerSoldier, QUOTE_KILLED_A_CREATURE ); + } + else + { + TacticalCharacterDialogue( pKillerSoldier, QUOTE_KILLED_AN_ENEMY ); + } } else { @@ -3130,9 +3161,9 @@ void HandleKilledQuote( SOLDIERTYPE *pKilledSoldier, SOLDIERTYPE *pKillerSoldier } } - // Buddy witnessed? - SayBuddyWitnessedQuoteFromKill( pKillerSoldier, sGridNo, bLevel ); - + // Buddy witnessed? + SayBuddyWitnessedQuoteFromKill( pKillerSoldier, sGridNo, bLevel ); + } } } @@ -3156,7 +3187,7 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse ) if ( pSoldier->iMuzFlash != -1 ) { LightSpriteDestroy( pSoldier->iMuzFlash ); - pSoldier->iMuzFlash = -1; + pSoldier->iMuzFlash = -1; } if ( pSoldier->iLight != -1 ) { @@ -3265,15 +3296,15 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse ) // if killer is assister, don't increment if ( pSoldier->ubPreviousAttackerID != NOBODY && pSoldier->ubPreviousAttackerID != pSoldier->ubAttackerID ) { - if ( MercPtrs[ pSoldier->ubPreviousAttackerID ]->bTeam == gbPlayerNum ) - { - gMercProfiles[ MercPtrs[ pSoldier->ubPreviousAttackerID ]->ubProfile ].usAssists++; - } - else if ( MercPtrs[ pSoldier->ubPreviousAttackerID ]->bTeam == MILITIA_TEAM ) - { - // get an assist - 1 points - MercPtrs[ pSoldier->ubPreviousAttackerID ]->ubMilitiaKills += 1; - } + if ( MercPtrs[ pSoldier->ubPreviousAttackerID ]->bTeam == gbPlayerNum ) + { + gMercProfiles[ MercPtrs[ pSoldier->ubPreviousAttackerID ]->ubProfile ].usAssists++; + } + else if ( MercPtrs[ pSoldier->ubPreviousAttackerID ]->bTeam == MILITIA_TEAM ) + { + // get an assist - 1 points + MercPtrs[ pSoldier->ubPreviousAttackerID ]->ubMilitiaKills += 1; + } } */ } @@ -3289,15 +3320,16 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse ) // Re-evaluate visiblitiy for the team! BetweenTurnsVisibilityAdjustments(); - if ( pSoldier->bTeam != gbPlayerNum ) - { - if ( !pSoldier->fDoingExternalDeath ) - { - // Release attacker - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, code 497 = handle soldier death") ); - ReleaseSoldiersAttacker( pSoldier ); - } - } + // 0verhaul: This is now handled in the death state transitions + // if ( pSoldier->bTeam != gbPlayerNum ) + // { + // if ( !pSoldier->fDoingExternalDeath ) + // { + // // Release attacker + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, code 497 = handle soldier death") ); + // ReleaseSoldiersAttacker( pSoldier ); + // } + // } if ( !( *pfMadeCorpse ) ) { @@ -3320,12 +3352,13 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse ) void HandlePlayerTeamMemberDeathAfterSkullAnimation( SOLDIERTYPE *pSoldier ) { + // 0verhaul: This is now handled in the death state transition. // Release attacker - if ( !pSoldier->fDoingExternalDeath ) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, code 497 = handle soldier death") ); - ReleaseSoldiersAttacker( pSoldier ); - } + // if ( !pSoldier->fDoingExternalDeath ) + // { + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, code 497 = handle soldier death") ); + // ReleaseSoldiersAttacker( pSoldier ); + // } HandlePlayerTeamMemberDeath( pSoldier ); @@ -3341,54 +3374,54 @@ BOOLEAN CheckForAndHandleSoldierDeath( SOLDIERTYPE *pSoldier, BOOLEAN *pfMadeCor // Select approriate death switch( pSoldier->usAnimState ) { - case FLYBACK_HIT_DEATH: - ChangeSoldierState( pSoldier, FLYBACK_HITDEATH_STOP, 0, FALSE ); - break; + case FLYBACK_HIT_DEATH: + ChangeSoldierState( pSoldier, FLYBACK_HITDEATH_STOP, 0, FALSE ); + break; - case GENERIC_HIT_DEATH: - ChangeSoldierState( pSoldier, FALLFORWARD_HITDEATH_STOP, 0, FALSE ); - break; + case GENERIC_HIT_DEATH: + ChangeSoldierState( pSoldier, FALLFORWARD_HITDEATH_STOP, 0, FALSE ); + break; - case FALLBACK_HIT_DEATH: - ChangeSoldierState( pSoldier, FALLBACK_HITDEATH_STOP, 0, FALSE ); - break; + case FALLBACK_HIT_DEATH: + ChangeSoldierState( pSoldier, FALLBACK_HITDEATH_STOP, 0, FALSE ); + break; - case PRONE_HIT_DEATH: - ChangeSoldierState( pSoldier, PRONE_HITDEATH_STOP, 0, FALSE ); - break; + case PRONE_HIT_DEATH: + ChangeSoldierState( pSoldier, PRONE_HITDEATH_STOP, 0, FALSE ); + break; - case JFK_HITDEATH: - ChangeSoldierState( pSoldier, JFK_HITDEATH_STOP, 0, FALSE ); - break; + case JFK_HITDEATH: + ChangeSoldierState( pSoldier, JFK_HITDEATH_STOP, 0, FALSE ); + break; - case FALLOFF_DEATH: - ChangeSoldierState( pSoldier, FALLOFF_DEATH_STOP, 0, FALSE ); - break; + case FALLOFF_DEATH: + ChangeSoldierState( pSoldier, FALLOFF_DEATH_STOP, 0, FALSE ); + break; - case FALLOFF_FORWARD_DEATH: - ChangeSoldierState( pSoldier, FALLOFF_FORWARD_DEATH_STOP, 0, FALSE ); - break; + case FALLOFF_FORWARD_DEATH: + ChangeSoldierState( pSoldier, FALLOFF_FORWARD_DEATH_STOP, 0, FALSE ); + break; - case WATER_DIE: - ChangeSoldierState( pSoldier, WATER_DIE_STOP, 0, FALSE ); - break; + case WATER_DIE: + ChangeSoldierState( pSoldier, WATER_DIE_STOP, 0, FALSE ); + break; - case DEEP_WATER_DIE: - ChangeSoldierState( pSoldier, DEEP_WATER_DIE_STOPPING, 0, FALSE ); - break; + case DEEP_WATER_DIE: + ChangeSoldierState( pSoldier, DEEP_WATER_DIE_STOPPING, 0, FALSE ); + break; - case COW_DYING: - ChangeSoldierState( pSoldier, COW_DYING_STOP, 0, FALSE); - break; + case COW_DYING: + ChangeSoldierState( pSoldier, COW_DYING_STOP, 0, FALSE); + break; - case BLOODCAT_DYING: - ChangeSoldierState( pSoldier, BLOODCAT_DYING_STOP, 0, FALSE); - break; + case BLOODCAT_DYING: + ChangeSoldierState( pSoldier, BLOODCAT_DYING_STOP, 0, FALSE); + break; - default: + default: - // IF we are here - something is wrong - we should have an animation stop here - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Soldier Ani: CODE 440 Error, Death STOP not handled" ); + // IF we are here - something is wrong - we should have an animation stop here + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Soldier Ani: CODE 440 Error, Death STOP not handled" ); } return( TRUE ); @@ -3415,27 +3448,27 @@ void CheckForAndHandleSoldierIncompacitated( SOLDIERTYPE *pSoldier ) // If we are a monster, set life to zero ( no unconscious ) switch( pSoldier->ubBodyType ) { - case ADULTFEMALEMONSTER: - case AM_MONSTER: - case YAF_MONSTER: - case YAM_MONSTER: - case LARVAE_MONSTER: - case INFANT_MONSTER: - case CRIPPLECIV: - case ROBOTNOWEAPON: - case QUEENMONSTER: - case TANK_NW: - case TANK_NE: + case ADULTFEMALEMONSTER: + case AM_MONSTER: + case YAF_MONSTER: + case YAM_MONSTER: + case LARVAE_MONSTER: + case INFANT_MONSTER: + case CRIPPLECIV: + case ROBOTNOWEAPON: + case QUEENMONSTER: + case TANK_NW: + case TANK_NE: - pSoldier->bLife = 0; - break; + pSoldier->bLife = 0; + break; } // OK, if we are in a meanwhile and this is elliot... if ( AreInMeanwhile( ) ) { SOLDIERTYPE *pQueen; - + pQueen = FindSoldierByProfileID( QUEEN, FALSE ); if ( pQueen ) @@ -3456,7 +3489,7 @@ void CheckForAndHandleSoldierIncompacitated( SOLDIERTYPE *pSoldier ) if ( !AreInMeanwhile() ) { DoMercBattleSound( pSoldier, BATTLE_SOUND_DIE1 ); - pSoldier->fDeadSoundPlayed = TRUE; + pSoldier->fDeadSoundPlayed = TRUE; } } @@ -3528,7 +3561,7 @@ void CheckForAndHandleSoldierIncompacitated( SOLDIERTYPE *pSoldier ) else if ( pSoldier->usAnimState == GENERIC_HIT_CROUCH ) { ChangeSoldierState( pSoldier, FALLFORWARD_FROMHIT_CROUCH, 0 , FALSE); - BeginTyingToFall( pSoldier ); + BeginTyingToFall( pSoldier ); return; } else if ( pSoldier->usAnimState == GENERIC_HIT_PRONE ) @@ -3603,80 +3636,81 @@ BOOLEAN CheckForAndHandleSoldierDyingNotFromHit( SOLDIERTYPE *pSoldier ) DoMercBattleSound( pSoldier, BATTLE_SOUND_DIE1 ); pSoldier->fDeadSoundPlayed = TRUE; - // Increment being attacked count - pSoldier->bBeingAttackedCount++; + // 0verhaul: The bBeingAttackedCount is now obsolete. + // Increment being attacked count + // pSoldier->bBeingAttackedCount++; if ( gGameSettings.fOptions[ TOPTION_BLOOD_N_GORE ] ) { switch( pSoldier->usAnimState ) { - case FLYBACKHIT_STOP: - ChangeSoldierState( pSoldier, FLYBACK_HIT_DEATH, 0, FALSE ); - break; + case FLYBACKHIT_STOP: + ChangeSoldierState( pSoldier, FLYBACK_HIT_DEATH, 0, FALSE ); + break; - case FALLFORWARD_FROMHIT_STAND: - case FALLFORWARD_FROMHIT_CROUCH: - case STAND_FALLFORWARD_STOP: - ChangeSoldierState( pSoldier, GENERIC_HIT_DEATH, 0, FALSE ); - break; + case FALLFORWARD_FROMHIT_STAND: + case FALLFORWARD_FROMHIT_CROUCH: + case STAND_FALLFORWARD_STOP: + ChangeSoldierState( pSoldier, GENERIC_HIT_DEATH, 0, FALSE ); + break; - case FALLBACKHIT_STOP: - ChangeSoldierState( pSoldier, FALLBACK_HIT_DEATH, 0, FALSE ); - break; + case FALLBACKHIT_STOP: + ChangeSoldierState( pSoldier, FALLBACK_HIT_DEATH, 0, FALSE ); + break; - case PRONE_LAYFROMHIT_STOP: - case PRONE_LAY_FROMHIT: + case PRONE_LAYFROMHIT_STOP: + case PRONE_LAY_FROMHIT: - ChangeSoldierState( pSoldier, PRONE_HIT_DEATH, 0, FALSE ); - break; + ChangeSoldierState( pSoldier, PRONE_HIT_DEATH, 0, FALSE ); + break; - case FALLOFF_STOP: - ChangeSoldierState( pSoldier, FALLOFF_DEATH, 0, FALSE ); - break; + case FALLOFF_STOP: + ChangeSoldierState( pSoldier, FALLOFF_DEATH, 0, FALSE ); + break; - case FALLOFF_FORWARD_STOP: - ChangeSoldierState( pSoldier, FALLOFF_FORWARD_DEATH, 0, FALSE); - break; + case FALLOFF_FORWARD_STOP: + ChangeSoldierState( pSoldier, FALLOFF_FORWARD_DEATH, 0, FALSE); + break; - case ADULTMONSTER_HIT: - ChangeSoldierState( pSoldier, ADULTMONSTER_DYING, 0 , FALSE ); - break; + case ADULTMONSTER_HIT: + ChangeSoldierState( pSoldier, ADULTMONSTER_DYING, 0 , FALSE ); + break; - case LARVAE_HIT: - ChangeSoldierState( pSoldier, LARVAE_DIE, 0 , FALSE ); - break; - - case QUEEN_HIT: - ChangeSoldierState( pSoldier, QUEEN_DIE, 0 , FALSE ); - break; + case LARVAE_HIT: + ChangeSoldierState( pSoldier, LARVAE_DIE, 0 , FALSE ); + break; - case CRIPPLE_HIT: - ChangeSoldierState( pSoldier, CRIPPLE_DIE, 0 , FALSE ); - break; + case QUEEN_HIT: + ChangeSoldierState( pSoldier, QUEEN_DIE, 0 , FALSE ); + break; - case ROBOTNW_HIT: - ChangeSoldierState( pSoldier, ROBOTNW_DIE, 0 , FALSE ); - break; + case CRIPPLE_HIT: + ChangeSoldierState( pSoldier, CRIPPLE_DIE, 0 , FALSE ); + break; - case INFANT_HIT: - ChangeSoldierState( pSoldier, INFANT_DIE, 0 , FALSE ); - break; + case ROBOTNW_HIT: + ChangeSoldierState( pSoldier, ROBOTNW_DIE, 0 , FALSE ); + break; - case COW_HIT: - ChangeSoldierState( pSoldier, COW_DYING, 0 , FALSE ); - break; + case INFANT_HIT: + ChangeSoldierState( pSoldier, INFANT_DIE, 0 , FALSE ); + break; - case BLOODCAT_HIT: - ChangeSoldierState( pSoldier, BLOODCAT_DYING, 0 , FALSE ); - break; - - default: - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Soldier Control: Death state %d has no death hit", pSoldier->usAnimState ) ); - { - BOOLEAN fMadeCorpse; - CheckForAndHandleSoldierDeath( pSoldier, &fMadeCorpse ); - } - break; + case COW_HIT: + ChangeSoldierState( pSoldier, COW_DYING, 0 , FALSE ); + break; + + case BLOODCAT_HIT: + ChangeSoldierState( pSoldier, BLOODCAT_DYING, 0 , FALSE ); + break; + + default: + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Soldier Control: Death state %d has no death hit", pSoldier->usAnimState ) ); + { + BOOLEAN fMadeCorpse; + CheckForAndHandleSoldierDeath( pSoldier, &fMadeCorpse ); + } + break; } } @@ -3744,51 +3778,51 @@ BOOLEAN HandleUnjamAnimation( SOLDIERTYPE *pSoldier ) // Check what animatnion we should do..... switch( pSoldier->usAnimState ) { - case SHOOT_RIFLE_STAND: - case STANDING_BURST: - case FIRE_STAND_BURST_SPREAD: - // Normal shoot rifle.... play - ChangeSoldierState( pSoldier, STANDING_SHOOT_UNJAM, 0 , FALSE ); - return( TRUE ); + case SHOOT_RIFLE_STAND: + case STANDING_BURST: + case FIRE_STAND_BURST_SPREAD: + // Normal shoot rifle.... play + ChangeSoldierState( pSoldier, STANDING_SHOOT_UNJAM, 0 , FALSE ); + return( TRUE ); - case PRONE_BURST: - case SHOOT_RIFLE_PRONE: + case PRONE_BURST: + case SHOOT_RIFLE_PRONE: - // Normal shoot rifle.... play - ChangeSoldierState( pSoldier, PRONE_SHOOT_UNJAM, 0 , FALSE ); - return( TRUE ); + // Normal shoot rifle.... play + ChangeSoldierState( pSoldier, PRONE_SHOOT_UNJAM, 0 , FALSE ); + return( TRUE ); - case CROUCHED_BURST: - case SHOOT_RIFLE_CROUCH: + case CROUCHED_BURST: + case SHOOT_RIFLE_CROUCH: - // Normal shoot rifle.... play - ChangeSoldierState( pSoldier, CROUCH_SHOOT_UNJAM, 0 , FALSE ); - return( TRUE ); + // Normal shoot rifle.... play + ChangeSoldierState( pSoldier, CROUCH_SHOOT_UNJAM, 0 , FALSE ); + return( TRUE ); - case SHOOT_DUAL_STAND: + case SHOOT_DUAL_STAND: - // Normal shoot rifle.... play - ChangeSoldierState( pSoldier, STANDING_SHOOT_DWEL_UNJAM, 0 , FALSE ); - return( TRUE ); + // Normal shoot rifle.... play + ChangeSoldierState( pSoldier, STANDING_SHOOT_DWEL_UNJAM, 0 , FALSE ); + return( TRUE ); - case SHOOT_DUAL_PRONE: + case SHOOT_DUAL_PRONE: - // Normal shoot rifle.... play - ChangeSoldierState( pSoldier, PRONE_SHOOT_DWEL_UNJAM, 0 , FALSE ); - return( TRUE ); + // Normal shoot rifle.... play + ChangeSoldierState( pSoldier, PRONE_SHOOT_DWEL_UNJAM, 0 , FALSE ); + return( TRUE ); - case SHOOT_DUAL_CROUCH: + case SHOOT_DUAL_CROUCH: - // Normal shoot rifle.... play - ChangeSoldierState( pSoldier, CROUCH_SHOOT_DWEL_UNJAM, 0 , FALSE ); - return( TRUE ); + // Normal shoot rifle.... play + ChangeSoldierState( pSoldier, CROUCH_SHOOT_DWEL_UNJAM, 0 , FALSE ); + return( TRUE ); - case FIRE_LOW_STAND: - case FIRE_BURST_LOW_STAND: + case FIRE_LOW_STAND: + case FIRE_BURST_LOW_STAND: - // Normal shoot rifle.... play - ChangeSoldierState( pSoldier, STANDING_SHOOT_LOW_UNJAM, 0 , FALSE ); - return( TRUE ); + // Normal shoot rifle.... play + ChangeSoldierState( pSoldier, STANDING_SHOOT_LOW_UNJAM, 0 , FALSE ); + return( TRUE ); } @@ -3799,45 +3833,45 @@ BOOLEAN HandleUnjamAnimation( SOLDIERTYPE *pSoldier ) #if 0 - //OK, if here, if our health is still good, but we took a lot of damage, try to fall down! - if ( pSoldier->bLife >= OKLIFE ) - { - // Randomly fall back or forward, if we are in the standing hit animation - if ( pSoldier->usAnimState == GENERIC_HIT_STAND || pSoldier->usAnimState == RIFLE_STAND_HIT ) - { - INT8 bTestDirection = pSoldier->bDirection; - BOOLEAN fForceDirection = FALSE; - BOOLEAN fDoFallback = FALSE; +//OK, if here, if our health is still good, but we took a lot of damage, try to fall down! +if ( pSoldier->bLife >= OKLIFE ) +{ + // Randomly fall back or forward, if we are in the standing hit animation + if ( pSoldier->usAnimState == GENERIC_HIT_STAND || pSoldier->usAnimState == RIFLE_STAND_HIT ) + { + INT8 bTestDirection = pSoldier->bDirection; + BOOLEAN fForceDirection = FALSE; + BOOLEAN fDoFallback = FALSE; - // As the damage pretty brutal? + // As the damage pretty brutal? - // TRY FALLING BACKWARDS, ( ONLY IF WE ARE A MERC! ) - if ( Random( 1000 ) > 40 && IS_MERC_BODY_TYPE( pSoldier ) ) - { - // CHECK IF WE HAVE AN ATTACKER, TAKE OPPOSITE DIRECTION! - if ( pSoldier->ubAttackerID != NOBODY ) - { - // Find direction! - bTestDirection = (INT8)GetDirectionFromGridNo( MercPtrs[ pSoldier->ubAttackerID ]->sGridNo, pSoldier ); - fForceDirection = TRUE; - } + // TRY FALLING BACKWARDS, ( ONLY IF WE ARE A MERC! ) + if ( Random( 1000 ) > 40 && IS_MERC_BODY_TYPE( pSoldier ) ) + { + // CHECK IF WE HAVE AN ATTACKER, TAKE OPPOSITE DIRECTION! + if ( pSoldier->ubAttackerID != NOBODY ) + { + // Find direction! + bTestDirection = (INT8)GetDirectionFromGridNo( MercPtrs[ pSoldier->ubAttackerID ]->sGridNo, pSoldier ); + fForceDirection = TRUE; + } - sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)(-1 * DirectionInc( bTestDirection ) ) ); + sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)(-1 * DirectionInc( bTestDirection ) ) ); - if ( NewOKDestination( pSoldier, sNewGridNo, TRUE, pSoldier->bLevel ) && OKHeightDest( pSoldier, sNewGridNo ) ) - { - // ALL'S OK HERE..... IF WE FORCED DIRECTION, SET! - if ( fForceDirection ) - { - EVENT_SetSoldierDirection( pSoldier, bTestDirection ); - EVENT_SetSoldierDesiredDirection( pSoldier, bTestDirection ); - } - ChangeSoldierState( pSoldier, FALLBACK_HIT_STAND, 0, FALSE ); - return; - } - } - } - } + if ( NewOKDestination( pSoldier, sNewGridNo, TRUE, pSoldier->bLevel ) && OKHeightDest( pSoldier, sNewGridNo ) ) + { + // ALL'S OK HERE..... IF WE FORCED DIRECTION, SET! + if ( fForceDirection ) + { + EVENT_SetSoldierDirection( pSoldier, bTestDirection ); + EVENT_SetSoldierDesiredDirection( pSoldier, bTestDirection ); + } + ChangeSoldierState( pSoldier, FALLBACK_HIT_STAND, 0, FALSE ); + return; + } + } + } +} #endif @@ -3853,11 +3887,11 @@ BOOLEAN OKFallDirection( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bLevel, INT8 return( FALSE ); } - //NOT ok if in water.... + //NOT ok if in water.... if ( GetTerrainType( sGridNo ) == MED_WATER || GetTerrainType( sGridNo ) == DEEP_WATER || GetTerrainType( sGridNo ) == LOW_WATER ) - { - return( FALSE ); - } + { + return( FALSE ); + } // How are we for OK dest? if (!NewOKDestination( pSoldier, sGridNo, TRUE, bLevel ) ) @@ -3914,7 +3948,7 @@ BOOLEAN HandleCheckForDeathCommonCode( SOLDIERTYPE *pSoldier ) // OTHERWISE, GOTO APPROPRIATE STOPANIMATION! pSoldier->bCollapsed = TRUE; - // CC has requested - handle sight here... + // CC has requested - handle sight here... HandleSight( pSoldier, SIGHT_LOOK ); // ATE: If it is our turn, make them try to getup... @@ -3932,39 +3966,39 @@ BOOLEAN HandleCheckForDeathCommonCode( SOLDIERTYPE *pSoldier ) switch( pSoldier->usAnimState ) { - case FLYBACK_HIT: - ChangeSoldierState( pSoldier, FLYBACKHIT_STOP, 0, FALSE ); - break; + case FLYBACK_HIT: + ChangeSoldierState( pSoldier, FLYBACKHIT_STOP, 0, FALSE ); + break; - case GENERIC_HIT_DEATHTWITCHNB: - case FALLFORWARD_FROMHIT_STAND: - case ENDFALLFORWARD_FROMHIT_CROUCH: + case GENERIC_HIT_DEATHTWITCHNB: + case FALLFORWARD_FROMHIT_STAND: + case ENDFALLFORWARD_FROMHIT_CROUCH: - ChangeSoldierState( pSoldier, STAND_FALLFORWARD_STOP, 0, FALSE ); - break; + ChangeSoldierState( pSoldier, STAND_FALLFORWARD_STOP, 0, FALSE ); + break; - case FALLBACK_HIT_DEATHTWITCHNB: - case FALLBACK_HIT_STAND: - ChangeSoldierState( pSoldier, FALLBACKHIT_STOP, 0, FALSE ); - break; + case FALLBACK_HIT_DEATHTWITCHNB: + case FALLBACK_HIT_STAND: + ChangeSoldierState( pSoldier, FALLBACKHIT_STOP, 0, FALSE ); + break; - case PRONE_HIT_DEATHTWITCHNB: - case PRONE_LAY_FROMHIT: + case PRONE_HIT_DEATHTWITCHNB: + case PRONE_LAY_FROMHIT: - ChangeSoldierState( pSoldier, PRONE_LAYFROMHIT_STOP, 0, FALSE ); - break; + ChangeSoldierState( pSoldier, PRONE_LAYFROMHIT_STOP, 0, FALSE ); + break; - case FALLOFF: - ChangeSoldierState( pSoldier, FALLOFF_STOP, 0, FALSE ); - break; + case FALLOFF: + ChangeSoldierState( pSoldier, FALLOFF_STOP, 0, FALSE ); + break; - case FALLFORWARD_ROOF: - ChangeSoldierState( pSoldier, FALLOFF_FORWARD_STOP, 0, FALSE); - break; + case FALLFORWARD_ROOF: + ChangeSoldierState( pSoldier, FALLOFF_FORWARD_STOP, 0, FALSE); + break; - default: - // IF we are here - something is wrong - we should have a death animation here - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Soldier Ani: unconscious hit sequence needed for animation %d", pSoldier->usAnimState ) ); + default: + // IF we are here - something is wrong - we should have a death animation here + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Soldier Ani: unconscious hit sequence needed for animation %d", pSoldier->usAnimState ) ); } // OTHERWISE, GOTO APPROPRIATE STOPANIMATION! @@ -3985,39 +4019,39 @@ BOOLEAN HandleCheckForDeathCommonCode( SOLDIERTYPE *pSoldier ) switch( pSoldier->usAnimState ) { - case FLYBACK_HIT: - ChangeSoldierState( pSoldier, FLYBACKHIT_STOP, 0, FALSE ); - break; + case FLYBACK_HIT: + ChangeSoldierState( pSoldier, FLYBACKHIT_STOP, 0, FALSE ); + break; - case GENERIC_HIT_DEATHTWITCHNB: - case FALLFORWARD_FROMHIT_STAND: - case ENDFALLFORWARD_FROMHIT_CROUCH: + case GENERIC_HIT_DEATHTWITCHNB: + case FALLFORWARD_FROMHIT_STAND: + case ENDFALLFORWARD_FROMHIT_CROUCH: - ChangeSoldierState( pSoldier, STAND_FALLFORWARD_STOP, 0, FALSE ); - break; + ChangeSoldierState( pSoldier, STAND_FALLFORWARD_STOP, 0, FALSE ); + break; - case FALLBACK_HIT_DEATHTWITCHNB: - case FALLBACK_HIT_STAND: - ChangeSoldierState( pSoldier, FALLBACKHIT_STOP, 0, FALSE ); - break; + case FALLBACK_HIT_DEATHTWITCHNB: + case FALLBACK_HIT_STAND: + ChangeSoldierState( pSoldier, FALLBACKHIT_STOP, 0, FALSE ); + break; - case PRONE_HIT_DEATHTWITCHNB: - case PRONE_LAY_FROMHIT: + case PRONE_HIT_DEATHTWITCHNB: + case PRONE_LAY_FROMHIT: - ChangeSoldierState( pSoldier, PRONE_LAYFROMHIT_STOP, 0, FALSE ); - break; + ChangeSoldierState( pSoldier, PRONE_LAYFROMHIT_STOP, 0, FALSE ); + break; - case FALLOFF: - ChangeSoldierState( pSoldier, FALLOFF_STOP, 0, FALSE ); - break; + case FALLOFF: + ChangeSoldierState( pSoldier, FALLOFF_STOP, 0, FALSE ); + break; - case FALLFORWARD_ROOF: - ChangeSoldierState( pSoldier, FALLOFF_FORWARD_STOP, 0, FALSE); - break; + case FALLFORWARD_ROOF: + ChangeSoldierState( pSoldier, FALLOFF_FORWARD_STOP, 0, FALSE); + break; - default: - // IF we are here - something is wrong - we should have a death animation here - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Soldier Ani: unconscious hit sequence needed for animation %d", pSoldier->usAnimState ) ); + default: + // IF we are here - something is wrong - we should have a death animation here + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Soldier Ani: unconscious hit sequence needed for animation %d", pSoldier->usAnimState ) ); } diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 328c8318..bf52190b 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -1,88 +1,99 @@ #ifdef PRECOMPILEDHEADERS - #include "Tactical All.h" +#include "Tactical All.h" #else - #include - #include - #include - #include "wcheck.h" - #include "Render Fun.h" - #include "stdlib.h" - #include "debug.h" - #include "MemMan.h" - #include "Overhead Types.h" - #include "Soldier Control.h" - #include "Animation Cache.h" - #include "Animation Data.h" - #include "Animation Control.h" - #include "container.h" - #include - #include "pathai.h" - #include "Random.h" - #include "worldman.h" - #include "Isometric Utils.h" - #include "Render Dirty.h" - #include "renderworld.h" - #include "sys globals.h" - #include "video.h" - #include "points.h" - #include "Win util.h" - #include "Sound Control.h" - #include "weapons.h" - #include "vobject_blitters.h" - #include "Handle UI.h" - #include "soldier ani.h" - #include "Event pump.h" - #include "opplist.h" - #include "ai.h" - #include "interface.h" - #include "lighting.h" - #include "faces.h" - #include "Soldier Profile.h" - #include "gap.h" - #include "interface panels.h" - #include "campaign.h" - #include "soldier macros.h" - #include "english.h" - #include "Squads.h" +#include "builddefines.h" +#include +#include +#include +#include "wcheck.h" +#include "Render Fun.h" +#include "stdlib.h" +#include "debug.h" +#include "MemMan.h" +#include "Overhead Types.h" +#include "Soldier Control.h" +#include "Animation Cache.h" +#include "Animation Data.h" +#include "Animation Control.h" +#include "container.h" +#include +#include "pathai.h" +#include "Random.h" +#include "worldman.h" +#include "Isometric Utils.h" +#include "Render Dirty.h" +#include "renderworld.h" +#include "sys globals.h" +#include "video.h" +#include "points.h" +#include "Win util.h" +#include "Sound Control.h" +#include "weapons.h" +#include "vobject_blitters.h" +#include "Handle UI.h" +#include "soldier ani.h" +#include "Event pump.h" +#include "opplist.h" +#include "ai.h" +#include "interface.h" +#include "lighting.h" +#include "faces.h" +#include "Soldier Profile.h" +#include "gap.h" +#include "interface panels.h" +#include "campaign.h" +#include "soldier macros.h" +#include "english.h" +#include "Squads.h" - #ifdef NETWORKED - #include "Networking.h" - #include "NetworkEvent.h" - #endif - #include "structure wrap.h" - #include "items.h" - #include "Soundman.h" - #include "utilities.h" - #include "Strategic.h" - #include "soldier tile.h" - #include "Smell.h" - #include "Keys.h" - #include "dialogue control.h" - #include "soldier functions.h" - #include "rt time defines.h" - #include "Exit Grids.h" - #include "gamescreen.h" - #include "Quests.h" - #include "message.h" - #include "NPC.h" - #include "SkillCheck.h" - #include "handle doors.h" - #include "interface dialogue.h" - #include "smokeeffects.h" - #include "GameSettings.h" - #include "tile animation.h" - #include "ShopKeeper Interface.h" - #include "Arms Dealer Init.h" - #include "vehicles.h" - #include "rotting corpses.h" - #include "Interface Control.h" - #include "strategicmap.h" - #include "morale.h" - #include "meanwhile.h" - #include "drugs and alcohol.h" - #include "SkillCheck.h" - #include "boxing.h" - #include "overhead map.h" +#ifdef NETWORKED +#include "Networking.h" +#include "NetworkEvent.h" +#endif +#include "structure wrap.h" +#include "items.h" +#include "Soundman.h" +#include "utilities.h" +#include "Strategic.h" +#include "soldier tile.h" +#include "Smell.h" +#include "Keys.h" +#include "dialogue control.h" +#include "soldier functions.h" +#include "rt time defines.h" +#include "Exit Grids.h" +#include "gamescreen.h" +#include "Quests.h" +#include "message.h" +#include "NPC.h" +#include "SkillCheck.h" +#include "handle doors.h" +#include "interface dialogue.h" +#include "smokeeffects.h" +#include "GameSettings.h" +#include "tile animation.h" +#include "ShopKeeper Interface.h" +#include "Arms Dealer Init.h" +#include "vehicles.h" +#include "rotting corpses.h" +#include "Interface Control.h" +#include "strategicmap.h" +#include "morale.h" +#include "meanwhile.h" +#include "drugs and alcohol.h" +#include "SkillCheck.h" +#include "boxing.h" +#include "overhead map.h" +#include "Map Information.h" +#include "environment.h" +#include "Game Clock.h" +#include "Explosion Control.h" +#include "Buildings.h" +#include "Text.h" +#include "Strategic Merc Handler.h" +#include "Campaign Types.h" +#include "Strategic Status.h" +#include "civ quotes.h" #endif //turnspeed @@ -237,16 +248,16 @@ UINT8 bHealthStrRanges[] = INT16 gsTerrainTypeSpeedModifiers[] = { - 5, // Flat ground - 5, // Floor - 5, // Paved road - 5, // Dirt road - 10, // LOW GRASS - 15, // HIGH GRASS - 20, // TRAIN TRACKS - 20, // LOW WATER - 25, // MID WATER - 30 // DEEP WATER + 5, // Flat ground + 5, // Floor + 5, // Paved road + 5, // Dirt road + 10, // LOW GRASS + 15, // HIGH GRASS + 20, // TRAIN TRACKS + 20, // LOW WATER + 25, // MID WATER + 30 // DEEP WATER }; //Kris: @@ -340,10 +351,10 @@ void HandleVehicleMovementSound( SOLDIERTYPE *pSoldier, BOOLEAN fOn ) void AdjustNoAPToFinishMove( SOLDIERTYPE *pSoldier, BOOLEAN fSet ) { - if ( pSoldier->ubBodyType == CROW ) - { - return; - } + if ( pSoldier->ubBodyType == CROW ) + { + return; + } // Check if we are a vehicle first.... if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) @@ -484,26 +495,26 @@ void HandleCrowShadowNewPosition( SOLDIERTYPE *pSoldier ) INT8 CalcActionPoints(SOLDIERTYPE *pSold) { - UINT8 ubPoints,ubMaxAPs; + UINT8 ubPoints,ubMaxAPs; INT8 bBandage; - // dead guys don't get any APs (they shouldn't be here asking for them!) - if (!pSold->bLife) - return(0); + // dead guys don't get any APs (they shouldn't be here asking for them!) + if (!pSold->bLife) + return(0); // people with sleep dart drug who have collapsed get no APs if ( (pSold->bSleepDrugCounter > 0) && pSold->bCollapsed ) return( 0 ); - // Calculate merc's action points at 100% capability (range is 10 - 25) - // round fractions of .5 up (that's why the +20 before the division! + // Calculate merc's action points at 100% capability (range is 10 - 25) + // round fractions of .5 up (that's why the +20 before the division! ubPoints = 5 + (((10 * EffectiveExpLevel( pSold ) + - 3 * EffectiveAgility( pSold ) + - 2 * pSold->bLifeMax + - 2 * EffectiveDexterity( pSold ) ) + 20) / 40); + 3 * EffectiveAgility( pSold ) + + 2 * pSold->bLifeMax + + 2 * EffectiveDexterity( pSold ) ) + 20) / 40); - //if (GameOption[INCREASEDAP] % 2 == 1) - //points += AP_INCREASE; + //if (GameOption[INCREASEDAP] % 2 == 1) + //points += AP_INCREASE; //Madd: Add in AP Bonuses (Penalties) from worn gear ubPoints += GetGearAPBonus ( pSold ); @@ -511,36 +522,36 @@ INT8 CalcActionPoints(SOLDIERTYPE *pSold) // Calculate bandage bBandage = pSold->bLifeMax - pSold->bLife - pSold->bBleeding; - // If injured, reduce action points accordingly (by up to 2/3rds) - if (pSold->bLife < pSold->bLifeMax) - { - ubPoints -= (2 * ubPoints * (pSold->bLifeMax - pSold->bLife + (bBandage / 2))) / - (3 * pSold->bLifeMax); - } + // If injured, reduce action points accordingly (by up to 2/3rds) + if (pSold->bLife < pSold->bLifeMax) + { + ubPoints -= (2 * ubPoints * (pSold->bLifeMax - pSold->bLife + (bBandage / 2))) / + (3 * pSold->bLifeMax); + } - // If tired, reduce action points accordingly (by up to 1/2) - if (pSold->bBreath < 100) - ubPoints -= (ubPoints * (100 - pSold->bBreath)) / 200; + // If tired, reduce action points accordingly (by up to 1/2) + if (pSold->bBreath < 100) + ubPoints -= (ubPoints * (100 - pSold->bBreath)) / 200; if (pSold->sWeightCarriedAtTurnStart > 100) { ubPoints = (UINT8) ( ((UINT32)ubPoints) * 100 / pSold->sWeightCarriedAtTurnStart ); } - // If resulting APs are below our permitted minimum, raise them to it! - if (ubPoints < AP_MINIMUM) + // If resulting APs are below our permitted minimum, raise them to it! + if (ubPoints < AP_MINIMUM) ubPoints = AP_MINIMUM; - // make sure action points doesn't exceed the permitted maximum - ubMaxAPs = gubMaxActionPoints[ pSold->ubBodyType ]; + // make sure action points doesn't exceed the permitted maximum + ubMaxAPs = gubMaxActionPoints[ pSold->ubBodyType ]; - //if (GameOption[INCREASEDAP] % 2 == 1) - // maxAPs += AP_INCREASE; + //if (GameOption[INCREASEDAP] % 2 == 1) + // maxAPs += AP_INCREASE; - // If resulting APs are below our permitted minimum, raise them to it! - if (ubPoints > ubMaxAPs) - ubPoints = ubMaxAPs; + // If resulting APs are below our permitted minimum, raise them to it! + if (ubPoints > ubMaxAPs) + ubPoints = ubMaxAPs; if ( pSold->ubBodyType == BLOODCAT ) { @@ -585,44 +596,44 @@ INT8 CalcActionPoints(SOLDIERTYPE *pSold) AdjustVehicleAPs( pSold, &ubPoints ); } -//Madd -// if ( pSold->bTeam != CIV_TEAM && pSold->bTeam != gbPlayerNum && gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE ) -// ubPoints += 5; // everything and everyone moves a little faster against you on insane... + //Madd + // if ( pSold->bTeam != CIV_TEAM && pSold->bTeam != gbPlayerNum && gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE ) + // ubPoints += 5; // everything and everyone moves a little faster against you on insane... //Kaiden: Took your idea a step further adding the bonus for each difficulty level // and then externalized it. AND added it to the Dont max out points section below. - if ( pSold->bTeam != CIV_TEAM && pSold->bTeam != gbPlayerNum) + if ( pSold->bTeam != CIV_TEAM && pSold->bTeam != gbPlayerNum) + { + + switch( gGameOptions.ubDifficultyLevel ) { + case DIF_LEVEL_EASY: - switch( gGameOptions.ubDifficultyLevel ) - { - case DIF_LEVEL_EASY: + ubPoints += gGameExternalOptions.iEasyAPBonus; + break; - ubPoints += gGameExternalOptions.iEasyAPBonus; - break; + case DIF_LEVEL_MEDIUM: - case DIF_LEVEL_MEDIUM: + ubPoints += gGameExternalOptions.iExperiencedAPBonus; + break; - ubPoints += gGameExternalOptions.iExperiencedAPBonus; - break; + case DIF_LEVEL_HARD: - case DIF_LEVEL_HARD: + ubPoints += gGameExternalOptions.iExpertAPBonus; + break; - ubPoints += gGameExternalOptions.iExpertAPBonus; - break; + case DIF_LEVEL_INSANE: - case DIF_LEVEL_INSANE: + ubPoints += gGameExternalOptions.iInsaneAPBonus; + break; - ubPoints += gGameExternalOptions.iInsaneAPBonus; - break; - - default: - ubPoints +=0; - } + default: + ubPoints +=0; } - else - ubPoints += gGameExternalOptions.iPlayerAPBonus; + } + else + ubPoints += gGameExternalOptions.iPlayerAPBonus; // if we are in boxing mode, adjust APs... THIS MUST BE LAST! if ( gTacticalStatus.bBoxingState == BOXING || gTacticalStatus.bBoxingState == PRE_BOXING ) @@ -630,7 +641,7 @@ INT8 CalcActionPoints(SOLDIERTYPE *pSold) ubPoints /= 2; } - return (ubPoints); + return (ubPoints); } void CalcNewActionPoints( SOLDIERTYPE *pSoldier ) @@ -656,34 +667,34 @@ void CalcNewActionPoints( SOLDIERTYPE *pSoldier ) // Don't max out if we are drugged.... if ( !GetDrugEffect( pSoldier, DRUG_TYPE_ADRENALINE ) ) { //Kaiden: If Enemy, they can max out, but their Max is NOW = MAX + diffAPBonus - // No sense in giving them a bonus if some of the points are wasted because we - // Didn't raise their cap by the same amount. + // No sense in giving them a bonus if some of the points are wasted because we + // Didn't raise their cap by the same amount. if ( pSoldier->bTeam != CIV_TEAM && pSoldier->bTeam != gbPlayerNum) { switch( gGameOptions.ubDifficultyLevel ) { - case DIF_LEVEL_EASY: + case DIF_LEVEL_EASY: - pSoldier->bActionPoints = __min( pSoldier->bActionPoints, (gubMaxActionPoints[ pSoldier->ubBodyType ] + gGameExternalOptions.iEasyAPBonus)); - break; + pSoldier->bActionPoints = __min( pSoldier->bActionPoints, (gubMaxActionPoints[ pSoldier->ubBodyType ] + gGameExternalOptions.iEasyAPBonus)); + break; - case DIF_LEVEL_MEDIUM: + case DIF_LEVEL_MEDIUM: - pSoldier->bActionPoints = __min( pSoldier->bActionPoints, (gubMaxActionPoints[ pSoldier->ubBodyType ] + gGameExternalOptions.iExperiencedAPBonus)); - break; + pSoldier->bActionPoints = __min( pSoldier->bActionPoints, (gubMaxActionPoints[ pSoldier->ubBodyType ] + gGameExternalOptions.iExperiencedAPBonus)); + break; - case DIF_LEVEL_HARD: + case DIF_LEVEL_HARD: - pSoldier->bActionPoints = __min( pSoldier->bActionPoints, (gubMaxActionPoints[ pSoldier->ubBodyType ] + gGameExternalOptions.iExpertAPBonus)); - break; + pSoldier->bActionPoints = __min( pSoldier->bActionPoints, (gubMaxActionPoints[ pSoldier->ubBodyType ] + gGameExternalOptions.iExpertAPBonus)); + break; - case DIF_LEVEL_INSANE: + case DIF_LEVEL_INSANE: - pSoldier->bActionPoints = __min( pSoldier->bActionPoints, (gubMaxActionPoints[ pSoldier->ubBodyType ] + gGameExternalOptions.iInsaneAPBonus)); - break; + pSoldier->bActionPoints = __min( pSoldier->bActionPoints, (gubMaxActionPoints[ pSoldier->ubBodyType ] + gGameExternalOptions.iInsaneAPBonus)); + break; - default: - pSoldier->bActionPoints = __min( pSoldier->bActionPoints, gubMaxActionPoints[ pSoldier->ubBodyType ] ); + default: + pSoldier->bActionPoints = __min( pSoldier->bActionPoints, gubMaxActionPoints[ pSoldier->ubBodyType ] ); } } @@ -849,13 +860,13 @@ BOOLEAN CreateSoldierCommon( UINT8 ubBodyType, SOLDIERTYPE *pSoldier, UINT16 usS pSoldier->uiTimeSameBattleSndDone = 0; // ATE: Reset every time..... pSoldier->fSoldierWasMoving = TRUE; - pSoldier->iTuringSoundID = NO_SAMPLE; - pSoldier->uiTimeSinceLastBleedGrunt = 0; + pSoldier->iTuringSoundID = NO_SAMPLE; + pSoldier->uiTimeSinceLastBleedGrunt = 0; - if ( pSoldier->ubBodyType == QUEENMONSTER ) - { - pSoldier->iPositionSndID = NewPositionSnd( NOWHERE, POSITION_SOUND_FROM_SOLDIER, (UINT32)pSoldier, QUEEN_AMBIENT_NOISE ); - } + if ( pSoldier->ubBodyType == QUEENMONSTER ) + { + pSoldier->iPositionSndID = NewPositionSnd( NOWHERE, POSITION_SOUND_FROM_SOLDIER, (UINT32)pSoldier, QUEEN_AMBIENT_NOISE ); + } // ANYTHING AFTER HERE CAN FAIL @@ -902,11 +913,11 @@ BOOLEAN CreateSoldierCommon( UINT8 ubBodyType, SOLDIERTYPE *pSoldier, UINT16 usS // bad anims are: HOPFENCE, // CLIMBDOWNROOF, FALLFORWARD_ROOF,FALLOFF, CLIMBUPROOF if( !gfWorldLoaded && - ( usState == HOPFENCE || - usState == CLIMBDOWNROOF || - usState == FALLFORWARD_ROOF || - usState == FALLOFF || - usState == CLIMBUPROOF ) ) + ( usState == HOPFENCE || + usState == CLIMBDOWNROOF || + usState == FALLFORWARD_ROOF || + usState == FALLOFF || + usState == CLIMBUPROOF ) ) { EVENT_InitNewSoldierAnim( pSoldier, STANDING, 0, TRUE ); } @@ -942,7 +953,7 @@ BOOLEAN CreateSoldierCommon( UINT8 ubBodyType, SOLDIERTYPE *pSoldier, UINT16 usS DebugMsg( TOPIC_JA2, DBG_LEVEL_0, String( "Soldier: Failed in creating soldier palettes" ) ); break; } - + fSuccess = TRUE; } while( FALSE ); @@ -968,10 +979,10 @@ BOOLEAN DeleteSoldier( SOLDIERTYPE *pSoldier ) if ( pSoldier != NULL ) { //if(pSoldier->pBackGround!=NULL) - //MemFree(pSoldier->pBackGround); + //MemFree(pSoldier->pBackGround); //if(pSoldier->pZBackground!=NULL) - //MemFree(pSoldier->pZBackground); + //MemFree(pSoldier->pZBackground); if( pSoldier->sGridNo != NOWHERE ) { @@ -985,7 +996,7 @@ BOOLEAN DeleteSoldier( SOLDIERTYPE *pSoldier ) } } } - + // Delete key ring if (pSoldier->pKeyRing) { @@ -1038,10 +1049,10 @@ BOOLEAN DeleteSoldier( SOLDIERTYPE *pSoldier ) } - if ( pSoldier->ubBodyType == QUEENMONSTER ) - { - DeletePositionSnd( pSoldier->iPositionSndID ); - } + if ( pSoldier->ubBodyType == QUEENMONSTER ) + { + DeletePositionSnd( pSoldier->iPositionSndID ); + } // Free any animations we may have locked... UnLoadCachedAnimationSurfaces( pSoldier->ubID, &( pSoldier->AnimCache) ); @@ -1057,12 +1068,12 @@ BOOLEAN DeleteSoldier( SOLDIERTYPE *pSoldier ) // Remove reseved movement value UnMarkMovementReserved( pSoldier ); - + } // REMOVE SOLDIER FROM SLOT! fRet = RemoveMercSlot( pSoldier ); - + if (!fRet) { RemoveAwaySlot( pSoldier ); @@ -1119,10 +1130,10 @@ BOOLEAN CreateSoldierLight( SOLDIERTYPE *pSoldier ) } } - if ( pSoldier->bLevel != 0 ) - { - LightSpriteRoofStatus(pSoldier->iLight, TRUE ); - } + if ( pSoldier->bLevel != 0 ) + { + LightSpriteRoofStatus(pSoldier->iLight, TRUE ); + } } return( TRUE ); @@ -1239,7 +1250,7 @@ BOOLEAN ReevaluateEnemyStance( SOLDIERTYPE *pSoldier, UINT16 usAnimState ) { return( FALSE ); } - + if ( gAnimControl[ usAnimState ].uiFlags & ( ANIM_MERCIDLE | ANIM_BREATH ) ) { if ( pSoldier->bOppCnt > 0 ) @@ -1270,7 +1281,7 @@ BOOLEAN ReevaluateEnemyStance( SOLDIERTYPE *pSoldier, UINT16 usAnimState ) return( fReturnVal ); } - + } } } @@ -1279,27 +1290,28 @@ BOOLEAN ReevaluateEnemyStance( SOLDIERTYPE *pSoldier, UINT16 usAnimState ) } - + void CheckForFreeupFromHit( SOLDIERTYPE *pSoldier, UINT32 uiOldAnimFlags, UINT32 uiNewAnimFlags, UINT16 usOldAniState, UINT16 usNewState ) { // THIS COULD POTENTIALLY CALL EVENT_INITNEWAnim() if the GUY was SUPPRESSED // CHECK IF THE OLD ANIMATION WAS A HIT START THAT WAS NOT FOLLOWED BY A HIT FINISH // IF SO, RELEASE ATTACKER FROM ATTACKING - // If old and new animations are the same, do nothing! - if ( usOldAniState == QUEEN_HIT && usNewState == QUEEN_HIT ) - { - return; - } + // If old and new animations are the same, do nothing! + if ( usOldAniState == QUEEN_HIT && usNewState == QUEEN_HIT ) + { + return; + } if ( usOldAniState != usNewState && ( uiOldAnimFlags & ANIM_HITSTART ) && !( uiNewAnimFlags & ANIM_HITFINISH ) && !( uiNewAnimFlags & ANIM_IGNOREHITFINISH ) && !(pSoldier->uiStatusFlags & SOLDIER_TURNINGFROMHIT ) ) { + // 0verhaul: Yet again, this is handled by the state transition code. // Release attacker - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, normal hit animation ended NEW: %s ( %d ) OLD: %s ( %d )", gAnimControl[ usNewState ].zAnimStr, usNewState, gAnimControl[ usOldAniState ].zAnimStr, pSoldier->usOldAniState ) ); - ReleaseSoldiersAttacker( pSoldier ); + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, normal hit animation ended NEW: %s ( %d ) OLD: %s ( %d )", gAnimControl[ usNewState ].zAnimStr, usNewState, gAnimControl[ usOldAniState ].zAnimStr, pSoldier->usOldAniState ) ); + // ReleaseSoldiersAttacker( pSoldier ); //FREEUP GETTING HIT FLAG - pSoldier->fGettingHit = FALSE; + // pSoldier->fGettingHit = FALSE; // ATE: if our guy, have 10% change of say damn, if still conscious... if ( pSoldier->bTeam == gbPlayerNum && pSoldier->bLife >= OKLIFE ) @@ -1315,12 +1327,13 @@ void CheckForFreeupFromHit( SOLDIERTYPE *pSoldier, UINT32 uiOldAnimFlags, UINT32 // OBLY DO THIS IF 1 ) We are dead already or 2 ) We are alive still if ( ( uiOldAnimFlags & ANIM_HITWHENDOWN ) && ( ( pSoldier->uiStatusFlags & SOLDIER_DEAD ) || pSoldier->bLife != 0 ) ) { + // 0verhaul: Ditto // Release attacker - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, animation of kill on the ground ended") ); - ReleaseSoldiersAttacker( pSoldier ); + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, animation of kill on the ground ended") ); + // ReleaseSoldiersAttacker( pSoldier ); //FREEUP GETTING HIT FLAG - pSoldier->fGettingHit = FALSE; + // pSoldier->fGettingHit = FALSE; if ( pSoldier->bLife == 0 ) { @@ -1362,14 +1375,14 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT if ( pSoldier->fRTInNonintAnim ) { - if ( !(gTacticalStatus.uiFlags & INCOMBAT) ) - { - return( FALSE ); - } - else - { - pSoldier->fRTInNonintAnim = FALSE; - } + if ( !(gTacticalStatus.uiFlags & INCOMBAT) ) + { + return( FALSE ); + } + else + { + pSoldier->fRTInNonintAnim = FALSE; + } } @@ -1388,7 +1401,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT if ( usStartingAniCode == 0 ) { if ( gAnimControl[ usNewState ].ubHeight != gAnimControl[ pSoldier->usAnimState ].ubEndHeight && - !( gAnimControl[ usNewState ].uiFlags & ( ANIM_STANCECHANGEANIM | ANIM_IGNORE_AUTOSTANCE ) ) ) + !( gAnimControl[ usNewState ].uiFlags & ( ANIM_STANCECHANGEANIM | ANIM_IGNORE_AUTOSTANCE ) ) ) { // Check if we are going from crouched height to prone height, and adjust fast turning accordingly @@ -1473,7 +1486,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT //if ( pSoldier->bLife > INJURED_CHANGE_THREASHOLD ) { // Don't do some of this if we are a monster! - // ATE: LOWER AIMATION IS GOOD, RAISE ONE HOWEVER MAY CAUSE PROBLEMS FOR AI.... + // ATE: LOWER AIMATION IS GOOD, RAISE ONE HOWEVER MAY CAUSE PROBLEMS FOR AI.... if ( !(pSoldier->uiStatusFlags & SOLDIER_MONSTER ) && pSoldier->ubBodyType != ROBOTNOWEAPON && pSoldier->bTeam == gbPlayerNum ) { // If this animation is a raise_weapon animation @@ -1484,18 +1497,18 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT // 1) We have a rifle in hand... usItem = pSoldier->inv[ HANDPOS ].usItem; -// if ( usItem != NOTHING && (Item[ usItem ].fFlags & ITEM_TWO_HANDED) && usItem != ROCKET_LAUNCHER && usItem != RPG7 ) + // if ( usItem != NOTHING && (Item[ usItem ].fFlags & ITEM_TWO_HANDED) && usItem != ROCKET_LAUNCHER && usItem != RPG7 ) if ( usItem != NOTHING && (Item[ usItem ].twohanded ) && !Item[usItem].rocketlauncher ) { // Switch on height! switch( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: + case ANIM_STAND: - // 2) OK, all's fine... lower weapon first.... - pSoldier->usPendingAnimation = usNewState; - // Set new state to be animation to move to new stance - usNewState = RAISE_RIFLE; + // 2) OK, all's fine... lower weapon first.... + pSoldier->usPendingAnimation = usNewState; + // Set new state to be animation to move to new stance + usNewState = RAISE_RIFLE; } } } @@ -1508,18 +1521,18 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT // 1) We have a rifle in hand... usItem = pSoldier->inv[ HANDPOS ].usItem; -// if ( usItem != NOTHING && (Item[ usItem ].fFlags & ITEM_TWO_HANDED) && usItem != ROCKET_LAUNCHER && usItem != RPG7 ) + // if ( usItem != NOTHING && (Item[ usItem ].fFlags & ITEM_TWO_HANDED) && usItem != ROCKET_LAUNCHER && usItem != RPG7 ) if ( usItem != NOTHING && (Item[ usItem ].twohanded ) && !Item[usItem].rocketlauncher ) { // Switch on height! switch( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: + case ANIM_STAND: - // 2) OK, all's fine... lower weapon first.... - pSoldier->usPendingAnimation = usNewState; - // Set new state to be animation to move to new stance - usNewState = LOWER_RIFLE; + // 2) OK, all's fine... lower weapon first.... + pSoldier->usPendingAnimation = usNewState; + // Set new state to be animation to move to new stance + usNewState = LOWER_RIFLE; } } } @@ -1533,7 +1546,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT // Set new state to be animation to move to new stance usNewState = END_COWER; } - + // If we want to start swatting, put a pending animation if( pSoldier->usAnimState != START_SWAT && usNewState == SWATTING ) { @@ -1567,8 +1580,8 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT { if ( usNewState == READY_RIFLE_STAND ) { - // pSoldier->usPendingAnimation2 = usNewState; - // usNewState = FROM_INJURED_TRANSITION; + // pSoldier->usPendingAnimation2 = usNewState; + // usNewState = FROM_INJURED_TRANSITION; } } } @@ -1606,7 +1619,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT { if ( Item[ usItem ].usItemClass == IC_GUN && !Item[usItem].rocketlauncher ) { -// if ( (Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) + // if ( (Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) if ( (Item[ usItem ].twohanded ) ) { usNewState = BIGMERC_CROUCH_TRANS_INTO; @@ -1626,7 +1639,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT { if ( Item[ usItem ].usItemClass == IC_GUN && !Item[usItem].rocketlauncher ) { -// if ( (Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) + // if ( (Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) if ( (Item[ usItem ].twohanded ) ) { usNewState = BIGMERC_CROUCH_TRANS_OUTOF; @@ -1662,23 +1675,23 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT } } - // ATE: Patch hole for breath collapse for roofs, fences - if ( usNewState == CLIMBUPROOF || usNewState == CLIMBDOWNROOF || usNewState == HOPFENCE ) - { - // Check for breath collapse if a given animation like - if ( CheckForBreathCollapse( pSoldier ) || pSoldier->bCollapsed ) - { + // ATE: Patch hole for breath collapse for roofs, fences + if ( usNewState == CLIMBUPROOF || usNewState == CLIMBDOWNROOF || usNewState == HOPFENCE ) + { + // Check for breath collapse if a given animation like + if ( CheckForBreathCollapse( pSoldier ) || pSoldier->bCollapsed ) + { // UNset UI UnSetUIBusy( pSoldier->ubID ); SoldierCollapse( pSoldier ); - + pSoldier->bBreathCollapsed = FALSE; - return( FALSE ); + return( FALSE ); - } - } + } + } // If we are in water.....and trying to run, change to run if ( pSoldier->bOverTerrainType == LOW_WATER || pSoldier->bOverTerrainType == MED_WATER ) @@ -1711,7 +1724,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE; } } - + // We are about to start moving // Handle buddy beginning to move... // check new gridno, etc @@ -1735,37 +1748,37 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT if ( !( gAnimControl[ usNewState ].uiFlags & ANIM_SPECIALMOVE ) ) { - // Handle goto new tile... - if ( HandleGotoNewGridNo( pSoldier, &fKeepMoving, TRUE, usNewState ) ) - { - if ( !fKeepMoving ) - { - return( FALSE ); - } + // Handle goto new tile... + if ( HandleGotoNewGridNo( pSoldier, &fKeepMoving, TRUE, usNewState ) ) + { + if ( !fKeepMoving ) + { + return( FALSE ); + } - // Make sure desy = zeroed out... - // pSoldier->fPastXDest = pSoldier->fPastYDest = FALSE; - } - else - { - if ( pSoldier->bBreathCollapsed ) - { - // UNset UI - UnSetUIBusy( pSoldier->ubID ); + // Make sure desy = zeroed out... + // pSoldier->fPastXDest = pSoldier->fPastYDest = FALSE; + } + else + { + if ( pSoldier->bBreathCollapsed ) + { + // UNset UI + UnSetUIBusy( pSoldier->ubID ); - SoldierCollapse( pSoldier ); - - pSoldier->bBreathCollapsed = FALSE; - } - return( FALSE ); - } - } - else - { + SoldierCollapse( pSoldier ); + + pSoldier->bBreathCollapsed = FALSE; + } + return( FALSE ); + } + } + else + { // Change desired direction // Just change direction EVENT_InternalSetSoldierDestination( pSoldier, pSoldier->usPathingData[ pSoldier->usPathIndex ], FALSE, pSoldier->usAnimState ); - } + } //check for services ReceivingSoldierCancelServices( pSoldier ); @@ -1795,13 +1808,13 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT // Reset to false always..... // ( Unless locked ) - if ( gAnimControl[ usNewState ].uiFlags & ANIM_MOVING ) - { - if ( pSoldier->usDontUpdateNewGridNoOnMoveAnimChange != LOCKED_NO_NEWGRIDNO ) - { - pSoldier->usDontUpdateNewGridNoOnMoveAnimChange = FALSE; - } - } + if ( gAnimControl[ usNewState ].uiFlags & ANIM_MOVING ) + { + if ( pSoldier->usDontUpdateNewGridNoOnMoveAnimChange != LOCKED_NO_NEWGRIDNO ) + { + pSoldier->usDontUpdateNewGridNoOnMoveAnimChange = FALSE; + } + } if ( fTryingToRestart ) { @@ -1888,269 +1901,269 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT // Do special things based on new state switch( usNewState ) { - case STANDING: + case STANDING: - // Update desired height - pSoldier->ubDesiredHeight = ANIM_STAND; - break; + // Update desired height + pSoldier->ubDesiredHeight = ANIM_STAND; + break; - case CROUCHING: + case CROUCHING: - // Update desired height - pSoldier->ubDesiredHeight = ANIM_CROUCH; - break; + // Update desired height + pSoldier->ubDesiredHeight = ANIM_CROUCH; + break; - case PRONE: + case PRONE: - // Update desired height - pSoldier->ubDesiredHeight = ANIM_PRONE; - break; + // Update desired height + pSoldier->ubDesiredHeight = ANIM_PRONE; + break; - case READY_RIFLE_STAND: - case READY_RIFLE_PRONE: - case READY_RIFLE_CROUCH: - case READY_DUAL_STAND: - case READY_DUAL_CROUCH: - case READY_DUAL_PRONE: + case READY_RIFLE_STAND: + case READY_RIFLE_PRONE: + case READY_RIFLE_CROUCH: + case READY_DUAL_STAND: + case READY_DUAL_CROUCH: + case READY_DUAL_PRONE: - // OK, get points to ready weapon.... - if ( !pSoldier->fDontChargeReadyAPs ) + // OK, get points to ready weapon.... + if ( !pSoldier->fDontChargeReadyAPs ) + { + sAPCost = GetAPsToReadyWeapon( pSoldier, usNewState ); + DeductPoints( pSoldier, sAPCost, sBPCost ); + } + else + { + pSoldier->fDontChargeReadyAPs = FALSE; + } + break; + + case WALKING: + + pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; + pSoldier->ubPendingActionAnimCount = 0; + break; + + case SWATTING: + + pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; + pSoldier->ubPendingActionAnimCount = 0; + break; + + case CRAWLING: + + // Turn off flag... + pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_OFF; + pSoldier->ubPendingActionAnimCount = 0; + pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; + break; + + case RUNNING: + + // Only if our previous is not running + if ( pSoldier->usAnimState != RUNNING ) + { + sAPCost = AP_START_RUN_COST; + DeductPoints( pSoldier, sAPCost, sBPCost ); + } + // Set pending action count to 0 + pSoldier->ubPendingActionAnimCount = 0; + pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; + break; + + case ADULTMONSTER_WALKING: + pSoldier->ubPendingActionAnimCount = 0; + break; + + case ROBOT_WALK: + pSoldier->ubPendingActionAnimCount = 0; + break; + + case KNEEL_UP: + case KNEEL_DOWN: + case BIGMERC_CROUCH_TRANS_INTO: + case BIGMERC_CROUCH_TRANS_OUTOF: + + if ( !pSoldier->fDontChargeAPsForStanceChange ) + { + DeductPoints( pSoldier, AP_CROUCH, BP_CROUCH ); + } + pSoldier->fDontChargeAPsForStanceChange = FALSE; + break; + + case PRONE_UP: + case PRONE_DOWN: + + // ATE: If we are NOT waiting for prone down... + if ( pSoldier->fTurningFromPronePosition < TURNING_FROM_PRONE_START_UP_FROM_MOVE && !pSoldier->fDontChargeAPsForStanceChange ) + { + // ATE: Don't do this if we are still 'moving'.... + if ( pSoldier->sGridNo == pSoldier->sFinalDestination || pSoldier->usPathIndex == 0 ) { - sAPCost = GetAPsToReadyWeapon( pSoldier, usNewState ); - DeductPoints( pSoldier, sAPCost, sBPCost ); + DeductPoints( pSoldier, AP_PRONE, BP_PRONE ); } - else - { - pSoldier->fDontChargeReadyAPs = FALSE; - } - break; + } + pSoldier->fDontChargeAPsForStanceChange = FALSE; + break; - case WALKING: + //Deduct points for stance change + //sAPCost = GetAPsToChangeStance( pSoldier, gAnimControl[ usNewState ].ubEndHeight ); + //DeductPoints( pSoldier, sAPCost, 0 ); + //break; - pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; - pSoldier->ubPendingActionAnimCount = 0; - break; + case START_AID: - case SWATTING: + DeductPoints( pSoldier, AP_START_FIRST_AID, BP_START_FIRST_AID ); + break; - pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; - pSoldier->ubPendingActionAnimCount = 0; - break; + case CUTTING_FENCE: + DeductPoints( pSoldier, AP_USEWIRECUTTERS, BP_USEWIRECUTTERS ); + break; - case CRAWLING: + case PLANT_BOMB: - // Turn off flag... - pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_OFF; - pSoldier->ubPendingActionAnimCount = 0; - pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; - break; + DeductPoints( pSoldier, AP_DROP_BOMB, 0 ); + break; - case RUNNING: + case STEAL_ITEM: - // Only if our previous is not running - if ( pSoldier->usAnimState != RUNNING ) - { - sAPCost = AP_START_RUN_COST; - DeductPoints( pSoldier, sAPCost, sBPCost ); - } - // Set pending action count to 0 - pSoldier->ubPendingActionAnimCount = 0; - pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; - break; + DeductPoints( pSoldier, AP_STEAL_ITEM, 0 ); + break; - case ADULTMONSTER_WALKING: - pSoldier->ubPendingActionAnimCount = 0; - break; + case CROW_DIE: - case ROBOT_WALK: - pSoldier->ubPendingActionAnimCount = 0; - break; + // Delete shadow of crow.... + if ( pSoldier->pAniTile != NULL ) + { + DeleteAniTile( pSoldier->pAniTile ); + pSoldier->pAniTile = NULL; + } + break; - case KNEEL_UP: - case KNEEL_DOWN: - case BIGMERC_CROUCH_TRANS_INTO: - case BIGMERC_CROUCH_TRANS_OUTOF: + case CROW_FLY: - if ( !pSoldier->fDontChargeAPsForStanceChange ) - { - DeductPoints( pSoldier, AP_CROUCH, BP_CROUCH ); - } - pSoldier->fDontChargeAPsForStanceChange = FALSE; - break; + // Ate: startup a shadow ( if gridno is set ) + HandleCrowShadowNewGridNo( pSoldier ); + break; - case PRONE_UP: - case PRONE_DOWN: + case CROW_EAT: - // ATE: If we are NOT waiting for prone down... - if ( pSoldier->fTurningFromPronePosition < TURNING_FROM_PRONE_START_UP_FROM_MOVE && !pSoldier->fDontChargeAPsForStanceChange ) - { - // ATE: Don't do this if we are still 'moving'.... - if ( pSoldier->sGridNo == pSoldier->sFinalDestination || pSoldier->usPathIndex == 0 ) - { - DeductPoints( pSoldier, AP_PRONE, BP_PRONE ); - } - } - pSoldier->fDontChargeAPsForStanceChange = FALSE; - break; + // ATE: Make sure height level is 0.... + SetSoldierHeight( pSoldier, (FLOAT)(0) ); + HandleCrowShadowRemoveGridNo( pSoldier ); + break; - //Deduct points for stance change - //sAPCost = GetAPsToChangeStance( pSoldier, gAnimControl[ usNewState ].ubEndHeight ); - //DeductPoints( pSoldier, sAPCost, 0 ); - //break; + case USE_REMOTE: - case START_AID: - - DeductPoints( pSoldier, AP_START_FIRST_AID, BP_START_FIRST_AID ); - break; - - case CUTTING_FENCE: - DeductPoints( pSoldier, AP_USEWIRECUTTERS, BP_USEWIRECUTTERS ); - break; - - case PLANT_BOMB: - - DeductPoints( pSoldier, AP_DROP_BOMB, 0 ); - break; - - case STEAL_ITEM: - - DeductPoints( pSoldier, AP_STEAL_ITEM, 0 ); - break; - - case CROW_DIE: - - // Delete shadow of crow.... - if ( pSoldier->pAniTile != NULL ) - { - DeleteAniTile( pSoldier->pAniTile ); - pSoldier->pAniTile = NULL; - } - break; - - case CROW_FLY: - - // Ate: startup a shadow ( if gridno is set ) - HandleCrowShadowNewGridNo( pSoldier ); - break; - - case CROW_EAT: - - // ATE: Make sure height level is 0.... - SetSoldierHeight( pSoldier, (FLOAT)(0) ); - HandleCrowShadowRemoveGridNo( pSoldier ); - break; - - case USE_REMOTE: - - DeductPoints( pSoldier, AP_USE_REMOTE, 0 ); - break; + DeductPoints( pSoldier, AP_USE_REMOTE, 0 ); + break; //case PUNCH: - //Deduct points for punching - //sAPCost = MinAPsToAttack( pSoldier, pSoldier->sGridNo, FALSE ); - //DeductPoints( pSoldier, sAPCost, 0 ); - //break; + //Deduct points for punching + //sAPCost = MinAPsToAttack( pSoldier, pSoldier->sGridNo, FALSE ); + //DeductPoints( pSoldier, sAPCost, 0 ); + //break; - case HOPFENCE: + case HOPFENCE: - DeductPoints( pSoldier, AP_JUMPFENCE, BP_JUMPFENCE ); - break; + DeductPoints( pSoldier, AP_JUMPFENCE, BP_JUMPFENCE ); + break; // Deduct aps for falling down.... - case FALLBACK_HIT_STAND: - case FALLFORWARD_FROMHIT_STAND: + case FALLBACK_HIT_STAND: + case FALLFORWARD_FROMHIT_STAND: - DeductPoints( pSoldier, AP_FALL_DOWN, BP_FALL_DOWN ); - break; + DeductPoints( pSoldier, AP_FALL_DOWN, BP_FALL_DOWN ); + break; - case FALLFORWARD_FROMHIT_CROUCH: + case FALLFORWARD_FROMHIT_CROUCH: - DeductPoints( pSoldier, (AP_FALL_DOWN/2), (BP_FALL_DOWN/2) ); - break; + DeductPoints( pSoldier, (AP_FALL_DOWN/2), (BP_FALL_DOWN/2) ); + break; - case QUEEN_SWIPE: + case QUEEN_SWIPE: - // ATE: set damage counter... - pSoldier->uiPendingActionData1 = 0; - break; + // ATE: set damage counter... + pSoldier->uiPendingActionData1 = 0; + break; - case CLIMBDOWNROOF: + case CLIMBDOWNROOF: - // disable sight - gTacticalStatus.uiFlags |= DISALLOW_SIGHT; + // disable sight + gTacticalStatus.uiFlags |= DISALLOW_SIGHT; - DeductPoints( pSoldier, AP_CLIMBOFFROOF, BP_CLIMBOFFROOF ); - break; + DeductPoints( pSoldier, AP_CLIMBOFFROOF, BP_CLIMBOFFROOF ); + break; - case CLIMBUPROOF: + case CLIMBUPROOF: - // disable sight - gTacticalStatus.uiFlags |= DISALLOW_SIGHT; + // disable sight + gTacticalStatus.uiFlags |= DISALLOW_SIGHT; - DeductPoints( pSoldier, AP_CLIMBROOF, BP_CLIMBROOF ); - break; + DeductPoints( pSoldier, AP_CLIMBROOF, BP_CLIMBROOF ); + break; - case JUMP_OVER_BLOCKING_PERSON: - - // Set path.... - { - UINT16 usNewGridNo; + case JUMP_OVER_BLOCKING_PERSON: - DeductPoints( pSoldier, AP_JUMP_OVER, BP_JUMP_OVER ); + // Set path.... + { + UINT16 usNewGridNo; - usNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( pSoldier->bDirection ) ); - usNewGridNo = NewGridNo( (UINT16)usNewGridNo, DirectionInc( pSoldier->bDirection ) ); + DeductPoints( pSoldier, AP_JUMP_OVER, BP_JUMP_OVER ); - pSoldier->usPathDataSize = 0; - pSoldier->usPathIndex = 0; - pSoldier->usPathingData[ pSoldier->usPathDataSize ] = pSoldier->bDirection; - pSoldier->usPathDataSize++; - pSoldier->usPathingData[ pSoldier->usPathDataSize ] = pSoldier->bDirection; - pSoldier->usPathDataSize++; - pSoldier->sFinalDestination = usNewGridNo; - // Set direction - EVENT_InternalSetSoldierDestination( pSoldier, pSoldier->usPathingData[ pSoldier->usPathIndex ], FALSE, JUMP_OVER_BLOCKING_PERSON ); - } - break; - + usNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( pSoldier->bDirection ) ); + usNewGridNo = NewGridNo( (UINT16)usNewGridNo, DirectionInc( pSoldier->bDirection ) ); - case GENERIC_HIT_STAND: - case GENERIC_HIT_CROUCH: - case STANDING_BURST_HIT: - case ADULTMONSTER_HIT: - case ADULTMONSTER_DYING: - case COW_HIT: - case COW_DYING: - case BLOODCAT_HIT: - case BLOODCAT_DYING: - case WATER_HIT: - case WATER_DIE: - case DEEP_WATER_HIT: - case DEEP_WATER_DIE: - case RIFLE_STAND_HIT: - case LARVAE_HIT: - case LARVAE_DIE: - case QUEEN_HIT: - case QUEEN_DIE: - case INFANT_HIT: - case INFANT_DIE: - case CRIPPLE_HIT: - case CRIPPLE_DIE: - case CRIPPLE_DIE_FLYBACK: - case ROBOTNW_HIT: - case ROBOTNW_DIE: + pSoldier->usPathDataSize = 0; + pSoldier->usPathIndex = 0; + pSoldier->usPathingData[ pSoldier->usPathDataSize ] = pSoldier->bDirection; + pSoldier->usPathDataSize++; + pSoldier->usPathingData[ pSoldier->usPathDataSize ] = pSoldier->bDirection; + pSoldier->usPathDataSize++; + pSoldier->sFinalDestination = usNewGridNo; + // Set direction + EVENT_InternalSetSoldierDestination( pSoldier, pSoldier->usPathingData[ pSoldier->usPathIndex ], FALSE, JUMP_OVER_BLOCKING_PERSON ); + } + break; - // Set getting hit flag to TRUE - pSoldier->fGettingHit = TRUE; - break; - case CHARIOTS_OF_FIRE: - case BODYEXPLODING: + case GENERIC_HIT_STAND: + case GENERIC_HIT_CROUCH: + case STANDING_BURST_HIT: + case ADULTMONSTER_HIT: + case ADULTMONSTER_DYING: + case COW_HIT: + case COW_DYING: + case BLOODCAT_HIT: + case BLOODCAT_DYING: + case WATER_HIT: + case WATER_DIE: + case DEEP_WATER_HIT: + case DEEP_WATER_DIE: + case RIFLE_STAND_HIT: + case LARVAE_HIT: + case LARVAE_DIE: + case QUEEN_HIT: + case QUEEN_DIE: + case INFANT_HIT: + case INFANT_DIE: + case CRIPPLE_HIT: + case CRIPPLE_DIE: + case CRIPPLE_DIE_FLYBACK: + case ROBOTNW_HIT: + case ROBOTNW_DIE: - // Merc on fire! - pSoldier->uiPendingActionData1 = PlaySoldierJA2Sample( pSoldier->ubID, ( FIRE_ON_MERC ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 5, SoundDir( pSoldier->sGridNo ), TRUE ); - break; + // Set getting hit flag to TRUE + pSoldier->fGettingHit = TRUE; + break; + + case CHARIOTS_OF_FIRE: + case BODYEXPLODING: + + // Merc on fire! + pSoldier->uiPendingActionData1 = PlaySoldierJA2Sample( pSoldier->ubID, ( FIRE_ON_MERC ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 5, SoundDir( pSoldier->sGridNo ), TRUE ); + break; } } @@ -2159,7 +2172,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT // From animation control, set surface - if ( SetSoldierAnimationSurface( pSoldier, usNewState ) == FALSE ) + if ( SetSoldierAnimationSurface( pSoldier, usNewState ) == FALSE ) { return( FALSE ); } @@ -2171,6 +2184,36 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT // Change state value! pSoldier->usAnimState = usNewState; + // Set current frame + pSoldier->usAniCode = usStartingAniCode; + + // Handle cleanup stuff for getting hit. Shouldn't this be part of the animation script? + CheckForFreeupFromHit( pSoldier, uiOldAnimFlags, uiNewAnimFlags, pSoldier->usOldAniState, usNewState ); + + // Perform attack busy stuff + if (pSoldier->usOldAniState != pSoldier->usAnimState) + { + if ( uiNewAnimFlags & ANIM_ATTACK ) { + gTacticalStatus.ubAttackBusyCount++; + DebugAttackBusy( String( "**** Attack animation transfer to %s for %d.\nABC now %d\n", gAnimControl[ usNewState ].zAnimStr, pSoldier->ubID, gTacticalStatus.ubAttackBusyCount ) ); + } else if (uiOldAnimFlags & ANIM_ATTACK || pSoldier->fChangingStanceDueToSuppression ) { + DebugAttackBusy( String( "**** Transfer to %s for %d.\n", gAnimControl[ usNewState ].zAnimStr, pSoldier->ubID ) ); + } + if (uiOldAnimFlags & ANIM_ATTACK ) { + DebugAttackBusy( String( "**** Attack animation transfer from %s for %d. Reducing ABC.\n", gAnimControl[ pSoldier->usOldAniState ].zAnimStr, pSoldier->ubID ) ); + ReduceAttackBusyCount( ); + } else if (uiNewAnimFlags & ANIM_ATTACK || pSoldier->fChangingStanceDueToSuppression ) { + DebugAttackBusy( String( "**** Transfer from %s for %d\n", gAnimControl[ pSoldier->usOldAniState ].zAnimStr, pSoldier->ubID ) ); + } + } + + if (pSoldier->fChangingStanceDueToSuppression) + { + pSoldier->fChangingStanceDueToSuppression = FALSE; + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - end of suppression stance change") ); + DebugAttackBusy( String( "@@@@@@@ Freeing up attacker - end of suppression stance change for %d\n", pSoldier->ubID ) ); + ReduceAttackBusyCount( ); + } pSoldier->sZLevelOverride = -1; @@ -2182,11 +2225,11 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT // Do some special things for some actions switch( pSoldier->ubPendingAction ) { - case MERC_GIVEITEM: + case MERC_GIVEITEM: - // Unset target as enaged - MercPtrs[ pSoldier->uiPendingActionData4 ]->uiStatusFlags &= (~SOLDIER_ENGAGEDINACTION); - break; + // Unset target as enaged + MercPtrs[ pSoldier->uiPendingActionData4 ]->uiStatusFlags &= (~SOLDIER_ENGAGEDINACTION); + break; } pSoldier->ubPendingAction = NO_PENDING_ACTION; } @@ -2208,8 +2251,6 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT // Reset some animation values pSoldier->fForceShade = FALSE; - CheckForFreeupFromHit( pSoldier, uiOldAnimFlags, uiNewAnimFlags, pSoldier->usOldAniState, usNewState ); - // CHECK IF WE ARE AT AN IDLE ACTION #if 0 if ( gAnimControl[ usNewState ].uiFlags & ANIM_IDLE ) @@ -2222,9 +2263,6 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT } #endif - // Set current frame - pSoldier->usAniCode = usStartingAniCode; - // ATE; For some animations that could use some variations, do so.... if (usNewState == CHARIOTS_OF_FIRE || usNewState == BODYEXPLODING ) { @@ -2240,7 +2278,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT // Reset counters RESETTIMECOUNTER( pSoldier->UpdateCounter, pSoldier->sAniDelay ); - + // Adjust to new animation frame ( the first one ) AdjustToNextAnimationFrame( pSoldier ); @@ -2249,7 +2287,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT // Lesh: test fix visibility after raising gun if ( ( gAnimControl[ pSoldier->usOldAniState ].uiFlags & ANIM_RAISE_WEAPON) && (gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FIREREADY) ) - //equivalent if ( (pSoldier->usAnimState == AIM_RIFLE_PRONE) || (pSoldier->usAnimState == AIM_RIFLE_CROUCH) || (pSoldier->usAnimState == AIM_RIFLE_STAND) ) + //equivalent if ( (pSoldier->usAnimState == AIM_RIFLE_PRONE) || (pSoldier->usAnimState == AIM_RIFLE_CROUCH) || (pSoldier->usAnimState == AIM_RIFLE_STAND) ) { if ( (pSoldier->usOldAniState == READY_RIFLE_STAND) || (pSoldier->usOldAniState == READY_RIFLE_CROUCH) || (pSoldier->usOldAniState == READY_RIFLE_PRONE) ) { @@ -2284,7 +2322,7 @@ BOOLEAN EVENT_InitNewSoldierAnim( SOLDIERTYPE *pSoldier, UINT16 usNewState, UINT if( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) ) { if ( ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_STATIONARY ) && - ( gAnimControl[ pSoldier->usOldAniState ].uiFlags & ANIM_MOVING ) ) + ( gAnimControl[ pSoldier->usOldAniState ].uiFlags & ANIM_MOVING ) ) { PlaySoldierFootstepSound( pSoldier ); } @@ -2304,38 +2342,38 @@ void InternalRemoveSoldierFromGridNo( SOLDIERTYPE *pSoldier, BOOLEAN fForce ) if((pSoldier->sGridNo!=NO_MAP_POS) ) { - if ( pSoldier->bInSector || fForce ) - { - // Remove from world ( old pos ) - RemoveMerc( pSoldier->sGridNo, pSoldier, FALSE ); - HandleAnimationProfile( pSoldier, pSoldier->usAnimState, TRUE ); + if ( pSoldier->bInSector || fForce ) + { + // Remove from world ( old pos ) + RemoveMerc( pSoldier->sGridNo, pSoldier, FALSE ); + HandleAnimationProfile( pSoldier, pSoldier->usAnimState, TRUE ); - // Remove records of this guy being adjacent - for (bDir = 0; bDir < NUM_WORLD_DIRECTIONS; bDir++) - { - iGridNo = pSoldier->sGridNo + DirIncrementer[ bDir ]; - if( iGridNo >= 0 && iGridNo < WORLD_MAX ) - { - gpWorldLevelData[ iGridNo ].ubAdjacentSoldierCnt--; - } - } + // Remove records of this guy being adjacent + for (bDir = 0; bDir < NUM_WORLD_DIRECTIONS; bDir++) + { + iGridNo = pSoldier->sGridNo + DirIncrementer[ bDir ]; + if( iGridNo >= 0 && iGridNo < WORLD_MAX ) + { + gpWorldLevelData[ iGridNo ].ubAdjacentSoldierCnt--; + } + } - HandlePlacingRoofMarker( pSoldier, pSoldier->sGridNo, FALSE , FALSE ); + HandlePlacingRoofMarker( pSoldier, pSoldier->sGridNo, FALSE , FALSE ); - // Remove reseved movement value - UnMarkMovementReserved( pSoldier ); + // Remove reseved movement value + UnMarkMovementReserved( pSoldier ); - HandleCrowShadowRemoveGridNo( pSoldier ); + HandleCrowShadowRemoveGridNo( pSoldier ); - // Reset gridno... - pSoldier->sGridNo = NO_MAP_POS; - } + // Reset gridno... + pSoldier->sGridNo = NO_MAP_POS; + } } } void RemoveSoldierFromGridNo( SOLDIERTYPE *pSoldier ) { - InternalRemoveSoldierFromGridNo( pSoldier, FALSE ); + InternalRemoveSoldierFromGridNo( pSoldier, FALSE ); } @@ -2506,10 +2544,10 @@ void SetSoldierGridNo( SOLDIERTYPE *pSoldier, INT16 sNewGridNo, BOOLEAN fForceRe pSoldier->sOldGridNo = pSoldier->sGridNo; - if ( pSoldier->ubBodyType == QUEENMONSTER ) - { - SetPositionSndGridNo( pSoldier->iPositionSndID, sNewGridNo ); - } + if ( pSoldier->ubBodyType == QUEENMONSTER ) + { + SetPositionSndGridNo( pSoldier->iPositionSndID, sNewGridNo ); + } if ( !( pSoldier->uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) ) { @@ -2554,7 +2592,7 @@ void SetSoldierGridNo( SOLDIERTYPE *pSoldier, INT16 sNewGridNo, BOOLEAN fForceRe pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO; pSoldier->usStrategicInsertionData = sNewGridNo; - + // Remove this gridno as a reserved place! if ( !( pSoldier->uiStatusFlags & ( SOLDIER_DRIVER | SOLDIER_PASSENGER ) ) ) { @@ -2584,11 +2622,11 @@ void SetSoldierGridNo( SOLDIERTYPE *pSoldier, INT16 sNewGridNo, BOOLEAN fForceRe if ( IsJumpableFencePresentAtGridno( sNewGridNo ) ) { - //sX = MapX( sNewGridNo ); - //sY = MapY( sNewGridNo ); - //GetWorldXYAbsoluteScreenXY( sX, sY, &sWorldX, &sZLevel); - //pSoldier->sZLevelOverride = (sZLevel*Z_SUBLAYERS)+ROOF_Z_LEVEL; - pSoldier->sZLevelOverride = TOPMOST_Z_LEVEL; + //sX = MapX( sNewGridNo ); + //sY = MapY( sNewGridNo ); + //GetWorldXYAbsoluteScreenXY( sX, sY, &sWorldX, &sZLevel); + //pSoldier->sZLevelOverride = (sZLevel*Z_SUBLAYERS)+ROOF_Z_LEVEL; + pSoldier->sZLevelOverride = TOPMOST_Z_LEVEL; } @@ -2649,17 +2687,17 @@ void SetSoldierGridNo( SOLDIERTYPE *pSoldier, INT16 sNewGridNo, BOOLEAN fForceRe { fInWaterValue = MercInWater( pSoldier ); - // ATE: If ever in water MAKE SURE WE WALK AFTERWOODS! - if ( fInWaterValue ) - { - pSoldier->usUIMovementMode = WALKING; - } + // ATE: If ever in water MAKE SURE WE WALK AFTERWOODS! + if ( fInWaterValue ) + { + pSoldier->usUIMovementMode = WALKING; + } if ( fInWaterValue != pSoldier->fPrevInWater ) { //Update Animation data - SetSoldierAnimationSurface( pSoldier, pSoldier->usAnimState ); - + SetSoldierAnimationSurface( pSoldier, pSoldier->usAnimState ); + // Update flag pSoldier->fPrevInWater = fInWaterValue; @@ -2674,9 +2712,9 @@ void SetSoldierGridNo( SOLDIERTYPE *pSoldier, INT16 sNewGridNo, BOOLEAN fForceRe // with regular movement mode... EVENT_InitNewSoldierAnim( pSoldier, pSoldier->usUIMovementMode, 0 , FALSE ); } - + } - + // OK, If we were not in deep water but we are now, handle deep animations! if ( pSoldier->bOverTerrainType == DEEP_WATER && pSoldier->bOldOverTerrainType != DEEP_WATER ) @@ -2684,8 +2722,8 @@ void SetSoldierGridNo( SOLDIERTYPE *pSoldier, INT16 sNewGridNo, BOOLEAN fForceRe // Based on our current animation, change! switch( pSoldier->usAnimState ) { - case WALKING: - case RUNNING: + case WALKING: + case RUNNING: // IN deep water, swim! @@ -2713,21 +2751,21 @@ void SetSoldierGridNo( SOLDIERTYPE *pSoldier, INT16 sNewGridNo, BOOLEAN fForceRe } } - // are we now standing in tear gas without a decently working gas mask? + // are we now standing in tear gas without a decently working gas mask? if ( GetSmokeEffectOnTile( sNewGridNo, pSoldier->bLevel ) > 1 ) //lal: removed normal smoke { BOOLEAN fSetGassed = TRUE; // If we have a functioning gas mask... - if ( FindGasMask ( pSoldier ) != NO_SLOT && pSoldier->inv[ HEAD1POS ].bStatus[ 0 ] >= GASMASK_MIN_STATUS ) + if ( FindGasMask ( pSoldier ) != NO_SLOT && pSoldier->inv[ HEAD1POS ].bStatus[ 0 ] >= GASMASK_MIN_STATUS ) { fSetGassed = FALSE; } - // if ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK && pSoldier->inv[ HEAD1POS ].bStatus[ 0 ] >= GASMASK_MIN_STATUS ) + // if ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK && pSoldier->inv[ HEAD1POS ].bStatus[ 0 ] >= GASMASK_MIN_STATUS ) //{ // fSetGassed = FALSE; //} - // if ( pSoldier->inv[ HEAD2POS ].usItem == GASMASK && pSoldier->inv[ HEAD2POS ].bStatus[ 0 ] >= GASMASK_MIN_STATUS ) + // if ( pSoldier->inv[ HEAD2POS ].usItem == GASMASK && pSoldier->inv[ HEAD2POS ].bStatus[ 0 ] >= GASMASK_MIN_STATUS ) //{ // fSetGassed = FALSE; //} @@ -2738,12 +2776,12 @@ void SetSoldierGridNo( SOLDIERTYPE *pSoldier, INT16 sNewGridNo, BOOLEAN fForceRe } } - if ( pSoldier->bTeam == gbPlayerNum && pSoldier->bStealthMode ) - { + if ( pSoldier->bTeam == gbPlayerNum && pSoldier->bStealthMode ) + { // Merc got to a new tile by "sneaking". Did we theoretically sneak // past an enemy? - if ( pSoldier->bOppCnt > 0 ) // opponents in sight + if ( pSoldier->bOppCnt > 0 ) // opponents in sight { // check each possible enemy for ( cnt = 0; cnt < MAX_NUM_SOLDIERS; cnt++ ) @@ -2753,16 +2791,16 @@ void SetSoldierGridNo( SOLDIERTYPE *pSoldier, INT16 sNewGridNo, BOOLEAN fForceRe if ( pEnemy->bActive && pEnemy->bInSector && ( pEnemy->bLife >= OKLIFE ) ) { // no points for sneaking by the neutrals & friendlies!!! - if ( !pEnemy->bNeutral && ( pSoldier->bSide != pEnemy->bSide ) && (pEnemy->ubBodyType != COW && pEnemy->ubBodyType != CROW) ) + if ( !pEnemy->bNeutral && ( pSoldier->bSide != pEnemy->bSide ) && (pEnemy->ubBodyType != COW && pEnemy->ubBodyType != CROW) ) { // if we SEE this particular oppponent, and he DOESN'T see us... and he COULD see us... if ( (pSoldier->bOppList[ cnt ] == SEEN_CURRENTLY) && - pEnemy->bOppList[ pSoldier->ubID ] != SEEN_CURRENTLY && - PythSpacesAway( pSoldier->sGridNo, pEnemy->sGridNo ) < DistanceVisible( pEnemy, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, pSoldier->sGridNo, pSoldier->bLevel, pSoldier ) ) + pEnemy->bOppList[ pSoldier->ubID ] != SEEN_CURRENTLY && + PythSpacesAway( pSoldier->sGridNo, pEnemy->sGridNo ) < DistanceVisible( pEnemy, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, pSoldier->sGridNo, pSoldier->bLevel, pSoldier ) ) { - // AGILITY (5): Soldier snuck 1 square past unaware enemy - StatChange( pSoldier, AGILAMT, 5, FALSE ); - // Keep looping, we'll give'em 1 point for EACH such enemy! + // AGILITY (5): Soldier snuck 1 square past unaware enemy + StatChange( pSoldier, AGILAMT, 5, FALSE ); + // Keep looping, we'll give'em 1 point for EACH such enemy! } } } @@ -2786,7 +2824,7 @@ void EVENT_FireSoldierWeapon( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ) INT16 sTargetXPos, sTargetYPos; BOOLEAN fDoFireRightAway = FALSE; - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EVENT_FireSoldierWeapon")); + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EVENT_FireSoldierWeapon")); // CANNOT BE SAME GRIDNO! if ( pSoldier->sGridNo == sTargetGridNo ) @@ -2794,10 +2832,10 @@ void EVENT_FireSoldierWeapon( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ) return; } - if ( pSoldier->ubID == 33 ) - { - int i = 0; - } + if ( pSoldier->ubID == 33 ) + { + int i = 0; + } //switch ( pSoldier->inv[ pSoldier->ubAttackingHand ].ubGunAmmoType ) //{ @@ -2809,18 +2847,28 @@ void EVENT_FireSoldierWeapon( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ) // break; //} +#if 0 + // 0verhaul: This does not go here! In spite of this function's name, it is not the actual "fire" function. + // In fact this sets the muzzle flash even while the soldier may be turning to shoot, which can cause + // problems for real-time shooting. + + // The correct place for this is UseGun, which already has code to set or reset the flash. + if ( IsFlashSuppressor (&pSoldier->inv[ pSoldier->ubAttackingHand ], pSoldier ) ) pSoldier->fMuzzleFlash = FALSE; else pSoldier->fMuzzleFlash = TRUE; +#endif DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EVENT_FireSoldierWeapon: Muzzle flash = %d",pSoldier->fMuzzleFlash)); // Increment the number of people busy doing stuff because of an attack //if ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) ) //{ - gTacticalStatus.ubAttackBusyCount++; - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting attack, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); + // Nah, just let the animations speak for themselves + // gTacticalStatus.ubAttackBusyCount++; + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting attack, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); + DebugAttackBusy( String("!!!!!!! Starting fire weapon attack, attack count now %d\n", gTacticalStatus.ubAttackBusyCount) ); //} // Set soldier's target gridno @@ -2830,10 +2878,13 @@ void EVENT_FireSoldierWeapon( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ) //pSoldier->sLastTarget = sTargetGridNo; pSoldier->ubTargetID = WhoIsThere2( sTargetGridNo, pSoldier->bTargetLevel ); -// if (Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_GUN) +#if 0 + // if (Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_GUN) { if (pSoldier->bDoBurst) { + // This is NOT the bullets to fire. That is done as a check of bDoBurst against the weapon burst count or + // bDoAutofire, or single-fire. So let the bullet count be managed by the firing code. // Set the TOTAL number of bullets to be fired // Can't shoot more bullets than we have in our magazine! if(pSoldier->bDoAutofire) @@ -2862,8 +2913,9 @@ void EVENT_FireSoldierWeapon( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ) pSoldier->bBulletsLeft *= AmmoTypes[pSoldier->inv[ pSoldier->ubAttackingHand ].ubGunAmmoType].numberOfBullets; } } +#endif DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting attack, bullets left %d", pSoldier->bBulletsLeft) ); - + // Convert our grid-not into an XY ConvertGridNoToXY( sTargetGridNo, &sTargetXPos, &sTargetYPos ); @@ -2871,13 +2923,13 @@ void EVENT_FireSoldierWeapon( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ) // Change to fire animation // Ready weapon SoldierReadyWeapon( pSoldier, sTargetXPos, sTargetYPos, FALSE ); - + // IF WE ARE AN NPC, SLIDE VIEW TO SHOW WHO IS SHOOTING { //if ( pSoldier->fDoSpread ) //{ - // If we are spreading burst, goto right away! - //EVENT_InitNewSoldierAnim( pSoldier, SelectFireAnimation( pSoldier, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ), 0, FALSE ); + // If we are spreading burst, goto right away! + //EVENT_InitNewSoldierAnim( pSoldier, SelectFireAnimation( pSoldier, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ), 0, FALSE ); //} @@ -2899,24 +2951,24 @@ void EVENT_FireSoldierWeapon( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ) // Check if our weapon has no intermediate anim... if (Item[pSoldier->inv[ HANDPOS ].usItem].rocketlauncher || Item[pSoldier->inv[ HANDPOS ].usItem].grenadelauncher || Item[pSoldier->inv[ HANDPOS ].usItem].mortar ) - ///* switch( pSoldier->inv[ HANDPOS ].usItem ) - // { + ///* switch( pSoldier->inv[ HANDPOS ].usItem ) + // { //case RPG7: //case ROCKET_LAUNCHER: //case MORTAR: //case GLAUNCHER:*/ - fDoFireRightAway = TRUE; + fDoFireRightAway = TRUE; // break; //} if ( fDoFireRightAway ) { - // Set to true so we don't get toasted twice for APs.. - pSoldier->fDontUnsetLastTargetFromTurn = TRUE; + // Set to true so we don't get toasted twice for APs.. + pSoldier->fDontUnsetLastTargetFromTurn = TRUE; - // Make sure we don't try and do fancy prone turning..... - pSoldier->fTurningFromPronePosition = FALSE; + // Make sure we don't try and do fancy prone turning..... + pSoldier->fTurningFromPronePosition = FALSE; // Force our direction! EVENT_SetSoldierDirection( pSoldier, pSoldier->bDesiredDirection ); @@ -2949,7 +3001,7 @@ UINT16 SelectFireAnimation( SOLDIERTYPE *pSoldier, UINT8 ubHeight ) FLOAT dTargetY; FLOAT dTargetZ; BOOLEAN fDoLowShot = FALSE; - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("SelectFireAnimation")); + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("SelectFireAnimation")); //Do different things if we are a monster @@ -2957,27 +3009,27 @@ UINT16 SelectFireAnimation( SOLDIERTYPE *pSoldier, UINT8 ubHeight ) { switch( pSoldier->ubBodyType ) { - case ADULTFEMALEMONSTER: - case AM_MONSTER: - case YAF_MONSTER: - case YAM_MONSTER: + case ADULTFEMALEMONSTER: + case AM_MONSTER: + case YAF_MONSTER: + case YAM_MONSTER: - return( MONSTER_SPIT_ATTACK ); - break; + return( MONSTER_SPIT_ATTACK ); + break; - case LARVAE_MONSTER: + case LARVAE_MONSTER: - break; + break; - case INFANT_MONSTER: + case INFANT_MONSTER: - return( INFANT_ATTACK ); - break; + return( INFANT_ATTACK ); + break; - case QUEENMONSTER: + case QUEENMONSTER: - return( QUEEN_SPIT ); - break; + return( QUEEN_SPIT ); + break; } return( TRUE ); @@ -3022,119 +3074,119 @@ UINT16 SelectFireAnimation( SOLDIERTYPE *pSoldier, UINT8 ubHeight ) // Determine which animation to do...depending on stance and gun in hand... switch ( ubHeight ) { - case ANIM_STAND: + case ANIM_STAND: - usItem = pSoldier->inv[ HANDPOS ].usItem; + usItem = pSoldier->inv[ HANDPOS ].usItem; - // CHECK 2ND HAND! - if ( IsValidSecondHandShot( pSoldier ) ) + // CHECK 2ND HAND! + if ( IsValidSecondHandShot( pSoldier ) ) + { + // Increment the number of people busy doing stuff because of an attack + //gTacticalStatus.ubAttackBusyCount++; + //DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting attack with 2 guns, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); + + return( SHOOT_DUAL_STAND ); + } + else + { + // OK, while standing check distance away from target, and shoot low if we should! + sDist = PythSpacesAway( pSoldier->sGridNo, pSoldier->sTargetGridNo ); + + //ATE: OK, SEE WERE WE ARE TARGETING.... + GetTargetWorldPositions( pSoldier, pSoldier->sTargetGridNo, &dTargetX, &dTargetY, &dTargetZ ); + + //CalculateSoldierZPos( pSoldier, FIRING_POS, &dFirerZ ); + + if ( sDist <= 2 && dTargetZ <= 100 ) { - // Increment the number of people busy doing stuff because of an attack - //gTacticalStatus.ubAttackBusyCount++; - //DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting attack with 2 guns, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); - - return( SHOOT_DUAL_STAND ); + fDoLowShot = TRUE; } - else + + // ATE: Made distence away long for psitols such that they never use this.... + //if ( !(Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) + //{ + // fDoLowShot = FALSE; + //} + + // Don't do any low shots if in water + if ( MercInWater( pSoldier ) ) { - // OK, while standing check distance away from target, and shoot low if we should! - sDist = PythSpacesAway( pSoldier->sGridNo, pSoldier->sTargetGridNo ); - - //ATE: OK, SEE WERE WE ARE TARGETING.... - GetTargetWorldPositions( pSoldier, pSoldier->sTargetGridNo, &dTargetX, &dTargetY, &dTargetZ ); - - //CalculateSoldierZPos( pSoldier, FIRING_POS, &dFirerZ ); - - if ( sDist <= 2 && dTargetZ <= 100 ) - { - fDoLowShot = TRUE; - } - - // ATE: Made distence away long for psitols such that they never use this.... - //if ( !(Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) - //{ - // fDoLowShot = FALSE; - //} - - // Don't do any low shots if in water - if ( MercInWater( pSoldier ) ) - { - fDoLowShot = FALSE; - } - - - if ( pSoldier->bDoBurst > 0 ) - { - if ( fDoLowShot ) - { - return( FIRE_BURST_LOW_STAND ); - } - else - { - return( STANDING_BURST ); - } - } - else - { - if ( fDoLowShot ) - { - return( FIRE_LOW_STAND ); - } - else - { - return( SHOOT_RIFLE_STAND ); - } - } + fDoLowShot = FALSE; } - break; - case ANIM_PRONE: if ( pSoldier->bDoBurst > 0 ) { -// pSoldier->fBurstCompleted = FALSE; - return( PRONE_BURST ); - } - else - { - if ( IsValidSecondHandShot( pSoldier ) ) + if ( fDoLowShot ) { - return( SHOOT_DUAL_PRONE ); + return( FIRE_BURST_LOW_STAND ); } else { - return( SHOOT_RIFLE_PRONE ); + return( STANDING_BURST ); } } - break; + else + { + if ( fDoLowShot ) + { + return( FIRE_LOW_STAND ); + } + else + { + return( SHOOT_RIFLE_STAND ); + } + } + } + break; - case ANIM_CROUCH: + case ANIM_PRONE: + if ( pSoldier->bDoBurst > 0 ) + { + // pSoldier->fBurstCompleted = FALSE; + return( PRONE_BURST ); + } + else + { if ( IsValidSecondHandShot( pSoldier ) ) { - // Increment the number of people busy doing stuff because of an attack - //gTacticalStatus.ubAttackBusyCount++; - //DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting attack with 2 guns, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); - - return( SHOOT_DUAL_CROUCH ); + return( SHOOT_DUAL_PRONE ); } else { - if ( pSoldier->bDoBurst > 0 ) - { - // pSoldier->fBurstCompleted = FALSE; - return( CROUCHED_BURST ); - } - else - { - return( SHOOT_RIFLE_CROUCH ); - } + return( SHOOT_RIFLE_PRONE ); } - break; + } + break; - default: - AssertMsg( FALSE, String( "SelectFireAnimation: ERROR - Invalid height %d", ubHeight ) ); - break; + case ANIM_CROUCH: + + if ( IsValidSecondHandShot( pSoldier ) ) + { + // Increment the number of people busy doing stuff because of an attack + //gTacticalStatus.ubAttackBusyCount++; + //DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting attack with 2 guns, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); + + return( SHOOT_DUAL_CROUCH ); + } + else + { + if ( pSoldier->bDoBurst > 0 ) + { + // pSoldier->fBurstCompleted = FALSE; + return( CROUCHED_BURST ); + } + else + { + return( SHOOT_RIFLE_CROUCH ); + } + } + break; + + default: + AssertMsg( FALSE, String( "SelectFireAnimation: ERROR - Invalid height %d", ubHeight ) ); + break; } @@ -3149,43 +3201,43 @@ UINT16 GetMoveStateBasedOnStance( SOLDIERTYPE *pSoldier, UINT8 ubStanceHeight ) // Determine which animation to do...depending on stance and gun in hand... switch ( ubStanceHeight ) { - case ANIM_STAND: - if ( pSoldier->fUIMovementFast && !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) - { - return( RUNNING ); - } - else - { - return( WALKING ); - } - break; + case ANIM_STAND: + if ( pSoldier->fUIMovementFast && !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) + { + return( RUNNING ); + } + else + { + return( WALKING ); + } + break; - case ANIM_PRONE: - if ( pSoldier->fUIMovementFast ) - { - return( CRAWLING ); - } - else - { - return( CRAWLING ); - } - break; + case ANIM_PRONE: + if ( pSoldier->fUIMovementFast ) + { + return( CRAWLING ); + } + else + { + return( CRAWLING ); + } + break; - case ANIM_CROUCH: - if ( pSoldier->fUIMovementFast ) - { - return( SWATTING ); - } - else - { - return( SWATTING ); - } - break; + case ANIM_CROUCH: + if ( pSoldier->fUIMovementFast ) + { + return( SWATTING ); + } + else + { + return( SWATTING ); + } + break; - default: - AssertMsg( FALSE, String( "GetMoveStateBasedOnStance: ERROR - Invalid height %d", ubStanceHeight ) ); - break; + default: + AssertMsg( FALSE, String( "GetMoveStateBasedOnStance: ERROR - Invalid height %d", ubStanceHeight ) ); + break; } @@ -3200,13 +3252,13 @@ void SelectFallAnimation( SOLDIERTYPE *pSoldier ) // Determine which animation to do...depending on stance and gun in hand... switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: - EVENT_InitNewSoldierAnim( pSoldier, FLYBACK_HIT, 0 , FALSE ); - break; + case ANIM_STAND: + EVENT_InitNewSoldierAnim( pSoldier, FLYBACK_HIT, 0 , FALSE ); + break; - case ANIM_PRONE: - EVENT_InitNewSoldierAnim( pSoldier, FLYBACK_HIT, 0 , FALSE ); - break; + case ANIM_PRONE: + EVENT_InitNewSoldierAnim( pSoldier, FLYBACK_HIT, 0 , FALSE ); + break; } } @@ -3273,7 +3325,7 @@ BOOLEAN InternalSoldierReadyWeapon( SOLDIERTYPE *pSoldier, UINT8 sFacingDir, BOO UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady ) { - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("PickSoldierReadyAnimation")); + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("PickSoldierReadyAnimation")); // Invalid animation if nothing in our hands if ( pSoldier->inv[ HANDPOS ].usItem == NOTHING ) @@ -3315,43 +3367,43 @@ UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady ) switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: + case ANIM_STAND: - // CHECK 2ND HAND! - if ( IsValidSecondHandShot( pSoldier ) ) - { - return( END_DUAL_STAND ); - } - else - { - return( END_RIFLE_STAND ); - } - break; + // CHECK 2ND HAND! + if ( IsValidSecondHandShot( pSoldier ) ) + { + return( END_DUAL_STAND ); + } + else + { + return( END_RIFLE_STAND ); + } + break; - case ANIM_PRONE: + case ANIM_PRONE: - if ( IsValidSecondHandShot( pSoldier ) ) - { - return( END_DUAL_PRONE ); - } - else - { - return( END_RIFLE_PRONE ); - } - break; + if ( IsValidSecondHandShot( pSoldier ) ) + { + return( END_DUAL_PRONE ); + } + else + { + return( END_RIFLE_PRONE ); + } + break; - case ANIM_CROUCH: + case ANIM_CROUCH: - // CHECK 2ND HAND! - if ( IsValidSecondHandShot( pSoldier ) ) - { - return( END_DUAL_CROUCH ); - } - else - { - return( END_RIFLE_CROUCH ); - } - break; + // CHECK 2ND HAND! + if ( IsValidSecondHandShot( pSoldier ) ) + { + return( END_DUAL_CROUCH ); + } + else + { + return( END_RIFLE_CROUCH ); + } + break; } @@ -3367,46 +3419,46 @@ UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady ) { switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: + case ANIM_STAND: - // CHECK 2ND HAND! - if ( IsValidSecondHandShot( pSoldier ) ) - { - return( READY_DUAL_STAND ); - } - else - { - return( READY_RIFLE_STAND ); - } - break; + // CHECK 2ND HAND! + if ( IsValidSecondHandShot( pSoldier ) ) + { + return( READY_DUAL_STAND ); + } + else + { + return( READY_RIFLE_STAND ); + } + break; - case ANIM_PRONE: - // Go into crouch, turn, then go into prone again - //ChangeSoldierStance( pSoldier, ANIM_CROUCH ); - //pSoldier->ubDesiredHeight = ANIM_PRONE; - //ChangeSoldierState( pSoldier, PRONE_UP ); - if ( IsValidSecondHandShot( pSoldier ) ) - { - return( READY_DUAL_PRONE ); - } - else - { - return( READY_RIFLE_PRONE ); - } - break; + case ANIM_PRONE: + // Go into crouch, turn, then go into prone again + //ChangeSoldierStance( pSoldier, ANIM_CROUCH ); + //pSoldier->ubDesiredHeight = ANIM_PRONE; + //ChangeSoldierState( pSoldier, PRONE_UP ); + if ( IsValidSecondHandShot( pSoldier ) ) + { + return( READY_DUAL_PRONE ); + } + else + { + return( READY_RIFLE_PRONE ); + } + break; - case ANIM_CROUCH: + case ANIM_CROUCH: - // CHECK 2ND HAND! - if ( IsValidSecondHandShot( pSoldier ) ) - { - return( READY_DUAL_CROUCH ); - } - else - { - return( READY_RIFLE_CROUCH ); - } - break; + // CHECK 2ND HAND! + if ( IsValidSecondHandShot( pSoldier ) ) + { + return( READY_DUAL_CROUCH ); + } + else + { + return( READY_RIFLE_CROUCH ); + } + break; } } @@ -3417,20 +3469,24 @@ UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady ) return( INVALID_ANIMATION ); } -extern SOLDIERTYPE * FreeUpAttackerGivenTarget( UINT8 ubID, UINT8 ubTargetID ); -extern SOLDIERTYPE * ReduceAttackBusyGivenTarget( UINT8 ubID, UINT8 ubTargetID ); +// 0verhaul: These routines are obsolete. Just call ReduceAttackBusyCount to reduce the ABC or +// FreeUpAttacker to abort the current action. +// extern SOLDIERTYPE * FreeUpAttackerGivenTarget( UINT8 ubID, UINT8 ubTargetID ); +// extern SOLDIERTYPE * ReduceAttackBusyGivenTarget( UINT8 ubID, UINT8 ubTargetID ); // ATE: THIS FUNCTION IS USED FOR ALL SOLDIER TAKE DAMAGE FUNCTIONS! void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDamage, INT16 sBreathLoss, UINT16 bDirection, UINT16 sRange, UINT8 ubAttackerID, UINT8 ubSpecial, UINT8 ubHitLocation, INT16 sSubsequent, INT16 sLocationGrid ) { UINT8 ubCombinedLoss, ubVolume, ubReason; - SOLDIERTYPE * pNewSoldier; +// SOLDIERTYPE * pNewSoldier; ubReason = 0; DebugMsg(TOPIC_JA2,DBG_LEVEL_3 , "EVENT_SoldierGotHit"); +#if 0 + // 0verhaul: Under the new ABC system this is no longer necessary. // ATE: If we have gotten hit, but are still in our attack animation, reduce count! switch ( pSoldier->usAnimState ) { @@ -3446,6 +3502,7 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa ReduceAttackBusyCount( pSoldier->ubID, FALSE ); break; } +#endif // DO STUFF COMMON FOR ALL TYPES if ( ubAttackerID != NOBODY) @@ -3456,11 +3513,13 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa // Set attacker's ID pSoldier->ubAttackerID = ubAttackerID; +#if 0 + // 0verhaul: Slashing out more unnecessary and reworked code if ( !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) { - // Increment being attacked count - pSoldier->bBeingAttackedCount++; - } + // Increment being attacked count + pSoldier->bBeingAttackedCount++; + } // if defender is a vehicle, there will be no hit animation played! if ( !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) @@ -3469,6 +3528,7 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa gTacticalStatus.ubAttackBusyCount++; DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Person got hit, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); } +#endif // ATE; Save hit location info...( for later anim determination stuff ) pSoldier->ubHitLocation = ubHitLocation; @@ -3487,25 +3547,25 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa } // SWITCH IN TYPE OF WEAPON - if ( ubSpecial == FIRE_WEAPON_TOSSED_OBJECT_SPECIAL ) - { + if ( ubSpecial == FIRE_WEAPON_TOSSED_OBJECT_SPECIAL ) + { ubReason = TAKE_DAMAGE_OBJECT; - } + } else if ( Item[ usWeaponIndex ].usItemClass & IC_TENTACLES ) { ubReason = TAKE_DAMAGE_TENTACLES; } // marke take out gunfire if ammotype is explosive - - // callahan update start - // setting new func to intercept testhit + + // callahan update start + // setting new func to intercept testhit else if ( Item[ usWeaponIndex ].usItemClass & ( IC_GUN | IC_THROWING_KNIFE ) && ubAttackerID == NOBODY) { sBreathLoss += BP_GET_HIT; ubReason = TAKE_DAMAGE_GUNFIRE; } // callahan update end - + else if ( Item[ usWeaponIndex ].usItemClass & ( IC_GUN | IC_THROWING_KNIFE ) && AmmoTypes[MercPtrs[ubAttackerID]->inv[MercPtrs[ubAttackerID]->ubAttackingHand ].ubGunAmmoType].explosionSize <= 1) { if ( ubSpecial == FIRE_WEAPON_SLEEP_DART_SPECIAL ) @@ -3539,8 +3599,8 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa // will always increase counter by at least 1 pSoldier->bBlindedCounter += (sDamage / 8) + 1; - // Dirty panel - fInterfacePanelDirty = DIRTYLEVEL2; + // Dirty panel + fInterfacePanelDirty = DIRTYLEVEL2; } sBreathLoss += BP_GET_HIT; ubReason = TAKE_DAMAGE_GUNFIRE; @@ -3563,7 +3623,7 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa } ubReason = TAKE_DAMAGE_HANDTOHAND; } - // marke added one 'or' for explosive ammo. variation of: AmmoTypes[pSoldier->inv[pSoldier->ubAttackingHand ].ubGunAmmoType].explosionSize > 1 + // marke added one 'or' for explosive ammo. variation of: AmmoTypes[pSoldier->inv[pSoldier->ubAttackingHand ].ubGunAmmoType].explosionSize > 1 // extracting attacker´s ammo type else if ( Item[ usWeaponIndex ].usItemClass & IC_EXPLOSV || AmmoTypes[MercPtrs[ubAttackerID]->inv[MercPtrs[ubAttackerID]->ubAttackingHand ].ubGunAmmoType].explosionSize > 1) { @@ -3578,7 +3638,7 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa { case FIRE_WEAPON_BLINDED_AND_DEAFENED: pSoldier->bDeafenedCounter = bDeafValue; - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Soldier is blinded and deafened" ); + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Soldier is blinded and deafened" ); // if soldier in building OR underground if ( InBuilding(sLocationGrid) || (gbWorldSectorZ) ) @@ -3591,7 +3651,7 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa TacticalCharacterDialogue( pSoldier, QUOTE_BLINDED ); } } - else if ( NightTime() ) // if soldier outside at night + else if ( NightTime() ) // if soldier outside at night { // halve effect pSoldier->bBlindedCounter = (INT8)Explosive[ Item[ usWeaponIndex ].ubClassIndex ].ubDuration / 2; @@ -3631,6 +3691,8 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa } +#if 0 + // 0verhaul: None of this hairyness is necessary anymore! Hazaa! // CJC: moved to after SoldierTakeDamage so that any quotes from the defender // will not be said if they are knocked out or killed if ( ubReason != TAKE_DAMAGE_TENTACLES && ubReason != TAKE_DAMAGE_OBJECT ) @@ -3654,6 +3716,7 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa } DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Tried to free up attacker, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); } +#endif // OK, If we are a vehicle.... damage vehicle...( people inside... ) @@ -3703,13 +3766,13 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa if ( Item[ usWeaponIndex ].usItemClass & IC_BLADE ) - { - PlayJA2Sample( (UINT32)( KNIFE_IMPACT ), RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - } - else - { - PlayJA2Sample( (UINT32)( BULLET_IMPACT_1 + Random(3) ), RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - } + { + PlayJA2Sample( (UINT32)( KNIFE_IMPACT ), RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); + } + else + { + PlayJA2Sample( (UINT32)( BULLET_IMPACT_1 + Random(3) ), RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); + } // PLAY RANDOM GETTING HIT SOUND // ONLY IF WE ARE CONSCIOUS! @@ -3722,15 +3785,15 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa } else { - // ATE: This is to disallow large amounts of smaples being played which is load! - if ( pSoldier->fGettingHit && pSoldier->usAniCode != STANDING_BURST_HIT ) - { + // ATE: This is to disallow large amounts of smaples being played which is load! + if ( pSoldier->fGettingHit && pSoldier->usAniCode != STANDING_BURST_HIT ) + { - } - else - { - DoMercBattleSound( pSoldier, (INT8)( BATTLE_SOUND_HIT1 + Random( 2 ) ) ); - } + } + else + { + DoMercBattleSound( pSoldier, (INT8)( BATTLE_SOUND_HIT1 + Random( 2 ) ) ); + } } } @@ -3739,56 +3802,56 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa { switch( pSoldier->usAnimState ) { - case FLYBACKHIT_STOP: - ChangeSoldierState( pSoldier, FALLBACK_DEATHTWICH, 0, FALSE ); - break; + case FLYBACKHIT_STOP: + ChangeSoldierState( pSoldier, FALLBACK_DEATHTWICH, 0, FALSE ); + break; - case STAND_FALLFORWARD_STOP: - ChangeSoldierState( pSoldier, GENERIC_HIT_DEATHTWITCHNB, 0, FALSE ); - break; + case STAND_FALLFORWARD_STOP: + ChangeSoldierState( pSoldier, GENERIC_HIT_DEATHTWITCHNB, 0, FALSE ); + break; - case JFK_HITDEATH_STOP: - ChangeSoldierState( pSoldier, JFK_HITDEATH_TWITCHB, 0, FALSE ); - break; + case JFK_HITDEATH_STOP: + ChangeSoldierState( pSoldier, JFK_HITDEATH_TWITCHB, 0, FALSE ); + break; - case FALLBACKHIT_STOP: - ChangeSoldierState( pSoldier, FALLBACK_HIT_DEATHTWITCHNB, 0, FALSE ); - break; + case FALLBACKHIT_STOP: + ChangeSoldierState( pSoldier, FALLBACK_HIT_DEATHTWITCHNB, 0, FALSE ); + break; - case PRONE_LAYFROMHIT_STOP: - ChangeSoldierState( pSoldier, PRONE_HIT_DEATHTWITCHNB, 0, FALSE ); - break; + case PRONE_LAYFROMHIT_STOP: + ChangeSoldierState( pSoldier, PRONE_HIT_DEATHTWITCHNB, 0, FALSE ); + break; - case PRONE_HITDEATH_STOP: - ChangeSoldierState( pSoldier, PRONE_HIT_DEATHTWITCHB, 0 , FALSE ); - break; + case PRONE_HITDEATH_STOP: + ChangeSoldierState( pSoldier, PRONE_HIT_DEATHTWITCHB, 0 , FALSE ); + break; - case FALLFORWARD_HITDEATH_STOP: - ChangeSoldierState( pSoldier, GENERIC_HIT_DEATHTWITCHB, 0 , FALSE ); - break; + case FALLFORWARD_HITDEATH_STOP: + ChangeSoldierState( pSoldier, GENERIC_HIT_DEATHTWITCHB, 0 , FALSE ); + break; - case FALLBACK_HITDEATH_STOP: - ChangeSoldierState( pSoldier, FALLBACK_HIT_DEATHTWITCHB, 0 , FALSE ); - break; + case FALLBACK_HITDEATH_STOP: + ChangeSoldierState( pSoldier, FALLBACK_HIT_DEATHTWITCHB, 0 , FALSE ); + break; - case FALLOFF_DEATH_STOP: - ChangeSoldierState( pSoldier, FALLOFF_TWITCHB, 0 , FALSE ); - break; + case FALLOFF_DEATH_STOP: + ChangeSoldierState( pSoldier, FALLOFF_TWITCHB, 0 , FALSE ); + break; - case FALLOFF_STOP: - ChangeSoldierState( pSoldier, FALLOFF_TWITCHNB, 0 , FALSE ); - break; + case FALLOFF_STOP: + ChangeSoldierState( pSoldier, FALLOFF_TWITCHNB, 0 , FALSE ); + break; - case FALLOFF_FORWARD_DEATH_STOP: - ChangeSoldierState( pSoldier, FALLOFF_FORWARD_TWITCHB, 0 , FALSE ); - break; + case FALLOFF_FORWARD_DEATH_STOP: + ChangeSoldierState( pSoldier, FALLOFF_FORWARD_TWITCHB, 0 , FALSE ); + break; - case FALLOFF_FORWARD_STOP: - ChangeSoldierState( pSoldier, FALLOFF_FORWARD_TWITCHNB, 0 , FALSE ); - break; - - default: - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Soldier Control: Death state %d has no death hit", pSoldier->usAnimState ) ); + case FALLOFF_FORWARD_STOP: + ChangeSoldierState( pSoldier, FALLOFF_FORWARD_TWITCHNB, 0 , FALSE ); + break; + + default: + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Soldier Control: Death state %d has no death hit", pSoldier->usAnimState ) ); } return; @@ -3818,98 +3881,98 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa // Change based on body type switch( pSoldier->ubBodyType ) { - case COW: - EVENT_InitNewSoldierAnim( pSoldier, COW_HIT, 0 , FALSE ); - return; - break; + case COW: + EVENT_InitNewSoldierAnim( pSoldier, COW_HIT, 0 , FALSE ); + return; + break; - case BLOODCAT: - EVENT_InitNewSoldierAnim( pSoldier, BLOODCAT_HIT, 0 , FALSE ); - return; - break; + case BLOODCAT: + EVENT_InitNewSoldierAnim( pSoldier, BLOODCAT_HIT, 0 , FALSE ); + return; + break; - case ADULTFEMALEMONSTER: - case AM_MONSTER: - case YAF_MONSTER: - case YAM_MONSTER: + case ADULTFEMALEMONSTER: + case AM_MONSTER: + case YAF_MONSTER: + case YAM_MONSTER: - EVENT_InitNewSoldierAnim( pSoldier, ADULTMONSTER_HIT, 0 , FALSE ); - return; - break; + EVENT_InitNewSoldierAnim( pSoldier, ADULTMONSTER_HIT, 0 , FALSE ); + return; + break; - case LARVAE_MONSTER: - EVENT_InitNewSoldierAnim( pSoldier, LARVAE_HIT, 0 , FALSE ); - return; - break; + case LARVAE_MONSTER: + EVENT_InitNewSoldierAnim( pSoldier, LARVAE_HIT, 0 , FALSE ); + return; + break; - case QUEENMONSTER: - EVENT_InitNewSoldierAnim( pSoldier, QUEEN_HIT, 0 , FALSE ); - return; - break; + case QUEENMONSTER: + EVENT_InitNewSoldierAnim( pSoldier, QUEEN_HIT, 0 , FALSE ); + return; + break; - case CRIPPLECIV: + case CRIPPLECIV: - { - // OK, do some code here to allow the fact that poor buddy can be thrown back if it's a big enough hit... - EVENT_InitNewSoldierAnim( pSoldier, CRIPPLE_HIT, 0 , FALSE ); + { + // OK, do some code here to allow the fact that poor buddy can be thrown back if it's a big enough hit... + EVENT_InitNewSoldierAnim( pSoldier, CRIPPLE_HIT, 0 , FALSE ); - //pSoldier->bLife = 0; - //EVENT_InitNewSoldierAnim( pSoldier, CRIPPLE_DIE_FLYBACK, 0 , FALSE ); + //pSoldier->bLife = 0; + //EVENT_InitNewSoldierAnim( pSoldier, CRIPPLE_DIE_FLYBACK, 0 , FALSE ); - } - return; - break; + } + return; + break; - case ROBOTNOWEAPON: - EVENT_InitNewSoldierAnim( pSoldier, ROBOTNW_HIT, 0 , FALSE ); - return; - break; + case ROBOTNOWEAPON: + EVENT_InitNewSoldierAnim( pSoldier, ROBOTNW_HIT, 0 , FALSE ); + return; + break; - case INFANT_MONSTER: - EVENT_InitNewSoldierAnim( pSoldier, INFANT_HIT, 0 , FALSE ); - return; + case INFANT_MONSTER: + EVENT_InitNewSoldierAnim( pSoldier, INFANT_HIT, 0 , FALSE ); + return; - case CROW: + case CROW: - EVENT_InitNewSoldierAnim( pSoldier, CROW_DIE, 0 , FALSE ); - return; + EVENT_InitNewSoldierAnim( pSoldier, CROW_DIE, 0 , FALSE ); + return; //case FATCIV: - case MANCIV: - case MINICIV: - case DRESSCIV: - case HATKIDCIV: - case KIDCIV: - - // OK, if life is 0 and not set as dead ( this is a death hit... ) - if ( !( pSoldier->uiStatusFlags & SOLDIER_DEAD ) && pSoldier->bLife == 0 ) - { - // Randomize death! - if ( Random( 2 ) ) - { - EVENT_InitNewSoldierAnim( pSoldier, CIV_DIE2, 0 , FALSE ); - return; - } - } + case MANCIV: + case MINICIV: + case DRESSCIV: + case HATKIDCIV: + case KIDCIV: - // IF here, go generic hit ALWAYS..... - EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_STAND, 0 , FALSE ); - return; - break; + // OK, if life is 0 and not set as dead ( this is a death hit... ) + if ( !( pSoldier->uiStatusFlags & SOLDIER_DEAD ) && pSoldier->bLife == 0 ) + { + // Randomize death! + if ( Random( 2 ) ) + { + EVENT_InitNewSoldierAnim( pSoldier, CIV_DIE2, 0 , FALSE ); + return; + } + } + + // IF here, go generic hit ALWAYS..... + EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_STAND, 0 , FALSE ); + return; + break; } // If here, we are a merc, check if we are in water if ( pSoldier->bOverTerrainType == LOW_WATER ) { - EVENT_InitNewSoldierAnim( pSoldier, WATER_HIT, 0 , FALSE ); - return; + EVENT_InitNewSoldierAnim( pSoldier, WATER_HIT, 0 , FALSE ); + return; } if ( pSoldier->bOverTerrainType == DEEP_WATER ) { - EVENT_InitNewSoldierAnim( pSoldier, DEEP_WATER_HIT, 0 , FALSE ); - return; + EVENT_InitNewSoldierAnim( pSoldier, DEEP_WATER_HIT, 0 , FALSE ); + return; } @@ -3922,7 +3985,7 @@ void EVENT_SoldierGotHit( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDa { SoldierGotHitBlade( pSoldier, usWeaponIndex, sDamage, bDirection, sRange, ubAttackerID, ubSpecial, ubHitLocation ); } - // marke setting ammo explosions included here with 3rd 'or' including ubReason + // marke setting ammo explosions included here with 3rd 'or' including ubReason if ( Item[ usWeaponIndex ].usItemClass & IC_EXPLOSV || Item[ usWeaponIndex ].usItemClass & IC_TENTACLES || ubReason == TAKE_DAMAGE_EXPLOSION ) { SoldierGotHitExplosion( pSoldier, usWeaponIndex, sDamage, bDirection, sRange, ubAttackerID, ubSpecial, ubHitLocation ); @@ -3956,15 +4019,15 @@ UINT8 CalcScreamVolume( SOLDIERTYPE * pSoldier, UINT8 ubCombinedLoss ) ubVolume = 10 - EffectiveExpLevel( pSoldier ); } -/* - // the "Speck factor"... He's a whiner, and extra-sensitive to pain! - if (ptr->trait == NERVOUS) - ubVolume += 2; -*/ + /* + // the "Speck factor"... He's a whiner, and extra-sensitive to pain! + if (ptr->trait == NERVOUS) + ubVolume += 2; + */ if (ubVolume < 0) { - ubVolume = 0; + ubVolume = 0; } return( ubVolume ); @@ -3973,43 +4036,43 @@ UINT8 CalcScreamVolume( SOLDIERTYPE * pSoldier, UINT8 ubCombinedLoss ) void DoGenericHit( SOLDIERTYPE *pSoldier, UINT8 ubSpecial, INT16 bDirection ) { - // Based on stance, select generic hit animation + // Based on stance, select generic hit animation switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: - // For now, check if we are affected by a burst - // For now, if the weapon was a gun, special 1 == burst - // ATE: Only do this for mercs! - if ( ubSpecial == FIRE_WEAPON_BURST_SPECIAL && pSoldier->ubBodyType <= REGFEMALE ) - { - //SetSoldierDesiredDirection( pSoldier, bDirection ); - EVENT_SetSoldierDirection( pSoldier, (INT8)bDirection ); - EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); + case ANIM_STAND: + // For now, check if we are affected by a burst + // For now, if the weapon was a gun, special 1 == burst + // ATE: Only do this for mercs! + if ( ubSpecial == FIRE_WEAPON_BURST_SPECIAL && pSoldier->ubBodyType <= REGFEMALE ) + { + //SetSoldierDesiredDirection( pSoldier, bDirection ); + EVENT_SetSoldierDirection( pSoldier, (INT8)bDirection ); + EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); - EVENT_InitNewSoldierAnim( pSoldier, STANDING_BURST_HIT, 0 , FALSE ); + EVENT_InitNewSoldierAnim( pSoldier, STANDING_BURST_HIT, 0 , FALSE ); + } + else + { + // Check in hand for rifle + if ( SoldierCarriesTwoHandedWeapon( pSoldier ) ) + { + EVENT_InitNewSoldierAnim( pSoldier, RIFLE_STAND_HIT, 0 , FALSE ); } else { - // Check in hand for rifle - if ( SoldierCarriesTwoHandedWeapon( pSoldier ) ) - { - EVENT_InitNewSoldierAnim( pSoldier, RIFLE_STAND_HIT, 0 , FALSE ); - } - else - { - EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_STAND, 0 , FALSE ); - } + EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_STAND, 0 , FALSE ); } - break; + } + break; - case ANIM_PRONE: + case ANIM_PRONE: - EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_PRONE, 0 , FALSE ); - break; + EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_PRONE, 0 , FALSE ); + break; - case ANIM_CROUCH: - EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_CROUCH, 0 , FALSE ); - break; + case ANIM_CROUCH: + EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_CROUCH, 0 , FALSE ); + break; } } @@ -4021,7 +4084,7 @@ void SoldierGotHitGunFire( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sD BOOLEAN fBlownAway = FALSE; BOOLEAN fHeadHit = FALSE; BOOLEAN fFallenOver = FALSE; - + // MAYBE CHANGE TO SPECIAL ANIMATION BASED ON VALUE SET BY DAMAGE CALCULATION CODE // ALL THESE ONLY WORK ON STANDING PEOPLE if (!(pSoldier->uiStatusFlags & SOLDIER_MONSTER) && gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND) @@ -4094,8 +4157,9 @@ void SoldierGotHitGunFire( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sD // IF HERE AND GUY IS DEAD, RETURN! if ( pSoldier->uiStatusFlags & SOLDIER_DEAD ) { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker,Dead soldier hit" ) ); - ReleaseSoldiersAttacker( pSoldier ); + // 0verhaul: Handled in the soldier state change code + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker,Dead soldier hit" ) ); + // ReleaseSoldiersAttacker( pSoldier ); return; } @@ -4125,14 +4189,14 @@ void SoldierGotHitGunFire( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sD } } - DoGenericHit( pSoldier, ubSpecial, bDirection ); + DoGenericHit( pSoldier, ubSpecial, bDirection ); } void SoldierGotHitExplosion( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDamage, UINT16 bDirection, UINT16 sRange, UINT8 ubAttackerID, UINT8 ubSpecial, UINT8 ubHitLocation ) { INT16 sNewGridNo; - + // IF HERE AND GUY IS DEAD, RETURN! if ( pSoldier->uiStatusFlags & SOLDIER_DEAD ) { @@ -4165,12 +4229,12 @@ void SoldierGotHitExplosion( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 } } - // If we can't fal back or such, so generic hit... + // If we can't fal back or such, so generic hit... if ( pSoldier->ubBodyType >= 4 ) { - DoGenericHit( pSoldier, 0, bDirection ); - return; - } + DoGenericHit( pSoldier, 0, bDirection ); + return; + } // Lesh: possible soldier behavior when affected by flashbang // Soldier can: @@ -4184,114 +4248,114 @@ void SoldierGotHitExplosion( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 // Based on stance, select generic hit animation switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: - if ( ubSpecial == FIRE_WEAPON_DEAFENED ) + case ANIM_STAND: + if ( ubSpecial == FIRE_WEAPON_DEAFENED ) + { + switch( Random(10) ) { - switch( Random(10) ) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - // 6 of 10 - crouch - ChangeSoldierStance( pSoldier, ANIM_CROUCH ); - break; - case 6: - case 7: - case 8: - // 3 of 10 - fall forward - BeginTyingToFall( pSoldier ); - EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0, FALSE ); - break; - case 9: - // 1 of 10 - still standing - DoGenericHit( pSoldier, 0, bDirection ); - break; - }; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + // 6 of 10 - crouch + ChangeSoldierStance( pSoldier, ANIM_CROUCH ); break; - } - else if ( ubSpecial == FIRE_WEAPON_BLINDED_AND_DEAFENED ) - { - switch( Random(10) ) - { - case 0: - case 1: - case 2: - case 3: - case 4: - // 5 of 10 - crouch - ChangeSoldierStance( pSoldier, ANIM_CROUCH ); - break; - case 5: - case 6: - case 7: - case 8: - // 4 of 10 - fall backward (if possible) either forward - // Check behind us! - sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( gOppositeDirection[ bDirection ] ) ); - if ( OKFallDirection( pSoldier, sNewGridNo, pSoldier->bLevel, gOppositeDirection[ bDirection ], FLYBACK_HIT ) ) - { - EVENT_SetSoldierDirection( pSoldier, (INT8)bDirection ); - EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); - ChangeToFallbackAnimation( pSoldier, (INT8)bDirection ); - } - else - { - BeginTyingToFall( pSoldier ); - EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0, FALSE ); - } - break; - case 9: - // 1 of 10 - still standing - DoGenericHit( pSoldier, 0, bDirection ); - break; - }; + case 6: + case 7: + case 8: + // 3 of 10 - fall forward + BeginTyingToFall( pSoldier ); + EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0, FALSE ); break; - } - else if ( ubSpecial == FIRE_WEAPON_BLINDED ) - { - } - - case ANIM_CROUCH: - - if ( ubSpecial == FIRE_WEAPON_BLINDED || - ubSpecial == FIRE_WEAPON_BLINDED_AND_DEAFENED || - ubSpecial == FIRE_WEAPON_DEAFENED ) - { + case 9: + // 1 of 10 - still standing DoGenericHit( pSoldier, 0, bDirection ); break; - } - - EVENT_SetSoldierDirection( pSoldier, (INT8)bDirection ); - EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); - - // Check behind us! - sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( gOppositeDirection[ bDirection ] ) ); - - if ( OKFallDirection( pSoldier, sNewGridNo, pSoldier->bLevel, gOppositeDirection[ bDirection ], FLYBACK_HIT ) ) + }; + break; + } + else if ( ubSpecial == FIRE_WEAPON_BLINDED_AND_DEAFENED ) + { + switch( Random(10) ) { - ChangeToFallbackAnimation( pSoldier, (INT8)bDirection ); - } - else - { - if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND ) + case 0: + case 1: + case 2: + case 3: + case 4: + // 5 of 10 - crouch + ChangeSoldierStance( pSoldier, ANIM_CROUCH ); + break; + case 5: + case 6: + case 7: + case 8: + // 4 of 10 - fall backward (if possible) either forward + // Check behind us! + sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( gOppositeDirection[ bDirection ] ) ); + if ( OKFallDirection( pSoldier, sNewGridNo, pSoldier->bLevel, gOppositeDirection[ bDirection ], FLYBACK_HIT ) ) { - BeginTyingToFall( pSoldier ); - EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0, FALSE ); + EVENT_SetSoldierDirection( pSoldier, (INT8)bDirection ); + EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); + ChangeToFallbackAnimation( pSoldier, (INT8)bDirection ); } else { - SoldierCollapse( pSoldier ); + BeginTyingToFall( pSoldier ); + EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0, FALSE ); } + break; + case 9: + // 1 of 10 - still standing + DoGenericHit( pSoldier, 0, bDirection ); + break; + }; + break; + } + else if ( ubSpecial == FIRE_WEAPON_BLINDED ) + { + } + + case ANIM_CROUCH: + + if ( ubSpecial == FIRE_WEAPON_BLINDED || + ubSpecial == FIRE_WEAPON_BLINDED_AND_DEAFENED || + ubSpecial == FIRE_WEAPON_DEAFENED ) + { + DoGenericHit( pSoldier, 0, bDirection ); + break; + } + + EVENT_SetSoldierDirection( pSoldier, (INT8)bDirection ); + EVENT_SetSoldierDesiredDirection( pSoldier, pSoldier->bDirection ); + + // Check behind us! + sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( gOppositeDirection[ bDirection ] ) ); + + if ( OKFallDirection( pSoldier, sNewGridNo, pSoldier->bLevel, gOppositeDirection[ bDirection ], FLYBACK_HIT ) ) + { + ChangeToFallbackAnimation( pSoldier, (INT8)bDirection ); + } + else + { + if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND ) + { + BeginTyingToFall( pSoldier ); + EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0, FALSE ); } - break; + else + { + SoldierCollapse( pSoldier ); + } + } + break; - case ANIM_PRONE: + case ANIM_PRONE: - SoldierCollapse( pSoldier ); - break; + SoldierCollapse( pSoldier ); + break; } } @@ -4299,7 +4363,7 @@ void SoldierGotHitExplosion( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 void SoldierGotHitBlade( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDamage, UINT16 bDirection, UINT16 sRange, UINT8 ubAttackerID, UINT8 ubSpecial, UINT8 ubHitLocation ) { - + // IF HERE AND GUY IS DEAD, RETURN! if ( pSoldier->uiStatusFlags & SOLDIER_DEAD ) { @@ -4310,26 +4374,26 @@ void SoldierGotHitBlade( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDam // Based on stance, select generic hit animation switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: + case ANIM_STAND: - // Check in hand for rifle - if ( SoldierCarriesTwoHandedWeapon( pSoldier ) ) - { - EVENT_InitNewSoldierAnim( pSoldier, RIFLE_STAND_HIT, 0 , FALSE ); - } - else - { - EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_STAND, 0 , FALSE ); - } - break; + // Check in hand for rifle + if ( SoldierCarriesTwoHandedWeapon( pSoldier ) ) + { + EVENT_InitNewSoldierAnim( pSoldier, RIFLE_STAND_HIT, 0 , FALSE ); + } + else + { + EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_STAND, 0 , FALSE ); + } + break; - case ANIM_CROUCH: - EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_CROUCH, 0 , FALSE ); - break; + case ANIM_CROUCH: + EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_CROUCH, 0 , FALSE ); + break; - case ANIM_PRONE: - EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_PRONE, 0 , FALSE ); - break; + case ANIM_PRONE: + EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_PRONE, 0 , FALSE ); + break; } } @@ -4337,7 +4401,7 @@ void SoldierGotHitBlade( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDam void SoldierGotHitPunch( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDamage, UINT16 bDirection, UINT16 sRange, UINT8 ubAttackerID, UINT8 ubSpecial, UINT8 ubHitLocation ) { - + // IF HERE AND GUY IS DEAD, RETURN! if ( pSoldier->uiStatusFlags & SOLDIER_DEAD ) { @@ -4347,25 +4411,25 @@ void SoldierGotHitPunch( SOLDIERTYPE *pSoldier, UINT16 usWeaponIndex, INT16 sDam // Based on stance, select generic hit animation switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: - // Check in hand for rifle - if ( SoldierCarriesTwoHandedWeapon( pSoldier ) ) - { - EVENT_InitNewSoldierAnim( pSoldier, RIFLE_STAND_HIT, 0 , FALSE ); - } - else - { - EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_STAND, 0 , FALSE ); - } - break; + case ANIM_STAND: + // Check in hand for rifle + if ( SoldierCarriesTwoHandedWeapon( pSoldier ) ) + { + EVENT_InitNewSoldierAnim( pSoldier, RIFLE_STAND_HIT, 0 , FALSE ); + } + else + { + EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_STAND, 0 , FALSE ); + } + break; - case ANIM_CROUCH: - EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_CROUCH, 0 , FALSE ); - break; + case ANIM_CROUCH: + EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_CROUCH, 0 , FALSE ); + break; - case ANIM_PRONE: - EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_PRONE, 0 , FALSE ); - break; + case ANIM_PRONE: + EVENT_InitNewSoldierAnim( pSoldier, GENERIC_HIT_PRONE, 0 , FALSE ); + break; } @@ -4405,7 +4469,7 @@ BOOLEAN EVENT_InternalGetNewSoldierPath( SOLDIERTYPE *pSoldier, UINT16 sDestGrid if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) { SetSoldierCowerState( pSoldier, FALSE ); - usMoveAnimState = WALKING; + usMoveAnimState = WALKING; } } @@ -4548,7 +4612,7 @@ BOOLEAN EVENT_InternalGetNewSoldierPath( SOLDIERTYPE *pSoldier, UINT16 sDestGrid } // Change desired direction - // ATE: Here we have a situation where in RT, we may have + // ATE: Here we have a situation where in RT, we may have // gotten a new path, but we are alreayd moving.. so // at leasty change new dest. This will be redundent if the ANI is a totaly new one @@ -4615,35 +4679,35 @@ void SoldierGotoStationaryStance( SOLDIERTYPE *pSoldier ) // Change state back to stationary state for given height switch( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: + case ANIM_STAND: - // If we are cowering....goto cower state - if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) - { - EVENT_InitNewSoldierAnim( pSoldier, START_COWER, 0 , FALSE ); - } - else - { - EVENT_InitNewSoldierAnim( pSoldier, STANDING, 0 , FALSE ); - } - break; + // If we are cowering....goto cower state + if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) + { + EVENT_InitNewSoldierAnim( pSoldier, START_COWER, 0 , FALSE ); + } + else + { + EVENT_InitNewSoldierAnim( pSoldier, STANDING, 0 , FALSE ); + } + break; - case ANIM_CROUCH: + case ANIM_CROUCH: - // If we are cowering....goto cower state - if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) - { - EVENT_InitNewSoldierAnim( pSoldier, COWERING, 0 , FALSE ); - } - else - { - EVENT_InitNewSoldierAnim( pSoldier, CROUCHING, 0 , FALSE ); - } - break; + // If we are cowering....goto cower state + if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) + { + EVENT_InitNewSoldierAnim( pSoldier, COWERING, 0 , FALSE ); + } + else + { + EVENT_InitNewSoldierAnim( pSoldier, CROUCHING, 0 , FALSE ); + } + break; - case ANIM_PRONE: - EVENT_InitNewSoldierAnim( pSoldier, PRONE, 0 , FALSE ); - break; + case ANIM_PRONE: + EVENT_InitNewSoldierAnim( pSoldier, PRONE, 0 , FALSE ); + break; } } @@ -4687,8 +4751,8 @@ void ChangeSoldierStance( SOLDIERTYPE *pSoldier, UINT8 ubDesiredStance ) // Now change to appropriate animation EVENT_InitNewSoldierAnim( pSoldier, usNewState, 0 , FALSE ); + } } -} void EVENT_InternalSetSoldierDestination( SOLDIERTYPE *pSoldier, UINT16 usNewDirection, BOOLEAN fFromMove, UINT16 usAnimState ) { @@ -4847,19 +4911,19 @@ void EVENT_InternalSetSoldierDesiredDirection( SOLDIERTYPE *pSoldier, UINT16 usN switch( gAnimControl[ usAnimState ].ubEndHeight ) { // Now change to appropriate animation - case ANIM_STAND: - DeductPoints( pSoldier, AP_LOOK_STANDING, 0 ); - break; + case ANIM_STAND: + DeductPoints( pSoldier, AP_LOOK_STANDING, 0 ); + break; - case ANIM_CROUCH: - DeductPoints( pSoldier, AP_LOOK_CROUCHED, 0 ); - break; + case ANIM_CROUCH: + DeductPoints( pSoldier, AP_LOOK_CROUCHED, 0 ); + break; - case ANIM_PRONE: - DeductPoints( pSoldier, AP_LOOK_PRONE, 0 ); - break; + case ANIM_PRONE: + DeductPoints( pSoldier, AP_LOOK_PRONE, 0 ); + break; } - + } pSoldier->fDontChargeTurningAPs = FALSE; @@ -4933,42 +4997,42 @@ void EVENT_SetSoldierDesiredDirection( SOLDIERTYPE *pSoldier, UINT16 usNewDirect void EVENT_SetSoldierDirection( SOLDIERTYPE *pSoldier, UINT16 usNewDirection ) { - // Remove old location data - HandleAnimationProfile( pSoldier, pSoldier->usAnimState, TRUE ); + // Remove old location data + HandleAnimationProfile( pSoldier, pSoldier->usAnimState, TRUE ); - pSoldier->bDirection = (INT8)usNewDirection; + pSoldier->bDirection = (INT8)usNewDirection; - // Updated extended direction..... - pSoldier->ubHiResDirection = ubExtDirection[ pSoldier->bDirection ]; - - // Add new stuff - HandleAnimationProfile( pSoldier, pSoldier->usAnimState, FALSE ); + // Updated extended direction..... + pSoldier->ubHiResDirection = ubExtDirection[ pSoldier->bDirection ]; - // If we are turning, we have chaanged our aim! - if ( !pSoldier->fDontUnsetLastTargetFromTurn ) - { - pSoldier->sLastTarget = NOWHERE; - } + // Add new stuff + HandleAnimationProfile( pSoldier, pSoldier->usAnimState, FALSE ); - AdjustForFastTurnAnimation( pSoldier ); + // If we are turning, we have chaanged our aim! + if ( !pSoldier->fDontUnsetLastTargetFromTurn ) + { + pSoldier->sLastTarget = NOWHERE; + } - // Update structure info! -// if ( pSoldier->uiStatusFlags & SOLDIER_MULTITILE ) - { - UpdateMercStructureInfo( pSoldier ); - } + AdjustForFastTurnAnimation( pSoldier ); - // Handle Profile data for hit locations - HandleAnimationProfile( pSoldier, pSoldier->usAnimState, TRUE ); + // Update structure info! + // if ( pSoldier->uiStatusFlags & SOLDIER_MULTITILE ) + { + UpdateMercStructureInfo( pSoldier ); + } - HandleCrowShadowNewDirection( pSoldier ); - - // Change values! - SetSoldierLocatorOffsets( pSoldier ); + // Handle Profile data for hit locations + HandleAnimationProfile( pSoldier, pSoldier->usAnimState, TRUE ); + + HandleCrowShadowNewDirection( pSoldier ); + + // Change values! + SetSoldierLocatorOffsets( pSoldier ); } - - + + void EVENT_BeginMercTurn( SOLDIERTYPE *pSoldier, BOOLEAN fFromRealTime, INT32 iRealTimeCounter ) { // NB realtimecounter is not used, always passed in as 0 now! @@ -5014,15 +5078,15 @@ void EVENT_BeginMercTurn( SOLDIERTYPE *pSoldier, BOOLEAN fFromRealTime, INT32 iR } } - // survived bleeding, but is he out of breath? - if ( pSoldier->bLife && !pSoldier->bBreath && MercInWater( pSoldier ) ) + // survived bleeding, but is he out of breath? + if ( pSoldier->bLife && !pSoldier->bBreath && MercInWater( pSoldier ) ) { // Drowning... } - // if he is still alive (didn't bleed to death) - if ( pSoldier->bLife ) - { + // if he is still alive (didn't bleed to death) + if ( pSoldier->bLife ) + { // reduce the effects of any residual shock from past injuries by half pSoldier->bShock /= 2; @@ -5040,19 +5104,19 @@ void EVENT_BeginMercTurn( SOLDIERTYPE *pSoldier, BOOLEAN fFromRealTime, INT32 iR } } - // save unused action points up to a maximum - /* - if ((savedPts = pSoldier->bActionPts) > MAX_AP_CARRIED) - savedPts = MAX_AP_CARRIED; - */ + // save unused action points up to a maximum + /* + if ((savedPts = pSoldier->bActionPts) > MAX_AP_CARRIED) + savedPts = MAX_AP_CARRIED; + */ if ( pSoldier->uiStatusFlags & SOLDIER_GASSED ) { - // then must get a gas mask or leave the gassed area to get over it -// if ( ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK || pSoldier->inv[ HEAD2POS ].usItem == GASMASK ) || !( GetSmokeEffectOnTile( pSoldier->sGridNo, pSoldier->bLevel ) ) ) - if ( FindGasMask( pSoldier ) != NO_SLOT || !( GetSmokeEffectOnTile( pSoldier->sGridNo, pSoldier->bLevel ) ) ) - { - // Turn off gassed flag.... - pSoldier->uiStatusFlags &= (~SOLDIER_GASSED ); + // then must get a gas mask or leave the gassed area to get over it + // if ( ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK || pSoldier->inv[ HEAD2POS ].usItem == GASMASK ) || !( GetSmokeEffectOnTile( pSoldier->sGridNo, pSoldier->bLevel ) ) ) + if ( FindGasMask( pSoldier ) != NO_SLOT || !( GetSmokeEffectOnTile( pSoldier->sGridNo, pSoldier->bLevel ) ) ) + { + // Turn off gassed flag.... + pSoldier->uiStatusFlags &= (~SOLDIER_GASSED ); } } @@ -5063,8 +5127,8 @@ void EVENT_BeginMercTurn( SOLDIERTYPE *pSoldier, BOOLEAN fFromRealTime, INT32 iR { // we can SEE!!!!! HandleSight( pSoldier, SIGHT_LOOK ); - // Dirty panel - fInterfacePanelDirty = DIRTYLEVEL2; + // Dirty panel + fInterfacePanelDirty = DIRTYLEVEL2; } } @@ -5082,7 +5146,7 @@ void EVENT_BeginMercTurn( SOLDIERTYPE *pSoldier, BOOLEAN fFromRealTime, INT32 iR pSoldier->sWeightCarriedAtTurnStart = (INT16) CalculateCarriedWeight( pSoldier ); UnusedAPsToBreath( pSoldier ); - + // Set flag back to normal, after reaching a certain statge if ( pSoldier->bBreath > 80 ) { @@ -5128,53 +5192,53 @@ void EVENT_BeginMercTurn( SOLDIERTYPE *pSoldier, BOOLEAN fFromRealTime, INT32 iR { switch( gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait ) { - case FEAR_OF_INSECTS: - if ( MercSeesCreature( pSoldier ) ) + case FEAR_OF_INSECTS: + if ( MercSeesCreature( pSoldier ) ) + { + HandleMoraleEvent( pSoldier, MORALE_INSECT_PHOBIC_SEES_CREATURE, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); + if ( !(pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_PERSONALITY) ) { - HandleMoraleEvent( pSoldier, MORALE_INSECT_PHOBIC_SEES_CREATURE, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); - if ( !(pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_PERSONALITY) ) - { - TacticalCharacterDialogue( pSoldier, QUOTE_PERSONALITY_TRAIT ); - pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY; - } + TacticalCharacterDialogue( pSoldier, QUOTE_PERSONALITY_TRAIT ); + pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY; } - break; - case CLAUSTROPHOBIC: - if ( gbWorldSectorZ > 0 && Random( 6 - gbWorldSectorZ ) == 0 ) + } + break; + case CLAUSTROPHOBIC: + if ( gbWorldSectorZ > 0 && Random( 6 - gbWorldSectorZ ) == 0 ) + { + // underground! + HandleMoraleEvent( pSoldier, MORALE_CLAUSTROPHOBE_UNDERGROUND, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); + if ( !(pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_PERSONALITY) ) { - // underground! - HandleMoraleEvent( pSoldier, MORALE_CLAUSTROPHOBE_UNDERGROUND, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); - if ( !(pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_PERSONALITY) ) - { - TacticalCharacterDialogue( pSoldier, QUOTE_PERSONALITY_TRAIT ); - pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY; - } + TacticalCharacterDialogue( pSoldier, QUOTE_PERSONALITY_TRAIT ); + pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY; + } - } - break; - case NERVOUS: - if ( DistanceToClosestFriend( pSoldier ) > NERVOUS_RADIUS ) + } + break; + case NERVOUS: + if ( DistanceToClosestFriend( pSoldier ) > NERVOUS_RADIUS ) + { + // augh!! + if ( pSoldier->bMorale < 50 ) { - // augh!! - if ( pSoldier->bMorale < 50 ) + HandleMoraleEvent( pSoldier, MORALE_NERVOUS_ALONE, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); + if ( !(pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_PERSONALITY) ) { - HandleMoraleEvent( pSoldier, MORALE_NERVOUS_ALONE, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); - if ( !(pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_PERSONALITY) ) - { - TacticalCharacterDialogue( pSoldier, QUOTE_PERSONALITY_TRAIT ); - pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY; - } + TacticalCharacterDialogue( pSoldier, QUOTE_PERSONALITY_TRAIT ); + pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY; } } - else + } + else + { + if ( pSoldier->bMorale > 45 ) { - if ( pSoldier->bMorale > 45 ) - { - // turn flag off, so that we say it every two turns - pSoldier->usQuoteSaidFlags &= ~SOLDIER_QUOTE_SAID_PERSONALITY; - } + // turn flag off, so that we say it every two turns + pSoldier->usQuoteSaidFlags &= ~SOLDIER_QUOTE_SAID_PERSONALITY; } - break; + } + break; } } } @@ -5259,16 +5323,16 @@ BOOLEAN ConvertAniCodeToAniFrame( SOLDIERTYPE *pSoldier, UINT16 usAniFrame ) pSoldier->usAniFrame = usAniFrame + (UINT16) ( ( gAnimSurfaceDatabase[ usAnimSurface ].uiNumFramesPerDir * ubTempDir ) ); - if ( gAnimSurfaceDatabase[ usAnimSurface ].hVideoObject == NULL ) - { + if ( gAnimSurfaceDatabase[ usAnimSurface ].hVideoObject == NULL ) + { pSoldier->usAniFrame = 0; - return( TRUE ); - } + return( TRUE ); + } if ( pSoldier->usAniFrame >= gAnimSurfaceDatabase[ usAnimSurface ].hVideoObject->usNumberOfObjects ) { // Debug msg here.... -// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Soldier Animation: Wrong Number of frames per number of objects: %d vs %d, %S", gAnimSurfaceDatabase[ usAnimSurface ].uiNumFramesPerDir, gAnimSurfaceDatabase[ usAnimSurface ].hVideoObject->usNumberOfObjects, gAnimControl[ pSoldier->usAnimState ].zAnimStr ); + // ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Soldier Animation: Wrong Number of frames per number of objects: %d vs %d, %S", gAnimSurfaceDatabase[ usAnimSurface ].uiNumFramesPerDir, gAnimSurfaceDatabase[ usAnimSurface ].hVideoObject->usNumberOfObjects, gAnimControl[ pSoldier->usAnimState ].zAnimStr ); pSoldier->usAniFrame = 0; } @@ -5279,46 +5343,46 @@ BOOLEAN ConvertAniCodeToAniFrame( SOLDIERTYPE *pSoldier, UINT16 usAniFrame ) void TurnSoldier( SOLDIERTYPE *pSoldier) { - INT16 sDirection; - BOOLEAN fDoDirectionChange = TRUE; - INT32 cnt; + INT16 sDirection; + BOOLEAN fDoDirectionChange = TRUE; + INT32 cnt; - // If we are a vehicle... DON'T TURN! - if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) - { - if ( pSoldier->ubBodyType != TANK_NW && pSoldier->ubBodyType != TANK_NE ) - { - return; - } - } - else // Lesh: patch for "Bug: Enemy turns around in turn based mode!" - { - // in case of errors in turning tasks - if ( pSoldier->bDesiredDirection > 7 || pSoldier->bDesiredDirection < 0) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("TurnSoldier() Warinig: Invalid desired direction for non-vehicle unit") ); - pSoldier->bDesiredDirection = pSoldier->bDirection; - } - } - // Lesh: patch ended + // If we are a vehicle... DON'T TURN! + if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) + { + if ( pSoldier->ubBodyType != TANK_NW && pSoldier->ubBodyType != TANK_NE ) + { + return; + } + } + else // Lesh: patch for "Bug: Enemy turns around in turn based mode!" + { + // in case of errors in turning tasks + if ( pSoldier->bDesiredDirection > 7 || pSoldier->bDesiredDirection < 0) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("TurnSoldier() Warinig: Invalid desired direction for non-vehicle unit") ); + pSoldier->bDesiredDirection = pSoldier->bDirection; + } + } + // Lesh: patch ended - // We handle sight now.... - if ( pSoldier->uiStatusFlags & SOLDIER_LOOK_NEXT_TURNSOLDIER ) - { + // We handle sight now.... + if ( pSoldier->uiStatusFlags & SOLDIER_LOOK_NEXT_TURNSOLDIER ) + { if ( ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_STATIONARY && pSoldier->usAnimState != CLIMBUPROOF && pSoldier->usAnimState != CLIMBDOWNROOF ) ) { - // HANDLE SIGHT! + // HANDLE SIGHT! HandleSight( pSoldier,SIGHT_LOOK | SIGHT_RADIO ); } // Turn off! pSoldier->uiStatusFlags &= (~SOLDIER_LOOK_NEXT_TURNSOLDIER ); HandleSystemNewAISituation( pSoldier, FALSE ); - } + } - if ( pSoldier->fTurningToShoot ) - { + if ( pSoldier->fTurningToShoot ) + { if ( pSoldier->bDirection == pSoldier->bDesiredDirection ) { if ( ( (gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FIREREADY ) && !pSoldier->fTurningFromPronePosition ) || pSoldier->ubBodyType == ROBOTNOWEAPON || pSoldier->ubBodyType == TANK_NW || pSoldier->ubBodyType == TANK_NE ) @@ -5347,29 +5411,29 @@ void TurnSoldier( SOLDIERTYPE *pSoldier) pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_OFF; } } - } + } - if ( pSoldier->fTurningToFall ) - { + if ( pSoldier->fTurningToFall ) + { if ( pSoldier->bDirection == pSoldier->bDesiredDirection ) { SelectFallAnimation( pSoldier ); pSoldier->fTurningToFall = FALSE; } - } + } - if ( pSoldier->fTurningUntilDone && ( pSoldier->ubPendingStanceChange != NO_PENDING_STANCE ) ) - { + if ( pSoldier->fTurningUntilDone && ( pSoldier->ubPendingStanceChange != NO_PENDING_STANCE ) ) + { if ( pSoldier->bDirection == pSoldier->bDesiredDirection ) { SendChangeSoldierStanceEvent( pSoldier, pSoldier->ubPendingStanceChange ); pSoldier->ubPendingStanceChange = NO_PENDING_STANCE; pSoldier->fTurningUntilDone = FALSE; } - } + } - if ( pSoldier->fTurningUntilDone && ( pSoldier->usPendingAnimation != NO_PENDING_ANIMATION ) ) - { + if ( pSoldier->fTurningUntilDone && ( pSoldier->usPendingAnimation != NO_PENDING_ANIMATION ) ) + { if ( pSoldier->bDirection == pSoldier->bDesiredDirection ) { UINT16 usPendingAnimation; @@ -5380,21 +5444,21 @@ void TurnSoldier( SOLDIERTYPE *pSoldier) EVENT_InitNewSoldierAnim( pSoldier, usPendingAnimation, 0 , FALSE ); pSoldier->fTurningUntilDone = FALSE; } - } - - // Don't do anything if we are at dest direction! - if ( pSoldier->bDirection == pSoldier->bDesiredDirection ) - { - if ( pSoldier->ubBodyType == TANK_NW || pSoldier->ubBodyType == TANK_NE ) - { - if ( pSoldier->iTuringSoundID != NO_SAMPLE ) - { - SoundStop( pSoldier->iTuringSoundID ); - pSoldier->iTuringSoundID = NO_SAMPLE; + } - PlaySoldierJA2Sample( pSoldier->ubID, TURRET_STOP, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - } - } + // Don't do anything if we are at dest direction! + if ( pSoldier->bDirection == pSoldier->bDesiredDirection ) + { + if ( pSoldier->ubBodyType == TANK_NW || pSoldier->ubBodyType == TANK_NE ) + { + if ( pSoldier->iTuringSoundID != NO_SAMPLE ) + { + SoundStop( pSoldier->iTuringSoundID ); + pSoldier->iTuringSoundID = NO_SAMPLE; + + PlaySoldierJA2Sample( pSoldier->ubID, TURRET_STOP, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + } + } // Turn off! pSoldier->uiStatusFlags &= (~SOLDIER_LOOK_NEXT_TURNSOLDIER ); @@ -5437,6 +5501,8 @@ void TurnSoldier( SOLDIERTYPE *pSoldier) if ( pSoldier->uiStatusFlags & SOLDIER_TURNINGFROMHIT ) { + // This section seems problem-prone. It relies on all animations happening without interruption. There must be a more + // foolproof method. if ( pSoldier->fGettingHit == 1 ) { if ( pSoldier->usPendingAnimation != FALLFORWARD_ROOF && pSoldier->usPendingAnimation != FALLOFF && pSoldier->usAnimState != FALLFORWARD_ROOF && pSoldier->usAnimState != FALLOFF ) @@ -5457,101 +5523,104 @@ void TurnSoldier( SOLDIERTYPE *pSoldier) // Turn off pSoldier->uiStatusFlags &= (~SOLDIER_TURNINGFROMHIT ); + // Release attacker - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, turning from hit animation ended") ); - ReleaseSoldiersAttacker( pSoldier ); + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Releasesoldierattacker, turning from hit animation ended") ); + // ReleaseSoldiersAttacker( pSoldier ); + DebugAttackBusy( "Finished turning from hit. Reducing attack busy.\n"); + ReduceAttackBusyCount( ); //FREEUP GETTING HIT FLAG - pSoldier->fGettingHit = FALSE; + // pSoldier->fGettingHit = FALSE; } } return; - } + } // IF WE ARE HERE, WE ARE IN THE PROCESS OF TURNING // DOUBLE CHECK TO UNSET fNOAPs... if ( pSoldier->fNoAPToFinishMove ) { - AdjustNoAPToFinishMove( pSoldier, FALSE ); + AdjustNoAPToFinishMove( pSoldier, FALSE ); } // Do something different for vehicles.... if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) { - fDoDirectionChange = FALSE; + fDoDirectionChange = FALSE; - // Get new direction - /* - sDirection = pSoldier->ubHiResDirection + ExtQuickestDirection( pSoldier->ubHiResDirection, pSoldier->ubHiResDesiredDirection ); - */ - sDirection = pSoldier->ubHiResDirection + pSoldier->bTurningIncrement; - if (sDirection > 31) - { - sDirection = 0; - } - else - { - if ( sDirection < 0 ) - { - sDirection = 31; - } - } - pSoldier->ubHiResDirection = (UINT8)sDirection; + // Get new direction + /* + sDirection = pSoldier->ubHiResDirection + ExtQuickestDirection( pSoldier->ubHiResDirection, pSoldier->ubHiResDesiredDirection ); + */ + sDirection = pSoldier->ubHiResDirection + pSoldier->bTurningIncrement; + if (sDirection > 31) + { + sDirection = 0; + } + else + { + if ( sDirection < 0 ) + { + sDirection = 31; + } + } + pSoldier->ubHiResDirection = (UINT8)sDirection; - // Are we at a multiple of a 'cardnal' direction? - for ( cnt = 0; cnt < 8; cnt++ ) - { - if ( sDirection == ubExtDirection[ cnt ] ) - { - fDoDirectionChange = TRUE; + // Are we at a multiple of a 'cardnal' direction? + for ( cnt = 0; cnt < 8; cnt++ ) + { + if ( sDirection == ubExtDirection[ cnt ] ) + { + fDoDirectionChange = TRUE; - sDirection = (INT16)cnt; + sDirection = (INT16)cnt; - break; - } - } + break; + } + } - if ( pSoldier->ubBodyType == TANK_NW || pSoldier->ubBodyType == TANK_NE ) - { - if ( pSoldier->iTuringSoundID == NO_SAMPLE ) - { - pSoldier->iTuringSoundID = PlaySoldierJA2Sample( pSoldier->ubID, TURRET_MOVE, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 100, SoundDir( pSoldier->sGridNo ), TRUE ); - } - } + if ( pSoldier->ubBodyType == TANK_NW || pSoldier->ubBodyType == TANK_NE ) + { + if ( pSoldier->iTuringSoundID == NO_SAMPLE ) + { + pSoldier->iTuringSoundID = PlaySoldierJA2Sample( pSoldier->ubID, TURRET_MOVE, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 100, SoundDir( pSoldier->sGridNo ), TRUE ); + } + } } else { - // Get new direction - //sDirection = pSoldier->bDirection + QuickestDirection( pSoldier->bDirection, pSoldier->bDesiredDirection ); - sDirection = pSoldier->bDirection + pSoldier->bTurningIncrement; - if (sDirection > 7) - { - sDirection = 0; - } - else - { - if ( sDirection < 0 ) - { - sDirection = 7; - } - } + // Get new direction + //sDirection = pSoldier->bDirection + QuickestDirection( pSoldier->bDirection, pSoldier->bDesiredDirection ); + sDirection = pSoldier->bDirection + pSoldier->bTurningIncrement; + if (sDirection > 7) + { + sDirection = 0; + } + else + { + if ( sDirection < 0 ) + { + sDirection = 7; + } + } } - // CHECK FOR A VALID TURN DIRECTION - // This is needed for prone animations as well as any multi-tiled structs - if ( fDoDirectionChange ) - { - if ( OKToAddMercToWorld( pSoldier, (INT8)sDirection ) ) - { - // Don't do this if we are walkoing off screen... - if ( gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALKOFF_SCREEN || gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALK_TO_GRIDNO ) + // CHECK FOR A VALID TURN DIRECTION + // This is needed for prone animations as well as any multi-tiled structs + if ( fDoDirectionChange ) + { + if ( OKToAddMercToWorld( pSoldier, (INT8)sDirection ) ) + { + // Don't do this if we are walkoing off screen... + if ( gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALKOFF_SCREEN || gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALK_TO_GRIDNO ) { } - else + else { // ATE: We should only do this if we are STATIONARY! if ( ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_STATIONARY ) ) @@ -5561,30 +5630,30 @@ void TurnSoldier( SOLDIERTYPE *pSoldier) // otherwise, it's handled next tile... } - EVENT_SetSoldierDirection( pSoldier, sDirection ); + EVENT_SetSoldierDirection( pSoldier, sDirection ); - if ( pSoldier->ubBodyType != LARVAE_MONSTER && !MercInWater( pSoldier ) && pSoldier->bOverTerrainType != DIRT_ROAD && pSoldier->bOverTerrainType != PAVED_ROAD ) - { - PlaySoldierFootstepSound( pSoldier ); - } - } - else - { - // Are we prone crawling? - if ( pSoldier->usAnimState == CRAWLING ) + if ( pSoldier->ubBodyType != LARVAE_MONSTER && !MercInWater( pSoldier ) && pSoldier->bOverTerrainType != DIRT_ROAD && pSoldier->bOverTerrainType != PAVED_ROAD ) + { + PlaySoldierFootstepSound( pSoldier ); + } + } + else + { + // Are we prone crawling? + if ( pSoldier->usAnimState == CRAWLING ) { - // OK, we want to getup, turn and go prone again.... - SendChangeSoldierStanceEvent( pSoldier, ANIM_CROUCH ); - pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE; + // OK, we want to getup, turn and go prone again.... + SendChangeSoldierStanceEvent( pSoldier, ANIM_CROUCH ); + pSoldier->fTurningFromPronePosition = TURNING_FROM_PRONE_ENDING_UP_FROM_MOVE; } - // If we are a creature, or multi-tiled, cancel AI action.....? - else if ( pSoldier->uiStatusFlags & SOLDIER_MULTITILE ) + // If we are a creature, or multi-tiled, cancel AI action.....? + else if ( pSoldier->uiStatusFlags & SOLDIER_MULTITILE ) { - pSoldier->bDesiredDirection = pSoldier->bDirection; + pSoldier->bDesiredDirection = pSoldier->bDirection; } - } - } + } + } } @@ -5829,7 +5898,7 @@ BOOLEAN CreateSoldierPalettes( SOLDIERTYPE *pSoldier ) CreateSoldierPaletteTables( pSoldier, HVOBJECT_GLOW_GREEN ); - + // Build a grayscale palette for testing grayout of mercs //for(uiCount=0; uiCount < 256; uiCount++) @@ -5904,104 +5973,104 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"CalculateSoldierAniSpeed"); UINT32 uiTerrainDelay; UINT32 uiSpeed = 0; - + INT8 bBreathDef, bLifeDef, bAgilDef; INT8 bAdditional = 0; - + // for those animations which have a speed of zero, we have to calculate it // here. Some animation, such as water-movement, have an ADDITIONAL speed switch( pSoldier->usAnimState ) { - // Lesh: bursting animation delay control begins - // Add your animation ID to control it - case STANDING_BURST: - case FIRE_STAND_BURST_SPREAD: - case FIRE_BURST_LOW_STAND: - case TANK_BURST: - case CROUCHED_BURST: - case PRONE_BURST: - pSoldier->sAniDelay = Weapon[Item[pSoldier->inv[HANDPOS].usItem].ubClassIndex].sAniDelay; - AdjustAniSpeed( pSoldier ); - return; - // Lesh: end + // Lesh: bursting animation delay control begins + // Add your animation ID to control it + case STANDING_BURST: + case FIRE_STAND_BURST_SPREAD: + case FIRE_BURST_LOW_STAND: + case TANK_BURST: + case CROUCHED_BURST: + case PRONE_BURST: + pSoldier->sAniDelay = Weapon[Item[pSoldier->inv[HANDPOS].usItem].ubClassIndex].sAniDelay; + AdjustAniSpeed( pSoldier ); + return; + // Lesh: end - case PRONE: - case STANDING: + case PRONE: + case STANDING: - pSoldier->sAniDelay = ( pStatsSoldier->bBreath * 2 ) + (100 - pStatsSoldier->bLife ); + pSoldier->sAniDelay = ( pStatsSoldier->bBreath * 2 ) + (100 - pStatsSoldier->bLife ); - // Limit it! - if ( pSoldier->sAniDelay < 40 ) - { - pSoldier->sAniDelay = 40; - } - AdjustAniSpeed( pSoldier ); - return; + // Limit it! + if ( pSoldier->sAniDelay < 40 ) + { + pSoldier->sAniDelay = 40; + } + AdjustAniSpeed( pSoldier ); + return; - case CROUCHING: + case CROUCHING: - pSoldier->sAniDelay = ( pStatsSoldier->bBreath * 2 ) + ( (100 - pStatsSoldier->bLife ) ); + pSoldier->sAniDelay = ( pStatsSoldier->bBreath * 2 ) + ( (100 - pStatsSoldier->bLife ) ); - // Limit it! - if ( pSoldier->sAniDelay < 40 ) - { - pSoldier->sAniDelay = 40; - } - AdjustAniSpeed( pSoldier ); - return; + // Limit it! + if ( pSoldier->sAniDelay < 40 ) + { + pSoldier->sAniDelay = 40; + } + AdjustAniSpeed( pSoldier ); + return; - case WALKING: + case WALKING: - // Adjust based on body type - bAdditional = (UINT8)( gubAnimWalkSpeeds[ pStatsSoldier->ubBodyType ].sSpeed ); - if ( bAdditional < 0 ) - bAdditional = 0; - break; + // Adjust based on body type + bAdditional = (UINT8)( gubAnimWalkSpeeds[ pStatsSoldier->ubBodyType ].sSpeed ); + if ( bAdditional < 0 ) + bAdditional = 0; + break; - case RUNNING: + case RUNNING: - // Adjust based on body type - bAdditional = (UINT8)gubAnimRunSpeeds[ pStatsSoldier->ubBodyType ].sSpeed; - if ( bAdditional < 0 ) - bAdditional = 0; - break; + // Adjust based on body type + bAdditional = (UINT8)gubAnimRunSpeeds[ pStatsSoldier->ubBodyType ].sSpeed; + if ( bAdditional < 0 ) + bAdditional = 0; + break; - case SWATTING: + case SWATTING: - // Adjust based on body type - if ( pStatsSoldier->ubBodyType <= REGFEMALE ) - { - bAdditional = (UINT8)gubAnimSwatSpeeds[ pStatsSoldier->ubBodyType ].sSpeed; - if ( bAdditional < 0 ) - bAdditional = 0; - } - break; + // Adjust based on body type + if ( pStatsSoldier->ubBodyType <= REGFEMALE ) + { + bAdditional = (UINT8)gubAnimSwatSpeeds[ pStatsSoldier->ubBodyType ].sSpeed; + if ( bAdditional < 0 ) + bAdditional = 0; + } + break; - case CRAWLING: + case CRAWLING: - // Adjust based on body type - if ( pStatsSoldier->ubBodyType <= REGFEMALE ) - { - bAdditional = (UINT8)gubAnimCrawlSpeeds[ pStatsSoldier->ubBodyType ].sSpeed; - if ( bAdditional < 0 ) - bAdditional = 0; - } - break; + // Adjust based on body type + if ( pStatsSoldier->ubBodyType <= REGFEMALE ) + { + bAdditional = (UINT8)gubAnimCrawlSpeeds[ pStatsSoldier->ubBodyType ].sSpeed; + if ( bAdditional < 0 ) + bAdditional = 0; + } + break; - case READY_RIFLE_STAND: + case READY_RIFLE_STAND: - // Raise rifle based on aim vs non-aim. - if ( pSoldier->bAimTime == 0 ) - { - // Quick shot - pSoldier->sAniDelay = 70; - } - else - { - pSoldier->sAniDelay = 150; - } - AdjustAniSpeed( pSoldier ); - return; + // Raise rifle based on aim vs non-aim. + if ( pSoldier->bAimTime == 0 ) + { + // Quick shot + pSoldier->sAniDelay = 70; + } + else + { + pSoldier->sAniDelay = 150; + } + AdjustAniSpeed( pSoldier ); + return; } @@ -6029,14 +6098,14 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier pSoldier->sAniDelay = (INT16)uiTerrainDelay; - // If a moving animation and w/re on drugs, increase speed.... + // If a moving animation and w/re on drugs, increase speed.... if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_MOVING ) - { - if ( GetDrugEffect( pSoldier, DRUG_TYPE_ADRENALINE ) ) - { - pSoldier->sAniDelay = pSoldier->sAniDelay / 2; - } - } + { + if ( GetDrugEffect( pSoldier, DRUG_TYPE_ADRENALINE ) ) + { + pSoldier->sAniDelay = pSoldier->sAniDelay / 2; + } + } // MODIFTY NOW BASED ON REAL-TIME, ETC // Adjust speed, make twice as fast if in turn-based! @@ -6074,14 +6143,14 @@ UINT8 GetSpeedUpFactor( ) case CIV_TEAM: return gGameExternalOptions.gubCivilianTurnSpeedUpFactor; } - + return 1; } void SetSoldierAniSpeed( SOLDIERTYPE *pSoldier ) { SOLDIERTYPE *pStatsSoldier; - + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"SetSoldierAniSpeed"); // ATE: If we are an enemy and are not visible...... @@ -6197,7 +6266,7 @@ BOOLEAN LoadPaletteData( ) { return( FALSE ); } - + // # entries if ( !FileRead( hFile, &gpPalRep[ cnt ].ubPaletteSize, sizeof( gpPalRep[ cnt ].ubPaletteSize ), (UINT32 *)NULL ) ) { @@ -6231,7 +6300,7 @@ BOOLEAN LoadPaletteData( ) } FileClose( hFile ); - + return( TRUE ); } @@ -6301,7 +6370,7 @@ BOOLEAN DeletePaletteData( ) MemFree( gpPalRep ); gpPalRep = NULL; } - + return( TRUE ); } @@ -6335,35 +6404,35 @@ UINT16 GetNewSoldierStateFromNewStance( SOLDIERTYPE *pSoldier, UINT8 ubDesiredSt switch( bCurrentHeight ) { - case ANIM_STAND - ANIM_CROUCH: - usNewState = KNEEL_UP; - break; - case ANIM_CROUCH - ANIM_STAND: - usNewState = KNEEL_DOWN; - break; + case ANIM_STAND - ANIM_CROUCH: + usNewState = KNEEL_UP; + break; + case ANIM_CROUCH - ANIM_STAND: + usNewState = KNEEL_DOWN; + break; - case ANIM_STAND - ANIM_PRONE: - usNewState = PRONE_UP; - break; - case ANIM_PRONE - ANIM_STAND: - usNewState = KNEEL_DOWN; - break; + case ANIM_STAND - ANIM_PRONE: + usNewState = PRONE_UP; + break; + case ANIM_PRONE - ANIM_STAND: + usNewState = KNEEL_DOWN; + break; - case ANIM_CROUCH - ANIM_PRONE: - usNewState = PRONE_UP; - break; - case ANIM_PRONE - ANIM_CROUCH: - usNewState = PRONE_DOWN; - break; + case ANIM_CROUCH - ANIM_PRONE: + usNewState = PRONE_UP; + break; + case ANIM_PRONE - ANIM_CROUCH: + usNewState = PRONE_DOWN; + break; - default: + default: - // Cannot get here unless ub desired stance is bogus - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "GetNewSoldierStateFromNewStance bogus ubDesiredStance value %d", ubDesiredStance ) ); - usNewState = pSoldier->usAnimState; + // Cannot get here unless ub desired stance is bogus + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "GetNewSoldierStateFromNewStance bogus ubDesiredStance value %d", ubDesiredStance ) ); + usNewState = pSoldier->usAnimState; } - + return( usNewState ); } @@ -6375,38 +6444,38 @@ void MoveMercFacingDirection( SOLDIERTYPE *pSoldier, BOOLEAN fReverse, FLOAT dMo // Determine which direction we are in switch( pSoldier->bDirection ) { - case NORTH: - dAngle = (FLOAT)( -1 * PI ); - break; + case NORTH: + dAngle = (FLOAT)( -1 * PI ); + break; - case NORTHEAST: - dAngle = (FLOAT)( PI * .75 ); - break; + case NORTHEAST: + dAngle = (FLOAT)( PI * .75 ); + break; - case EAST: - dAngle = (FLOAT)( PI / 2 ); - break; + case EAST: + dAngle = (FLOAT)( PI / 2 ); + break; - case SOUTHEAST: - dAngle = (FLOAT)( PI / 4 ); - break; + case SOUTHEAST: + dAngle = (FLOAT)( PI / 4 ); + break; - case SOUTH: - dAngle = (FLOAT)0; - break; + case SOUTH: + dAngle = (FLOAT)0; + break; - case SOUTHWEST: - //dAngle = (FLOAT)( PI * -.25 ); - dAngle = (FLOAT)-0.786; - break; + case SOUTHWEST: + //dAngle = (FLOAT)( PI * -.25 ); + dAngle = (FLOAT)-0.786; + break; - case WEST: - dAngle = (FLOAT) ( PI *-.5 ); - break; + case WEST: + dAngle = (FLOAT) ( PI *-.5 ); + break; - case NORTHWEST: - dAngle = (FLOAT) ( PI * -.75 ); - break; + case NORTHWEST: + dAngle = (FLOAT) ( PI * -.75 ); + break; } @@ -6430,34 +6499,38 @@ void BeginSoldierClimbUpRoof( SOLDIERTYPE *pSoldier ) if ( EnoughPoints( pSoldier, GetAPsToClimbRoof( pSoldier, FALSE ), 0, TRUE ) ) { //Kaiden: Helps if we look where we are going before we try to climb on top of someone - ubWhoIsThere = WhoIsThere2( NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc(bNewDirection ) ), 1 ); - if ( ubWhoIsThere != NOBODY && ubWhoIsThere != pSoldier->ubID ) + ubWhoIsThere = WhoIsThere2( NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc(bNewDirection ) ), 1 ); + if ( ubWhoIsThere != NOBODY && ubWhoIsThere != pSoldier->ubID ) { - return; + return; } - else + else { - if (pSoldier->bTeam == gbPlayerNum) - { - // OK, SET INTERFACE FIRST - SetUIBusy( pSoldier->ubID ); - } + if (pSoldier->bTeam == gbPlayerNum) + { + // OK, SET INTERFACE FIRST + SetUIBusy( pSoldier->ubID ); + } - pSoldier->sTempNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc(bNewDirection ) ); + pSoldier->sTempNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc(bNewDirection ) ); - pSoldier->ubPendingDirection = bNewDirection; - //pSoldier->usPendingAnimation = CLIMBUPROOF; - EVENT_InitNewSoldierAnim( pSoldier, CLIMBUPROOF, 0 , FALSE ); + pSoldier->ubPendingDirection = bNewDirection; + //pSoldier->usPendingAnimation = CLIMBUPROOF; + EVENT_InitNewSoldierAnim( pSoldier, CLIMBUPROOF, 0 , FALSE ); - InternalReceivingSoldierCancelServices( pSoldier, FALSE ); - InternalGivingSoldierCancelServices( pSoldier, FALSE ); + InternalReceivingSoldierCancelServices( pSoldier, FALSE ); + InternalGivingSoldierCancelServices( pSoldier, FALSE ); - } + } } } - + else + { + DebugAttackBusy( String( "Soldier %d tried to climb where no roof is.\n", pSoldier->ubID ) ); + pSoldier->bAction = AI_ACTION_NONE; + } } void BeginSoldierClimbFence( SOLDIERTYPE *pSoldier ) @@ -6535,27 +6608,27 @@ void BeginSoldierGetup( SOLDIERTYPE *pSoldier ) { switch( pSoldier->usAnimState ) { - case FALLOFF_FORWARD_STOP: - case PRONE_LAYFROMHIT_STOP: - case STAND_FALLFORWARD_STOP: - ChangeSoldierStance( pSoldier, ANIM_CROUCH ); - break; + case FALLOFF_FORWARD_STOP: + case PRONE_LAYFROMHIT_STOP: + case STAND_FALLFORWARD_STOP: + ChangeSoldierStance( pSoldier, ANIM_CROUCH ); + break; - case FALLBACKHIT_STOP: - case FALLOFF_STOP: - case FLYBACKHIT_STOP: - case FALLBACK_HIT_STAND: - case FALLOFF: - case FLYBACK_HIT: + case FALLBACKHIT_STOP: + case FALLOFF_STOP: + case FLYBACKHIT_STOP: + case FALLBACK_HIT_STAND: + case FALLOFF: + case FLYBACK_HIT: - // ROLL OVER - EVENT_InitNewSoldierAnim( pSoldier, ROLLOVER, 0 , FALSE ); - break; - - default: + // ROLL OVER + EVENT_InitNewSoldierAnim( pSoldier, ROLLOVER, 0 , FALSE ); + break; - ChangeSoldierStance( pSoldier, ANIM_CROUCH ); - break; + default: + + ChangeSoldierStance( pSoldier, ANIM_CROUCH ); + break; } } else @@ -6601,75 +6674,76 @@ void HandleTakeDamageDeath( SOLDIERTYPE *pSoldier, UINT8 bOldLife, UINT8 ubReaso { switch( ubReason ) { - case TAKE_DAMAGE_BLOODLOSS: - case TAKE_DAMAGE_ELECTRICITY: - case TAKE_DAMAGE_GAS: - - if ( pSoldier->bInSector ) + case TAKE_DAMAGE_BLOODLOSS: + case TAKE_DAMAGE_ELECTRICITY: + case TAKE_DAMAGE_GAS: + + if ( pSoldier->bInSector ) + { + if ( pSoldier->bVisible != -1 ) { - if ( pSoldier->bVisible != -1 ) + if ( ubReason != TAKE_DAMAGE_BLOODLOSS ) { - if ( ubReason != TAKE_DAMAGE_BLOODLOSS ) - { - DoMercBattleSound( pSoldier, BATTLE_SOUND_DIE1 ); - pSoldier->fDeadSoundPlayed = TRUE; - } - } - - if ( ( ubReason == TAKE_DAMAGE_ELECTRICITY ) && pSoldier->bLife < OKLIFE ) - { - pSoldier->fInNonintAnim = FALSE; - } - - // Check for < OKLIFE - if ( pSoldier->bLife < OKLIFE && pSoldier->bLife != 0 && !pSoldier->bCollapsed) - { - SoldierCollapse( pSoldier ); - } - - // THis is for the die animation that will be happening.... - if ( pSoldier->bLife == 0 ) - { - pSoldier->fDoingExternalDeath = TRUE; - } - - // Check if he is dead.... - CheckForAndHandleSoldierDyingNotFromHit( pSoldier ); - - } - - //if( !( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) ) - { - HandleSoldierTakeDamageFeedback( pSoldier ); - } - - if(( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) || !pSoldier->bInSector ) - { - if ( pSoldier->bLife == 0 && !( pSoldier->uiStatusFlags & SOLDIER_DEAD ) ) - { - StrategicHandlePlayerTeamMercDeath( pSoldier ); - - // ATE: Here, force always to use die sound... - pSoldier->fDieSoundUsed = FALSE; DoMercBattleSound( pSoldier, BATTLE_SOUND_DIE1 ); - pSoldier->fDeadSoundPlayed = TRUE; - - // ATE: DO death sound - PlayJA2Sample( (UINT8)DOORCR_1, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); - PlayJA2Sample( (UINT8)HEADCR_1, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); + pSoldier->fDeadSoundPlayed = TRUE; } } - break; + + if ( ( ubReason == TAKE_DAMAGE_ELECTRICITY ) && pSoldier->bLife < OKLIFE ) + { + pSoldier->fInNonintAnim = FALSE; + } + + // Check for < OKLIFE + if ( pSoldier->bLife < OKLIFE && pSoldier->bLife != 0 && !pSoldier->bCollapsed) + { + SoldierCollapse( pSoldier ); + } + + // THis is for the die animation that will be happening.... + if ( pSoldier->bLife == 0 ) + { + pSoldier->fDoingExternalDeath = TRUE; + } + + // Check if he is dead.... + CheckForAndHandleSoldierDyingNotFromHit( pSoldier ); + + } + + //if( !( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) ) + { + HandleSoldierTakeDamageFeedback( pSoldier ); + } + + if(( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) || !pSoldier->bInSector ) + { + if ( pSoldier->bLife == 0 && !( pSoldier->uiStatusFlags & SOLDIER_DEAD ) ) + { + StrategicHandlePlayerTeamMercDeath( pSoldier ); + + // ATE: Here, force always to use die sound... + pSoldier->fDieSoundUsed = FALSE; + DoMercBattleSound( pSoldier, BATTLE_SOUND_DIE1 ); + pSoldier->fDeadSoundPlayed = TRUE; + + // ATE: DO death sound + PlayJA2Sample( (UINT8)DOORCR_1, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); + PlayJA2Sample( (UINT8)HEADCR_1, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); + } + } + break; } - if ( ubReason == TAKE_DAMAGE_ELECTRICITY ) - { - if ( pSoldier->bLife >= OKLIFE ) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Freeing up attacker from electricity damage") ); - ReleaseSoldiersAttacker( pSoldier ); - } - } + // 0verhaul: This is also already handled by the animation transitions + // if ( ubReason == TAKE_DAMAGE_ELECTRICITY ) + // { + // if ( pSoldier->bLife >= OKLIFE ) + // { + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Freeing up attacker from electricity damage") ); + // ReleaseSoldiersAttacker( pSoldier ); + // } + // } } @@ -6681,38 +6755,38 @@ UINT8 SoldierTakeDamage( SOLDIERTYPE *pSoldier, INT8 bHeight, INT16 sLifeDeduct, INT16 sAPCost; UINT8 ubBlood; UINT16 usItemFlags=0; // Kaiden: Needed for the reveal all items after combat code from UB. - - pSoldier->ubLastDamageReason = ubReason; + + pSoldier->ubLastDamageReason = ubReason; // CJC Jan 21 99: add check to see if we are hurting an enemy in an enemy-controlled // sector; if so, this is a sign of player activity switch ( pSoldier->bTeam ) { - case ENEMY_TEAM: - // if we're in the wilderness this always counts - if ( StrategicMap[ CALCULATE_STRATEGIC_INDEX( gWorldSectorX, gWorldSectorY ) ].fEnemyControlled || SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] != TOWN ) - { - // update current day of activity! - UpdateLastDayOfPlayerActivity( (UINT16) GetWorldDay() ); - } - break; - case CREATURE_TEAM: - // always a sign of activity? + case ENEMY_TEAM: + // if we're in the wilderness this always counts + if ( StrategicMap[ CALCULATE_STRATEGIC_INDEX( gWorldSectorX, gWorldSectorY ) ].fEnemyControlled || SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] != TOWN ) + { + // update current day of activity! UpdateLastDayOfPlayerActivity( (UINT16) GetWorldDay() ); - break; - case CIV_TEAM: - if ( pSoldier->ubCivilianGroup == KINGPIN_CIV_GROUP && gubQuest[ QUEST_RESCUE_MARIA ] == QUESTINPROGRESS && gTacticalStatus.bBoxingState == NOT_BOXING ) + } + break; + case CREATURE_TEAM: + // always a sign of activity? + UpdateLastDayOfPlayerActivity( (UINT16) GetWorldDay() ); + break; + case CIV_TEAM: + if ( pSoldier->ubCivilianGroup == KINGPIN_CIV_GROUP && gubQuest[ QUEST_RESCUE_MARIA ] == QUESTINPROGRESS && gTacticalStatus.bBoxingState == NOT_BOXING ) + { + SOLDIERTYPE * pMaria = FindSoldierByProfileID( MARIA, FALSE ); + if ( pMaria && pMaria->bActive && pMaria->bInSector ) { - SOLDIERTYPE * pMaria = FindSoldierByProfileID( MARIA, FALSE ); - if ( pMaria && pMaria->bActive && pMaria->bInSector ) - { - SetFactTrue( FACT_MARIA_ESCAPE_NOTICED ); - } + SetFactTrue( FACT_MARIA_ESCAPE_NOTICED ); } - break; - default: - break; + } + break; + default: + break; } // Deduct life!, Show damage if we want! @@ -6770,7 +6844,7 @@ UINT8 SoldierTakeDamage( SOLDIERTYPE *pSoldier, INT8 bHeight, INT16 sLifeDeduct, if ( CREATURE_OR_BLOODCAT( pSoldier ) ) { INT16 sReductionFactor = 0; - + if ( pSoldier->ubBodyType == BLOODCAT ) { sReductionFactor = 2; @@ -6779,29 +6853,29 @@ UINT8 SoldierTakeDamage( SOLDIERTYPE *pSoldier, INT8 bHeight, INT16 sLifeDeduct, { switch( pSoldier->ubBodyType ) { - case LARVAE_MONSTER: - case INFANT_MONSTER: - sReductionFactor = 1; - break; - case YAF_MONSTER: - case YAM_MONSTER: - sReductionFactor = 4; - break; - case ADULTFEMALEMONSTER: - case AM_MONSTER: - sReductionFactor = 6; - break; - case QUEENMONSTER: - // increase with range! - if ( ubAttacker == NOBODY ) - { - sReductionFactor = 8; - } - else - { - sReductionFactor = 4 + PythSpacesAway( MercPtrs[ ubAttacker ]->sGridNo, pSoldier->sGridNo ) / 2; - } - break; + case LARVAE_MONSTER: + case INFANT_MONSTER: + sReductionFactor = 1; + break; + case YAF_MONSTER: + case YAM_MONSTER: + sReductionFactor = 4; + break; + case ADULTFEMALEMONSTER: + case AM_MONSTER: + sReductionFactor = 6; + break; + case QUEENMONSTER: + // increase with range! + if ( ubAttacker == NOBODY ) + { + sReductionFactor = 8; + } + else + { + sReductionFactor = 4 + PythSpacesAway( MercPtrs[ ubAttacker ]->sGridNo, pSoldier->sGridNo ) / 2; + } + break; } } @@ -6818,7 +6892,7 @@ UINT8 SoldierTakeDamage( SOLDIERTYPE *pSoldier, INT8 bHeight, INT16 sLifeDeduct, // take at most 2/3rds sLifeDeduct = (sLifeDeduct * 2) / 3; } - + // reduce breath loss to a smaller degree, except for the queen... if ( pSoldier->ubBodyType == QUEENMONSTER ) { @@ -6914,13 +6988,13 @@ UINT8 SoldierTakeDamage( SOLDIERTYPE *pSoldier, INT8 bHeight, INT16 sLifeDeduct, } // Deduct breath AND APs! - sAPCost = (sLifeDeduct / AP_GET_WOUNDED_DIVISOR); // + fallCost; + sAPCost = (sLifeDeduct / AP_GET_WOUNDED_DIVISOR); // + fallCost; - // ATE: if the robot, do not deduct + // ATE: if the robot, do not deduct if ( !AM_A_ROBOT( pSoldier ) ) { - DeductPoints( pSoldier, sAPCost, sBreathLoss , FALSE); - } + DeductPoints( pSoldier, sAPCost, sBreathLoss , FALSE); + } ubCombinedLoss = (UINT8) sLifeDeduct / 10 + sBreathLoss / 2000; @@ -6930,7 +7004,7 @@ UINT8 SoldierTakeDamage( SOLDIERTYPE *pSoldier, INT8 bHeight, INT16 sLifeDeduct, pSoldier->bShock += ubCombinedLoss; } - // start the stopwatch - the blood is gushing! + // start the stopwatch - the blood is gushing! pSoldier->dNextBleed = CalcSoldierNextBleed( pSoldier ); if ( pSoldier->bInSector && pSoldier->bVisible != -1 ) @@ -6945,17 +7019,17 @@ UINT8 SoldierTakeDamage( SOLDIERTYPE *pSoldier, INT8 bHeight, INT16 sLifeDeduct, pSoldier->fDisplayDamage = TRUE; pSoldier->bDisplayDamageCount = 0; - if ( pSoldier->ubBodyType == QUEENMONSTER ) - { - pSoldier->sDamageX = 0; - pSoldier->sDamageY = 0; - } - else - { - GetSoldierAnimOffsets( pSoldier, &sOffsetX, &sOffsetY ); - pSoldier->sDamageX = sOffsetX; - pSoldier->sDamageY = sOffsetY; - } + if ( pSoldier->ubBodyType == QUEENMONSTER ) + { + pSoldier->sDamageX = 0; + pSoldier->sDamageY = 0; + } + else + { + GetSoldierAnimOffsets( pSoldier, &sOffsetX, &sOffsetY ); + pSoldier->sDamageX = sOffsetX; + pSoldier->sDamageY = sOffsetY; + } } } @@ -7004,8 +7078,8 @@ UINT8 SoldierTakeDamage( SOLDIERTYPE *pSoldier, INT8 bHeight, INT16 sLifeDeduct, // Kaiden Added for UB reveal All items after combat feature! else if( pSoldier->bTeam == ENEMY_TEAM ) { - //add a flag to the item so when all enemies are killed, we can run through and reveal all the enemies items - usItemFlags |= WORLD_ITEM_DROPPED_FROM_ENEMY; + //add a flag to the item so when all enemies are killed, we can run through and reveal all the enemies items + usItemFlags |= WORLD_ITEM_DROPPED_FROM_ENEMY; } AddItemToPool( pSoldier->sGridNo, &(pSoldier->inv[ HANDPOS ]), bVisible, pSoldier->bLevel, usItemFlags, -1 ); //Madd: added usItemFlags to function arguments DeleteObj( &(pSoldier->inv[HANDPOS]) ); @@ -7014,23 +7088,23 @@ UINT8 SoldierTakeDamage( SOLDIERTYPE *pSoldier, INT8 bHeight, INT16 sLifeDeduct, } } - // Drop some blood! - // decide blood amt, if any - ubBlood = ( sLifeDeduct / BLOODDIVISOR); - if ( ubBlood > MAXBLOODQUANTITY ) - { - ubBlood = MAXBLOODQUANTITY; - } + // Drop some blood! + // decide blood amt, if any + ubBlood = ( sLifeDeduct / BLOODDIVISOR); + if ( ubBlood > MAXBLOODQUANTITY ) + { + ubBlood = MAXBLOODQUANTITY; + } if ( !( pSoldier->uiStatusFlags & ( SOLDIER_VEHICLE | SOLDIER_ROBOT ) ) ) { - if ( ubBlood != 0 ) - { + if ( ubBlood != 0 ) + { if ( pSoldier->bInSector ) { DropBlood( pSoldier, ubBlood, pSoldier->bVisible ); } - } + } } //Set UI Flag for unconscious, if it's our own guy! @@ -7048,7 +7122,7 @@ UINT8 SoldierTakeDamage( SOLDIERTYPE *pSoldier, INT8 bHeight, INT16 sLifeDeduct, CheckForBreathCollapse( pSoldier ); } - // EXPERIENCE CLASS GAIN (combLoss): Getting wounded in battle + // EXPERIENCE CLASS GAIN (combLoss): Getting wounded in battle DirtyMercPanelInterface( pSoldier, DIRTYLEVEL1 ); @@ -7066,8 +7140,8 @@ UINT8 SoldierTakeDamage( SOLDIERTYPE *pSoldier, INT8 bHeight, INT16 sLifeDeduct, /* else if ( ubReason == TAKE_DAMAGE_GUNFIRE ) { - // MARKSMANSHIP GAIN (combLoss): Causing wounds in battle - StatChange( MercPtrs[ ubAttacker ], MARKAMT, (UINT16)( 5 * ubCombinedLoss ), FALSE ); + // MARKSMANSHIP GAIN (combLoss): Causing wounds in battle + StatChange( MercPtrs[ ubAttacker ], MARKAMT, (UINT16)( 5 * ubCombinedLoss ), FALSE ); } */ } @@ -7077,7 +7151,7 @@ UINT8 SoldierTakeDamage( SOLDIERTYPE *pSoldier, INT8 bHeight, INT16 sLifeDeduct, if (PTR_OURTEAM) { // EXPERIENCE GAIN: Took some damage - StatChange( pSoldier, EXPERAMT, ( UINT16 )( 5 * ubCombinedLoss ), FROM_FAILURE ); + StatChange( pSoldier, EXPERAMT, ( UINT16 )( 5 * ubCombinedLoss ), FROM_FAILURE ); // Check for quote if ( !(pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_BEING_PUMMELED ) ) @@ -7116,7 +7190,7 @@ UINT8 SoldierTakeDamage( SOLDIERTYPE *pSoldier, INT8 bHeight, INT16 sLifeDeduct, { ShutupaYoFace( pSoldier->iFaceIndex ); } - + if ( pSoldier->bLife < OKLIFE ) { DecayIndividualOpplist( pSoldier ); @@ -7144,17 +7218,17 @@ BOOLEAN InternalDoMercBattleSound( SOLDIERTYPE *pSoldier, UINT8 ubBattleSoundID, // DOUBLECHECK RANGE CHECKF ( ubBattleSoundID < NUM_MERC_BATTLE_SOUNDS ); - if ( ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) - { - // Pick a passenger from vehicle.... - pSoldier = PickRandomPassengerFromVehicle( pSoldier ); + if ( ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) + { + // Pick a passenger from vehicle.... + pSoldier = PickRandomPassengerFromVehicle( pSoldier ); - if ( pSoldier == NULL ) - { - return( FALSE ); - } + if ( pSoldier == NULL ) + { + return( FALSE ); + } - } + } // If a death sound, and we have already done ours... if ( ubBattleSoundID == BATTLE_SOUND_DIE1 ) @@ -7165,7 +7239,7 @@ BOOLEAN InternalDoMercBattleSound( SOLDIERTYPE *pSoldier, UINT8 ubBattleSoundID, } } - + // Are we mute? if ( pSoldier->uiStatusFlags & SOLDIER_MUTE ) { @@ -7173,65 +7247,65 @@ BOOLEAN InternalDoMercBattleSound( SOLDIERTYPE *pSoldier, UINT8 ubBattleSoundID, } -// uiTimeSameBattleSndDone + // uiTimeSameBattleSndDone // If we are a creature, etc, pick a better sound... if ( ubBattleSoundID == BATTLE_SOUND_HIT1 || ubBattleSoundID == BATTLE_SOUND_HIT2 ) { switch ( pSoldier->ubBodyType ) { - case COW: + case COW: - fDoSub = TRUE; - uiSubSoundID = COW_HIT_SND; - break; + fDoSub = TRUE; + uiSubSoundID = COW_HIT_SND; + break; - case YAF_MONSTER: - case YAM_MONSTER: - case ADULTFEMALEMONSTER: - case AM_MONSTER: + case YAF_MONSTER: + case YAM_MONSTER: + case ADULTFEMALEMONSTER: + case AM_MONSTER: - fDoSub = TRUE; + fDoSub = TRUE; - if ( Random( 2 ) == 0 ) - { - uiSubSoundID = ACR_DIE_PART1; - } - else - { - uiSubSoundID = ACR_LUNGE; - } - break; + if ( Random( 2 ) == 0 ) + { + uiSubSoundID = ACR_DIE_PART1; + } + else + { + uiSubSoundID = ACR_LUNGE; + } + break; - case INFANT_MONSTER: + case INFANT_MONSTER: - fDoSub = TRUE; - uiSubSoundID = BCR_SHRIEK; - break; + fDoSub = TRUE; + uiSubSoundID = BCR_SHRIEK; + break; - case QUEENMONSTER: + case QUEENMONSTER: - fDoSub = TRUE; - uiSubSoundID = LQ_SHRIEK; - break; + fDoSub = TRUE; + uiSubSoundID = LQ_SHRIEK; + break; - case LARVAE_MONSTER: + case LARVAE_MONSTER: - fDoSub = TRUE; - uiSubSoundID = BCR_SHRIEK; - break; + fDoSub = TRUE; + uiSubSoundID = BCR_SHRIEK; + break; - case BLOODCAT: + case BLOODCAT: - fDoSub = TRUE; - uiSubSoundID = BLOODCAT_HIT_1; - break; + fDoSub = TRUE; + uiSubSoundID = BLOODCAT_HIT_1; + break; - case ROBOTNOWEAPON: + case ROBOTNOWEAPON: - fDoSub = TRUE; - uiSubSoundID = (UINT32)( S_METAL_IMPACT1 + Random( 2 ) ); - break; + fDoSub = TRUE; + uiSubSoundID = (UINT32)( S_METAL_IMPACT1 + Random( 2 ) ); + break; } } @@ -7239,51 +7313,51 @@ BOOLEAN InternalDoMercBattleSound( SOLDIERTYPE *pSoldier, UINT8 ubBattleSoundID, { switch ( pSoldier->ubBodyType ) { - case COW: + case COW: - fDoSub = TRUE; - uiSubSoundID = COW_DIE_SND; - break; + fDoSub = TRUE; + uiSubSoundID = COW_DIE_SND; + break; - case YAF_MONSTER: - case YAM_MONSTER: - case ADULTFEMALEMONSTER: - case AM_MONSTER: + case YAF_MONSTER: + case YAM_MONSTER: + case ADULTFEMALEMONSTER: + case AM_MONSTER: - fDoSub = TRUE; - uiSubSoundID = CREATURE_FALL_PART_2; - break; + fDoSub = TRUE; + uiSubSoundID = CREATURE_FALL_PART_2; + break; - case INFANT_MONSTER: + case INFANT_MONSTER: - fDoSub = TRUE; - uiSubSoundID = BCR_DYING; - break; + fDoSub = TRUE; + uiSubSoundID = BCR_DYING; + break; - case LARVAE_MONSTER: + case LARVAE_MONSTER: - fDoSub = TRUE; - uiSubSoundID = LCR_RUPTURE; - break; + fDoSub = TRUE; + uiSubSoundID = LCR_RUPTURE; + break; - case QUEENMONSTER: + case QUEENMONSTER: - fDoSub = TRUE; - uiSubSoundID = LQ_DYING; - break; + fDoSub = TRUE; + uiSubSoundID = LQ_DYING; + break; - case BLOODCAT: + case BLOODCAT: - fDoSub = TRUE; - uiSubSoundID = BLOODCAT_DIE_1; - break; + fDoSub = TRUE; + uiSubSoundID = BLOODCAT_DIE_1; + break; - case ROBOTNOWEAPON: + case ROBOTNOWEAPON: - fDoSub = TRUE; - uiSubSoundID = (UINT32)( EXPLOSION_1 ); - PlayJA2Sample( ROBOT_DEATH, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); - break; + fDoSub = TRUE; + uiSubSoundID = (UINT32)( EXPLOSION_1 ); + PlayJA2Sample( ROBOT_DEATH, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); + break; } } @@ -7292,14 +7366,14 @@ BOOLEAN InternalDoMercBattleSound( SOLDIERTYPE *pSoldier, UINT8 ubBattleSoundID, if ( pSoldier->ubBodyType == ROBOTNOWEAPON && !fDoSub ) { fDoSub = TRUE; - if ( ubBattleSoundID == BATTLE_SOUND_ATTN1 ) - { - uiSubSoundID = ROBOT_GREETING; - } - else - { - uiSubSoundID = ROBOT_BEEP; - } + if ( ubBattleSoundID == BATTLE_SOUND_ATTN1 ) + { + uiSubSoundID = ROBOT_GREETING; + } + else + { + uiSubSoundID = ROBOT_BEEP; + } } if ( fDoSub ) @@ -7362,8 +7436,8 @@ BOOLEAN InternalDoMercBattleSound( SOLDIERTYPE *pSoldier, UINT8 ubBattleSoundID, // Save this one we're doing... pSoldier->bOldBattleSnd = ubBattleSoundID; pSoldier->uiTimeSameBattleSndDone = GetJA2Clock( ); - - + + // Adjust based on morale... if ( ubBattleSoundID == BATTLE_SOUND_OK1 && pSoldier->bMorale < LOW_MORALE_BATTLE_SND_THREASHOLD ) { @@ -7403,7 +7477,7 @@ BOOLEAN InternalDoMercBattleSound( SOLDIERTYPE *pSoldier, UINT8 ubBattleSoundID, { sprintf( zFilename, "BATTLESNDS\\%03d_%s.wav", pSoldier->ubProfile, gBattleSndsData[ ubSoundID ].zName ); } - + if ( !FileExists( zFilename ) ) { // OK, temp build file... @@ -7621,13 +7695,13 @@ BOOLEAN CheckSoldierHitRoof( SOLDIERTYPE *pSoldier ) { return( FALSE ); } - + // Are wee near enough to fall forwards.... if ( pSoldier->bDirection == gOneCDirection[ bNewDirection ] || - pSoldier->bDirection == gTwoCDirection[ bNewDirection ] || - pSoldier->bDirection == bNewDirection || - pSoldier->bDirection == gOneCCDirection[ bNewDirection ] || - pSoldier->bDirection == gTwoCCDirection[ bNewDirection ] ) + pSoldier->bDirection == gTwoCDirection[ bNewDirection ] || + pSoldier->bDirection == bNewDirection || + pSoldier->bDirection == gOneCCDirection[ bNewDirection ] || + pSoldier->bDirection == gTwoCCDirection[ bNewDirection ] ) { // Do backwards... fDoForwards = FALSE; @@ -7681,70 +7755,70 @@ void BeginSoldierClimbDownRoof( SOLDIERTYPE *pSoldier ) if ( EnoughPoints( pSoldier, GetAPsToClimbRoof( pSoldier, TRUE ), 0, TRUE ) ) { //Kaiden: Helps if we look where we are going before we try to climb on top of someone - ubWhoIsThere = WhoIsThere2( NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc(bNewDirection ) ), 0 ); - if ( ubWhoIsThere != NOBODY && ubWhoIsThere != pSoldier->ubID ) + ubWhoIsThere = WhoIsThere2( NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc(bNewDirection ) ), 0 ); + if ( ubWhoIsThere != NOBODY && ubWhoIsThere != pSoldier->ubID ) { - return; + return; } - else + else { - if (pSoldier->bTeam == gbPlayerNum) - { - // OK, SET INTERFACE FIRST - SetUIBusy( pSoldier->ubID ); + if (pSoldier->bTeam == gbPlayerNum) + { + // OK, SET INTERFACE FIRST + SetUIBusy( pSoldier->ubID ); + } + + + + + pSoldier->sTempNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc(bNewDirection ) ); + + bNewDirection = gTwoCDirection[ bNewDirection ]; + + pSoldier->ubPendingDirection = bNewDirection; + EVENT_InitNewSoldierAnim( pSoldier, CLIMBDOWNROOF, 0 , FALSE ); + + InternalReceivingSoldierCancelServices( pSoldier, FALSE ); + InternalGivingSoldierCancelServices( pSoldier, FALSE ); + } - - - - - pSoldier->sTempNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc(bNewDirection ) ); - - bNewDirection = gTwoCDirection[ bNewDirection ]; - - pSoldier->ubPendingDirection = bNewDirection; - EVENT_InitNewSoldierAnim( pSoldier, CLIMBDOWNROOF, 0 , FALSE ); - - InternalReceivingSoldierCancelServices( pSoldier, FALSE ); - InternalGivingSoldierCancelServices( pSoldier, FALSE ); - } } - } } /* void BeginSoldierClimbDownRoof( SOLDIERTYPE *pSoldier ) { - INT8 bNewDirection; - UINT8 ubWhoIsThere; +INT8 bNewDirection; +UINT8 ubWhoIsThere; - if ( FindLowerLevel( pSoldier, pSoldier->sGridNo, pSoldier->bDirection, &bNewDirection ) && ( pSoldier->bLevel > 0 ) ) - { - if ( EnoughPoints( pSoldier, GetAPsToClimbRoof( pSoldier, TRUE ), 0, TRUE ) ) - { - if (pSoldier->bTeam == gbPlayerNum) - { - // OK, SET INTERFACE FIRST - SetUIBusy( pSoldier->ubID ); - } +if ( FindLowerLevel( pSoldier, pSoldier->sGridNo, pSoldier->bDirection, &bNewDirection ) && ( pSoldier->bLevel > 0 ) ) +{ +if ( EnoughPoints( pSoldier, GetAPsToClimbRoof( pSoldier, TRUE ), 0, TRUE ) ) +{ +if (pSoldier->bTeam == gbPlayerNum) +{ +// OK, SET INTERFACE FIRST +SetUIBusy( pSoldier->ubID ); +} - pSoldier->sTempNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc(bNewDirection ) ); +pSoldier->sTempNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc(bNewDirection ) ); - bNewDirection = gTwoCDirection[ bNewDirection ]; +bNewDirection = gTwoCDirection[ bNewDirection ]; - pSoldier->ubPendingDirection = bNewDirection; - EVENT_InitNewSoldierAnim( pSoldier, CLIMBDOWNROOF, 0 , FALSE ); +pSoldier->ubPendingDirection = bNewDirection; +EVENT_InitNewSoldierAnim( pSoldier, CLIMBDOWNROOF, 0 , FALSE ); - InternalReceivingSoldierCancelServices( pSoldier, FALSE ); - InternalGivingSoldierCancelServices( pSoldier, FALSE ); +InternalReceivingSoldierCancelServices( pSoldier, FALSE ); +InternalGivingSoldierCancelServices( pSoldier, FALSE ); - } - } +} +} } */ @@ -7774,31 +7848,31 @@ void MoveMerc( SOLDIERTYPE *pSoldier, FLOAT dMovementChange, FLOAT dAngle, BOOLE switch( pSoldier->bMovementDirection ) { - case NORTHEAST: - case EAST: - case SOUTHEAST: - - if ( dXPos >= pSoldier->sDestXPos ) - { - fStop = TRUE; - } - break; - - case NORTHWEST: - case WEST: - case SOUTHWEST: - - if ( dXPos <= pSoldier->sDestXPos ) - { - fStop = TRUE; - } - break; - - case NORTH: - case SOUTH: + case NORTHEAST: + case EAST: + case SOUTHEAST: + if ( dXPos >= pSoldier->sDestXPos ) + { fStop = TRUE; - break; + } + break; + + case NORTHWEST: + case WEST: + case SOUTHWEST: + + if ( dXPos <= pSoldier->sDestXPos ) + { + fStop = TRUE; + } + break; + + case NORTH: + case SOUTH: + + fStop = TRUE; + break; } @@ -7826,31 +7900,31 @@ void MoveMerc( SOLDIERTYPE *pSoldier, FLOAT dMovementChange, FLOAT dAngle, BOOLE switch( pSoldier->bMovementDirection ) { - case NORTH: - case NORTHEAST: - case NORTHWEST: - - if ( dYPos <= pSoldier->sDestYPos ) - { - fStop = TRUE; - } - break; - - case SOUTH: - case SOUTHWEST: - case SOUTHEAST: - - if ( dYPos >= pSoldier->sDestYPos ) - { - fStop = TRUE; - } - break; - - case EAST: - case WEST: + case NORTH: + case NORTHEAST: + case NORTHWEST: + if ( dYPos <= pSoldier->sDestYPos ) + { fStop = TRUE; - break; + } + break; + + case SOUTH: + case SOUTHWEST: + case SOUTHEAST: + + if ( dYPos >= pSoldier->sDestYPos ) + { + fStop = TRUE; + } + break; + + case EAST: + case WEST: + + fStop = TRUE; + break; } @@ -7869,7 +7943,7 @@ void MoveMerc( SOLDIERTYPE *pSoldier, FLOAT dMovementChange, FLOAT dAngle, BOOLE // OK, set new position EVENT_InternalSetSoldierPosition( pSoldier, dXPos, dYPos, FALSE, FALSE, FALSE ); -// DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("X: %f Y: %f", dXPos, dYPos ) ); + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("X: %f Y: %f", dXPos, dYPos ) ); } @@ -7906,8 +7980,8 @@ INT16 GetDirectionFromXY( INT16 sXPos, INT16 sYPos, SOLDIERTYPE *pSoldier ) #if 0 UINT8 atan8( INT16 x1, INT16 y1, INT16 x2, INT16 y2 ) { -static int trig[8] = { 2, 3, 4, 5, 6, 7, 8, 1 }; -// returned values are N=1, NE=2, E=3, SE=4, S=5, SW=6, W=7, NW=8 + static int trig[8] = { 2, 3, 4, 5, 6, 7, 8, 1 }; + // returned values are N=1, NE=2, E=3, SE=4, S=5, SW=6, W=7, NW=8 double dx=(x2-x1); double dy=(y2-y1); double a; @@ -7919,9 +7993,9 @@ static int trig[8] = { 2, 3, 4, 5, 6, 7, 8, 1 }; i=(int)a; if (a>0) k=i; else - if (a<0) - k=i+(PISLICES-1); else - k=0; + if (a<0) + k=i+(PISLICES-1); else + k=0; return(trig[k]); } #endif @@ -7939,7 +8013,7 @@ UINT8 atan8( INT16 sXPos, INT16 sYPos, INT16 sXPos2, INT16 sYPos2 ) { test_x = 0.04; } - + angle = atan2( test_x, test_y ); @@ -8173,7 +8247,7 @@ BOOLEAN FullStructAlone( INT16 sGridNo, UINT8 ubRadius ) if ( iNewIndex >=0 && iNewIndex < WORLD_MAX && - iNewIndex >= leftmost && iNewIndex < ( leftmost + WORLD_COLS ) ) + iNewIndex >= leftmost && iNewIndex < ( leftmost + WORLD_COLS ) ) { if ( iNewIndex != sGridNo ) { @@ -8194,10 +8268,10 @@ BOOLEAN FullStructAlone( INT16 sGridNo, UINT8 ubRadius ) void AdjustForFastTurnAnimation( SOLDIERTYPE *pSoldier ) { - // CHECK FOR FASTTURN ANIMATIONS - // ATE: Mod: Only fastturn for OUR guys! - if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FASTTURN && pSoldier->bTeam == gbPlayerNum && !( pSoldier->uiStatusFlags & SOLDIER_TURNINGFROMHIT ) ) - { + // CHECK FOR FASTTURN ANIMATIONS + // ATE: Mod: Only fastturn for OUR guys! + if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FASTTURN && pSoldier->bTeam == gbPlayerNum && !( pSoldier->uiStatusFlags & SOLDIER_TURNINGFROMHIT ) ) + { if ( pSoldier->bDirection != pSoldier->bDesiredDirection ) { pSoldier->sAniDelay = FAST_TURN_ANIM_SPEED; @@ -8205,7 +8279,7 @@ void AdjustForFastTurnAnimation( SOLDIERTYPE *pSoldier ) else { SetSoldierAniSpeed( pSoldier ); - // FreeUpNPCFromTurning( pSoldier, LOOK); + // FreeUpNPCFromTurning( pSoldier, LOOK); } } @@ -8293,10 +8367,10 @@ void SendChangeSoldierStanceEvent( SOLDIERTYPE *pSoldier, UINT8 ubNewStance ) #if 0 EV_S_CHANGESTANCE SChangeStance; - #ifdef NETWORKED +#ifdef NETWORKED if( !IsTheSolderUnderMyControl( pSoldier->ubID) ) return; - #endif +#endif SChangeStance.ubNewStance = ubNewStance; SChangeStance.usSoldierID = pSoldier->ubID; @@ -8326,6 +8400,9 @@ void SendBeginFireWeaponEvent( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ) } +#if 0 +// This function is now obsolete. Just call ReduceAttackBusyCount. + // This function just encapolates the check for turnbased and having an attacker in the first place void ReleaseSoldiersAttacker( SOLDIERTYPE *pSoldier ) { @@ -8367,6 +8444,7 @@ void ReleaseSoldiersAttacker( SOLDIERTYPE *pSoldier ) } } } +#endif BOOLEAN MercInWater( SOLDIERTYPE *pSoldier ) { @@ -8390,8 +8468,8 @@ void RevivePlayerTeam( ) // End the turn of player charactors cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; - // look for all mercs on the same team, - for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++) + // look for all mercs on the same team, + for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++) { ReviveSoldier( pSoldier ); } @@ -8399,6 +8477,8 @@ void RevivePlayerTeam( ) } + +// What? A zombie function? void ReviveSoldier( SOLDIERTYPE *pSoldier ) { INT16 sX, sY; @@ -8438,7 +8518,7 @@ void ReviveSoldier( SOLDIERTYPE *pSoldier ) void HandleAnimationProfile( SOLDIERTYPE *pSoldier, UINT16 usAnimState, BOOLEAN fRemove ) { -//#if 0 + //#if 0 ANIM_PROF *pProfile; ANIM_PROF_DIR *pProfileDir; ANIM_PROF_TILE *pProfileTile; @@ -8495,7 +8575,7 @@ void HandleAnimationProfile( SOLDIERTYPE *pSoldier, UINT16 usAnimState, BOOLEAN } } -//#endif + //#endif } @@ -8516,7 +8596,7 @@ LEVELNODE *GetAnimProfileFlags( UINT16 sGridNo, UINT16 *usFlags, SOLDIERTYPE **p pNode = pGivenNode->pNext; } -//#if 0 + //#if 0 if ( pNode != NULL ) { @@ -8527,7 +8607,7 @@ LEVELNODE *GetAnimProfileFlags( UINT16 sGridNo, UINT16 *usFlags, SOLDIERTYPE **p } } -//#endif + //#endif return( pNode ); @@ -8621,8 +8701,9 @@ void EVENT_SoldierBeginBladeAttack( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 // Increment the number of people busy doing stuff because of an attack //if ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) ) //{ - gTacticalStatus.ubAttackBusyCount++; - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Begin blade attack: ATB %d", gTacticalStatus.ubAttackBusyCount) ); +// gTacticalStatus.ubAttackBusyCount++; + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Begin blade attack: ATB %d", gTacticalStatus.ubAttackBusyCount) ); + DebugAttackBusy( String( "Begin blade attack: ATB %d\n", gTacticalStatus.ubAttackBusyCount) ); //} @@ -8640,7 +8721,7 @@ void EVENT_SoldierBeginBladeAttack( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 // Is there an unconscious guy at gridno...... ubTargetID = WhoIsThere2( sGridNo, pSoldier->bTargetLevel ); - + if ( ubTargetID != NOBODY && ( ( MercPtrs[ ubTargetID ]->bLife < OKLIFE && MercPtrs[ ubTargetID ]->bLife > 0 ) || ( MercPtrs[ ubTargetID ]->bBreath < OKBREATH && MercPtrs[ ubTargetID ]->bCollapsed ) ) ) { pSoldier->uiPendingActionData4 = ubTargetID; @@ -8682,63 +8763,63 @@ void EVENT_SoldierBeginBladeAttack( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 // Look at stance of target switch( gAnimControl[ pTSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: - case ANIM_CROUCH: + case ANIM_STAND: + case ANIM_CROUCH: - // CHECK IF HE CAN SEE US, IF SO RANDOMIZE - if ( pTSoldier->bOppList[ pSoldier->ubID ] == 0 && pTSoldier->bTeam != pSoldier->bTeam ) + // CHECK IF HE CAN SEE US, IF SO RANDOMIZE + if ( pTSoldier->bOppList[ pSoldier->ubID ] == 0 && pTSoldier->bTeam != pSoldier->bTeam ) + { + // WE ARE NOT SEEN + EVENT_InitNewSoldierAnim( pSoldier, STAB, 0 , FALSE ); + } + else + { + // WE ARE SEEN + if ( Random( 50 ) > 25 ) { - // WE ARE NOT SEEN EVENT_InitNewSoldierAnim( pSoldier, STAB, 0 , FALSE ); } else { - // WE ARE SEEN - if ( Random( 50 ) > 25 ) - { - EVENT_InitNewSoldierAnim( pSoldier, STAB, 0 , FALSE ); - } - else - { - EVENT_InitNewSoldierAnim( pSoldier, SLICE, 0 , FALSE ); - } - - // IF WE ARE SEEN, MAKE SURE GUY TURNS! - // Get direction to target - // IF WE ARE AN ANIMAL, CAR, MONSTER, DONT'T TURN - if ( !( pTSoldier->uiStatusFlags & ( SOLDIER_MONSTER | SOLDIER_ANIMAL | SOLDIER_VEHICLE ) ) ) - { - // OK, stop merc.... - EVENT_StopMerc( pTSoldier, pTSoldier->sGridNo, pTSoldier->bDirection ); - - if ( pTSoldier->bTeam != gbPlayerNum ) - { - CancelAIAction( pTSoldier, TRUE ); - } - - ubTDirection = (UINT8)GetDirectionFromGridNo( pSoldier->sGridNo, pTSoldier ); - SendSoldierSetDesiredDirectionEvent( pTSoldier, ubTDirection ); - } + EVENT_InitNewSoldierAnim( pSoldier, SLICE, 0 , FALSE ); } - break; - - case ANIM_PRONE: - - // CHECK OUR STANCE - if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_CROUCH ) + // IF WE ARE SEEN, MAKE SURE GUY TURNS! + // Get direction to target + // IF WE ARE AN ANIMAL, CAR, MONSTER, DONT'T TURN + if ( !( pTSoldier->uiStatusFlags & ( SOLDIER_MONSTER | SOLDIER_ANIMAL | SOLDIER_VEHICLE ) ) ) { - // SET DESIRED STANCE AND SET PENDING ANIMATION - SendChangeSoldierStanceEvent( pSoldier, ANIM_CROUCH ); - pSoldier->usPendingAnimation = CROUCH_STAB; + // OK, stop merc.... + EVENT_StopMerc( pTSoldier, pTSoldier->sGridNo, pTSoldier->bDirection ); + + if ( pTSoldier->bTeam != gbPlayerNum ) + { + CancelAIAction( pTSoldier, TRUE ); + } + + ubTDirection = (UINT8)GetDirectionFromGridNo( pSoldier->sGridNo, pTSoldier ); + SendSoldierSetDesiredDirectionEvent( pTSoldier, ubTDirection ); } - else - { - // USE crouched one - // NEED TO CHANGE STANCE IF NOT CROUCHD! - EVENT_InitNewSoldierAnim( pSoldier, CROUCH_STAB, 0 , FALSE ); - } - break; + } + + break; + + case ANIM_PRONE: + + // CHECK OUR STANCE + if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_CROUCH ) + { + // SET DESIRED STANCE AND SET PENDING ANIMATION + SendChangeSoldierStanceEvent( pSoldier, ANIM_CROUCH ); + pSoldier->usPendingAnimation = CROUCH_STAB; + } + else + { + // USE crouched one + // NEED TO CHANGE STANCE IF NOT CROUCHD! + EVENT_InitNewSoldierAnim( pSoldier, CROUCH_STAB, 0 , FALSE ); + } + break; } } else @@ -8791,13 +8872,14 @@ void EVENT_SoldierBeginPunchAttack( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 // Get item in hand... usItem = pSoldier->inv[ HANDPOS ].usItem; - + // Increment the number of people busy doing stuff because of an attack //if ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) ) //{ - gTacticalStatus.ubAttackBusyCount++; - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Begin HTH attack: ATB %d", gTacticalStatus.ubAttackBusyCount) ); +// gTacticalStatus.ubAttackBusyCount++; + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Begin HTH attack: ATB %d", gTacticalStatus.ubAttackBusyCount) ); + DebugAttackBusy( String( "Begin HTH attack: ATB %d\n", gTacticalStatus.ubAttackBusyCount) ); //} @@ -8845,63 +8927,63 @@ void EVENT_SoldierBeginPunchAttack( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 // Look at stance of target switch( gAnimControl[ pTSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: - case ANIM_CROUCH: + case ANIM_STAND: + case ANIM_CROUCH: - if ( !Item[usItem].crowbar ) + if ( !Item[usItem].crowbar ) + { + EVENT_InitNewSoldierAnim( pSoldier, PUNCH, 0 , FALSE ); + } + else + { + EVENT_InitNewSoldierAnim( pSoldier, CROWBAR_ATTACK, 0 , FALSE ); + } + + // CHECK IF HE CAN SEE US, IF SO CHANGE DIR + if ( pTSoldier->bOppList[ pSoldier->ubID ] == 0 && pTSoldier->bTeam != pSoldier->bTeam ) + { + // Get direction to target + // IF WE ARE AN ANIMAL, CAR, MONSTER, DONT'T TURN + if ( !( pTSoldier->uiStatusFlags & ( SOLDIER_MONSTER | SOLDIER_ANIMAL | SOLDIER_VEHICLE ) ) ) { - EVENT_InitNewSoldierAnim( pSoldier, PUNCH, 0 , FALSE ); + // OK, stop merc.... + EVENT_StopMerc( pTSoldier, pTSoldier->sGridNo, pTSoldier->bDirection ); + + if ( pTSoldier->bTeam != gbPlayerNum ) + { + CancelAIAction( pTSoldier, TRUE ); + } + + ubTDirection = (UINT8)GetDirectionFromGridNo( pSoldier->sGridNo, pTSoldier ); + SendSoldierSetDesiredDirectionEvent( pTSoldier, ubTDirection ); + } + } + break; + + case ANIM_PRONE: + + // CHECK OUR STANCE + // ATE: Added this for CIV body types 'cause of elliot + if ( !IS_MERC_BODY_TYPE( pSoldier ) ) + { + EVENT_InitNewSoldierAnim( pSoldier, PUNCH, 0 , FALSE ); + } + else + { + if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_CROUCH ) + { + // SET DESIRED STANCE AND SET PENDING ANIMATION + SendChangeSoldierStanceEvent( pSoldier, ANIM_CROUCH ); + pSoldier->usPendingAnimation = PUNCH_LOW; } else { - EVENT_InitNewSoldierAnim( pSoldier, CROWBAR_ATTACK, 0 , FALSE ); + // USE crouched one + // NEED TO CHANGE STANCE IF NOT CROUCHD! + EVENT_InitNewSoldierAnim( pSoldier, PUNCH_LOW, 0 , FALSE ); } - - // CHECK IF HE CAN SEE US, IF SO CHANGE DIR - if ( pTSoldier->bOppList[ pSoldier->ubID ] == 0 && pTSoldier->bTeam != pSoldier->bTeam ) - { - // Get direction to target - // IF WE ARE AN ANIMAL, CAR, MONSTER, DONT'T TURN - if ( !( pTSoldier->uiStatusFlags & ( SOLDIER_MONSTER | SOLDIER_ANIMAL | SOLDIER_VEHICLE ) ) ) - { - // OK, stop merc.... - EVENT_StopMerc( pTSoldier, pTSoldier->sGridNo, pTSoldier->bDirection ); - - if ( pTSoldier->bTeam != gbPlayerNum ) - { - CancelAIAction( pTSoldier, TRUE ); - } - - ubTDirection = (UINT8)GetDirectionFromGridNo( pSoldier->sGridNo, pTSoldier ); - SendSoldierSetDesiredDirectionEvent( pTSoldier, ubTDirection ); - } - } - break; - - case ANIM_PRONE: - - // CHECK OUR STANCE - // ATE: Added this for CIV body types 'cause of elliot - if ( !IS_MERC_BODY_TYPE( pSoldier ) ) - { - EVENT_InitNewSoldierAnim( pSoldier, PUNCH, 0 , FALSE ); - } - else - { - if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_CROUCH ) - { - // SET DESIRED STANCE AND SET PENDING ANIMATION - SendChangeSoldierStanceEvent( pSoldier, ANIM_CROUCH ); - pSoldier->usPendingAnimation = PUNCH_LOW; - } - else - { - // USE crouched one - // NEED TO CHANGE STANCE IF NOT CROUCHD! - EVENT_InitNewSoldierAnim( pSoldier, PUNCH_LOW, 0 , FALSE ); - } - } - break; + } + break; } } @@ -8918,10 +9000,11 @@ void EVENT_SoldierBeginKnifeThrowAttack( SOLDIERTYPE *pSoldier, INT16 sGridNo, U // Increment the number of people busy doing stuff because of an attack //if ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) ) //{ - gTacticalStatus.ubAttackBusyCount++; +// gTacticalStatus.ubAttackBusyCount++; //} - pSoldier->bBulletsLeft = 1; +// pSoldier->bBulletsLeft = 1; DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting knifethrow attack, bullets left %d", pSoldier->bBulletsLeft) ); + DebugAttackBusy( String( "Begin knife throwing attack: ATB %d\n", gTacticalStatus.ubAttackBusyCount) ); EVENT_InitNewSoldierAnim( pSoldier, THROW_KNIFE, 0 , FALSE ); @@ -8945,17 +9028,17 @@ void EVENT_SoldierBeginDropBomb( SOLDIERTYPE *pSoldier ) // Increment the number of people busy doing stuff because of an attack switch( gAnimControl[ pSoldier->usAnimState ].ubHeight ) { - case ANIM_STAND: + case ANIM_STAND: - EVENT_InitNewSoldierAnim( pSoldier, PLANT_BOMB, 0 , FALSE ); - break; + EVENT_InitNewSoldierAnim( pSoldier, PLANT_BOMB, 0 , FALSE ); + break; - default: + default: - // Call hander for planting bomb... - HandleSoldierDropBomb( pSoldier, pSoldier->sPendingActionData2 ); - SoldierGotoStationaryStance( pSoldier ); - break; + // Call hander for planting bomb... + HandleSoldierDropBomb( pSoldier, pSoldier->sPendingActionData2 ); + SoldierGotoStationaryStance( pSoldier ); + break; } } @@ -8966,16 +9049,16 @@ void EVENT_SoldierBeginUseDetonator( SOLDIERTYPE *pSoldier ) // Increment the number of people busy doing stuff because of an attack switch( gAnimControl[ pSoldier->usAnimState ].ubHeight ) { - case ANIM_STAND: + case ANIM_STAND: - EVENT_InitNewSoldierAnim( pSoldier, USE_REMOTE, 0 , FALSE ); - break; + EVENT_InitNewSoldierAnim( pSoldier, USE_REMOTE, 0 , FALSE ); + break; - default: + default: - // Call hander for planting bomb... - HandleSoldierUseRemote( pSoldier, pSoldier->sPendingActionData2 ); - break; + // Call hander for planting bomb... + HandleSoldierUseRemote( pSoldier, pSoldier->sPendingActionData2 ); + break; } } @@ -9033,7 +9116,7 @@ void EVENT_SoldierBeginFirstAid( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubD // CHECK OUR STANCE AND GOTO CROUCH IF NEEDED //if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_CROUCH ) //{ - // SET DESIRED STANCE AND SET PENDING ANIMATION + // SET DESIRED STANCE AND SET PENDING ANIMATION // SendChangeSoldierStanceEvent( pSoldier, ANIM_CROUCH ); // pSoldier->usPendingAnimation = START_AID; //} @@ -9045,7 +9128,7 @@ void EVENT_SoldierBeginFirstAid( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubD // SET TARGET GRIDNO pSoldier->sTargetGridNo = sGridNo; - + // SET PARTNER ID pSoldier->ubServicePartner = (UINT8)usSoldierIndex; @@ -9081,208 +9164,208 @@ void EVENT_SoldierEnterVehicle( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubDi UINT32 SoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, INT16 sKitPts, INT16 sStatus ) { - UINT32 uiDressSkill, uiPossible, uiActual, uiMedcost, uiDeficiency, uiAvailAPs, uiUsedAPs; - UINT8 ubBelowOKlife, ubPtsLeft; - BOOLEAN fRanOut = FALSE; + UINT32 uiDressSkill, uiPossible, uiActual, uiMedcost, uiDeficiency, uiAvailAPs, uiUsedAPs; + UINT8 ubBelowOKlife, ubPtsLeft; + BOOLEAN fRanOut = FALSE; - if (pVictim->bBleeding < 1 && pVictim->bLife >= OKLIFE ) - { - return(0); // nothing to do, shouldn't have even been called! - } + if (pVictim->bBleeding < 1 && pVictim->bLife >= OKLIFE ) + { + return(0); // nothing to do, shouldn't have even been called! + } - if ( pVictim->bLife == 0 ) - { - return(0); - } + if ( pVictim->bLife == 0 ) + { + return(0); + } - // in case he has multiple kits in hand, limit influence of kit status to 100%! - if (sStatus >= 100) - { - sStatus = 100; - } + // in case he has multiple kits in hand, limit influence of kit status to 100%! + if (sStatus >= 100) + { + sStatus = 100; + } - // calculate wound-dressing skill (3x medical, 2x equip, 1x level, 1x dex) - uiDressSkill = ( ( 3 * EffectiveMedical( pSoldier ) ) + // medical knowledge - ( 2 * sStatus) + // state of medical kit - (10 * EffectiveExpLevel( pSoldier ) ) + // battle injury experience - EffectiveDexterity( pSoldier ) ) / 7; // general "handiness" + // calculate wound-dressing skill (3x medical, 2x equip, 1x level, 1x dex) + uiDressSkill = ( ( 3 * EffectiveMedical( pSoldier ) ) + // medical knowledge + ( 2 * sStatus) + // state of medical kit + (10 * EffectiveExpLevel( pSoldier ) ) + // battle injury experience + EffectiveDexterity( pSoldier ) ) / 7; // general "handiness" - // try to use every AP that the merc has left - uiAvailAPs = pSoldier->bActionPoints; + // try to use every AP that the merc has left + uiAvailAPs = pSoldier->bActionPoints; - // OK, If we are in real-time, use another value... - if (!(gTacticalStatus.uiFlags & TURNBASED) || !(gTacticalStatus.uiFlags & INCOMBAT ) ) - { - // Set to a value which looks good based on our tactical turns duration + // OK, If we are in real-time, use another value... + if (!(gTacticalStatus.uiFlags & TURNBASED) || !(gTacticalStatus.uiFlags & INCOMBAT ) ) + { + // Set to a value which looks good based on our tactical turns duration uiAvailAPs = RT_FIRST_AID_GAIN_MODIFIER; - } + } - // calculate how much bandaging CAN be done this turn - uiPossible = ( uiAvailAPs * uiDressSkill ) / 50; // max rate is 2 * fullAPs + // calculate how much bandaging CAN be done this turn + uiPossible = ( uiAvailAPs * uiDressSkill ) / 50; // max rate is 2 * fullAPs - // if no healing is possible (insufficient APs or insufficient dressSkill) - if (!uiPossible) - return(0); + // if no healing is possible (insufficient APs or insufficient dressSkill) + if (!uiPossible) + return(0); - if (Item[pSoldier->inv[ HANDPOS ].usItem].medicalkit ) // using the GOOD medic stuff - { - uiPossible += ( uiPossible / 2); // add extra 50 % - } + if (Item[pSoldier->inv[ HANDPOS ].usItem].medicalkit ) // using the GOOD medic stuff + { + uiPossible += ( uiPossible / 2); // add extra 50 % + } - uiActual = uiPossible; // start by assuming maximum possible + uiActual = uiPossible; // start by assuming maximum possible - // figure out how far below OKLIFE the victim is - if (pVictim->bLife >= OKLIFE) - { - ubBelowOKlife = 0; - } - else - { - ubBelowOKlife = OKLIFE - pVictim->bLife; - } + // figure out how far below OKLIFE the victim is + if (pVictim->bLife >= OKLIFE) + { + ubBelowOKlife = 0; + } + else + { + ubBelowOKlife = OKLIFE - pVictim->bLife; + } - // figure out how many healing pts we need to stop dying (2x cost) - uiDeficiency = (2 * ubBelowOKlife ); + // figure out how many healing pts we need to stop dying (2x cost) + uiDeficiency = (2 * ubBelowOKlife ); - // if, after that, the patient will still be bleeding - if ( (pVictim->bBleeding - ubBelowOKlife ) > 0) - { - // then add how many healing pts we need to stop bleeding (1x cost) - uiDeficiency += ( pVictim->bBleeding - ubBelowOKlife ); - } + // if, after that, the patient will still be bleeding + if ( (pVictim->bBleeding - ubBelowOKlife ) > 0) + { + // then add how many healing pts we need to stop bleeding (1x cost) + uiDeficiency += ( pVictim->bBleeding - ubBelowOKlife ); + } - // now, make sure we weren't going to give too much - if ( uiActual > uiDeficiency) // if we were about to apply too much - uiActual = uiDeficiency; // reduce actual not to waste anything + // now, make sure we weren't going to give too much + if ( uiActual > uiDeficiency) // if we were about to apply too much + uiActual = uiDeficiency; // reduce actual not to waste anything - // now make sure we HAVE that much - if (Item[pSoldier->inv[ HANDPOS ].usItem].medicalkit ) - { - uiMedcost = (uiActual + 1) / 2; // cost is only half, rounded up + // now make sure we HAVE that much + if (Item[pSoldier->inv[ HANDPOS ].usItem].medicalkit ) + { + uiMedcost = (uiActual + 1) / 2; // cost is only half, rounded up - if ( uiMedcost > (UINT32)sKitPts ) // if we can't afford this - { + if ( uiMedcost > (UINT32)sKitPts ) // if we can't afford this + { fRanOut = TRUE; uiMedcost = sKitPts; // what CAN we afford? uiActual = uiMedcost * 2; // give double this as aid - } - } - else - { - uiMedcost = uiActual; + } + } + else + { + uiMedcost = uiActual; - if ( uiMedcost > (UINT32)sKitPts) // can't afford it + if ( uiMedcost > (UINT32)sKitPts) // can't afford it { fRanOut = TRUE; - uiMedcost = uiActual = sKitPts; // recalc cost AND aid + uiMedcost = uiActual = sKitPts; // recalc cost AND aid } - } + } - ubPtsLeft = (UINT8)uiActual; + ubPtsLeft = (UINT8)uiActual; - // heal real life points first (if below OKLIFE) because we don't want the - // patient still DYING if bandages run out, or medic is disabled/distracted! - // NOTE: Dressing wounds for life below OKLIFE now costs 2 pts/life point! - if ( ubPtsLeft && pVictim->bLife < OKLIFE) - { - // if we have enough points to bring him all the way to OKLIFE this turn - if ( ubPtsLeft >= (2 * ubBelowOKlife ) ) - { - // raise life to OKLIFE - pVictim->bLife = OKLIFE; + // heal real life points first (if below OKLIFE) because we don't want the + // patient still DYING if bandages run out, or medic is disabled/distracted! + // NOTE: Dressing wounds for life below OKLIFE now costs 2 pts/life point! + if ( ubPtsLeft && pVictim->bLife < OKLIFE) + { + // if we have enough points to bring him all the way to OKLIFE this turn + if ( ubPtsLeft >= (2 * ubBelowOKlife ) ) + { + // raise life to OKLIFE + pVictim->bLife = OKLIFE; - // reduce bleeding by the same number of life points healed up - pVictim->bBleeding -= ubBelowOKlife; + // reduce bleeding by the same number of life points healed up + pVictim->bBleeding -= ubBelowOKlife; - // use up appropriate # of actual healing points - ubPtsLeft -= (2 * ubBelowOKlife); - } - else - { - pVictim->bLife += ( ubPtsLeft / 2); - pVictim->bBleeding -= ( ubPtsLeft / 2); + // use up appropriate # of actual healing points + ubPtsLeft -= (2 * ubBelowOKlife); + } + else + { + pVictim->bLife += ( ubPtsLeft / 2); + pVictim->bBleeding -= ( ubPtsLeft / 2); - ubPtsLeft = ubPtsLeft % 2; // if ptsLeft was odd, ptsLeft = 1 - } + ubPtsLeft = ubPtsLeft % 2; // if ptsLeft was odd, ptsLeft = 1 + } - // this should never happen any more, but make sure bleeding not negative - if (pVictim->bBleeding < 0) - { - pVictim->bBleeding = 0; - } + // this should never happen any more, but make sure bleeding not negative + if (pVictim->bBleeding < 0) + { + pVictim->bBleeding = 0; + } - // if this healing brought the patient out of the worst of it, cancel dying - if (pVictim->bLife >= OKLIFE ) - { - //pVictim->dying = pVictim->dyingComment = FALSE; - //pVictim->shootOn = TRUE; + // if this healing brought the patient out of the worst of it, cancel dying + if (pVictim->bLife >= OKLIFE ) + { + //pVictim->dying = pVictim->dyingComment = FALSE; + //pVictim->shootOn = TRUE; - // turn off merc QUOTE flags - pVictim->fDyingComment = FALSE; + // turn off merc QUOTE flags + pVictim->fDyingComment = FALSE; - } + } - // update patient's entire panel (could have regained consciousness, etc.) - } + // update patient's entire panel (could have regained consciousness, etc.) + } - // if any healing points remain, apply that to any remaining bleeding (1/1) - // DON'T spend any APs/kit pts to cure bleeding until merc is no longer dying - //if ( ubPtsLeft && pVictim->bBleeding && !pVictim->dying) - if ( ubPtsLeft && pVictim->bBleeding ) - { - // if we have enough points to bandage all remaining bleeding this turn - if (ubPtsLeft >= pVictim->bBleeding ) - { - ubPtsLeft -= pVictim->bBleeding; - pVictim->bBleeding = 0; - } - else // bandage what we can - { - pVictim->bBleeding -= ubPtsLeft; - ubPtsLeft = 0; - } + // if any healing points remain, apply that to any remaining bleeding (1/1) + // DON'T spend any APs/kit pts to cure bleeding until merc is no longer dying + //if ( ubPtsLeft && pVictim->bBleeding && !pVictim->dying) + if ( ubPtsLeft && pVictim->bBleeding ) + { + // if we have enough points to bandage all remaining bleeding this turn + if (ubPtsLeft >= pVictim->bBleeding ) + { + ubPtsLeft -= pVictim->bBleeding; + pVictim->bBleeding = 0; + } + else // bandage what we can + { + pVictim->bBleeding -= ubPtsLeft; + ubPtsLeft = 0; + } - // update patient's life bar only - } + // update patient's life bar only + } - // if wound has been dressed enough so that bleeding won't occur, turn off - // the "warned about bleeding" flag so merc tells us about the next bleeding - if ( pVictim->bBleeding <= MIN_BLEEDING_THRESHOLD ) - { - pVictim->fWarnedAboutBleeding = FALSE; - } + // if wound has been dressed enough so that bleeding won't occur, turn off + // the "warned about bleeding" flag so merc tells us about the next bleeding + if ( pVictim->bBleeding <= MIN_BLEEDING_THRESHOLD ) + { + pVictim->fWarnedAboutBleeding = FALSE; + } - // if there are any ptsLeft now, then we didn't actually get to use them - uiActual -= ubPtsLeft; + // if there are any ptsLeft now, then we didn't actually get to use them + uiActual -= ubPtsLeft; - // usedAPs equals (actionPts) * (%of possible points actually used) - uiUsedAPs = ( uiActual * uiAvailAPs ) / uiPossible; + // usedAPs equals (actionPts) * (%of possible points actually used) + uiUsedAPs = ( uiActual * uiAvailAPs ) / uiPossible; - if (Item[pSoldier->inv[ HANDPOS ].usItem].medicalkit ) // using the GOOD medic stuff - { - uiUsedAPs = ( uiUsedAPs * 2) / 3; // reverse 50% bonus by taking 2/3rds - } + if (Item[pSoldier->inv[ HANDPOS ].usItem].medicalkit ) // using the GOOD medic stuff + { + uiUsedAPs = ( uiUsedAPs * 2) / 3; // reverse 50% bonus by taking 2/3rds + } - DeductPoints( pSoldier, (INT16)uiUsedAPs, (INT16)( ( uiUsedAPs * BP_PER_AP_LT_EFFORT) ) ); + DeductPoints( pSoldier, (INT16)uiUsedAPs, (INT16)( ( uiUsedAPs * BP_PER_AP_LT_EFFORT) ) ); - if ( PTR_OURTEAM ) - { - // MEDICAL GAIN (actual / 2): Helped someone by giving first aid - StatChange(pSoldier, MEDICALAMT, (UINT16)(uiActual / 2), FALSE); + if ( PTR_OURTEAM ) + { + // MEDICAL GAIN (actual / 2): Helped someone by giving first aid + StatChange(pSoldier, MEDICALAMT, (UINT16)(uiActual / 2), FALSE); - // DEXTERITY GAIN (actual / 6): Helped someone by giving first aid - StatChange(pSoldier, DEXTAMT, (UINT16)(uiActual / 6), FALSE); - } + // DEXTERITY GAIN (actual / 6): Helped someone by giving first aid + StatChange(pSoldier, DEXTAMT, (UINT16)(uiActual / 6), FALSE); + } - return( uiMedcost ); + return( uiMedcost ); } @@ -9292,10 +9375,10 @@ void InternalReceivingSoldierCancelServices( SOLDIERTYPE *pSoldier, BOOLEAN fPla INT32 cnt; if ( pSoldier->ubServiceCount > 0 ) - { - // Loop through guys who have us as servicing - for ( pTSoldier = Menptr, cnt = 0; cnt < MAX_NUM_SOLDIERS; pTSoldier++, cnt++ ) - { + { + // Loop through guys who have us as servicing + for ( pTSoldier = Menptr, cnt = 0; cnt < MAX_NUM_SOLDIERS; pTSoldier++, cnt++ ) + { if ( pTSoldier->bActive ) { if ( pTSoldier->ubServicePartner == pSoldier->ubID ) @@ -9323,7 +9406,7 @@ void InternalReceivingSoldierCancelServices( SOLDIERTYPE *pSoldier, BOOLEAN fPla } } - } + } } @@ -9360,8 +9443,8 @@ void InternalGivingSoldierCancelServices( SOLDIERTYPE *pSoldier, BOOLEAN fPlayEn { if ( pSoldier->bLife >= OKLIFE && pSoldier->bBreath > 0 && fPlayEndAnim ) { - // don't use end aid animation in autobandage - EVENT_InitNewSoldierAnim( pSoldier, END_AID, 0 , FALSE ); + // don't use end aid animation in autobandage + EVENT_InitNewSoldierAnim( pSoldier, END_AID, 0 , FALSE ); } } } @@ -9396,14 +9479,14 @@ void HaultSoldierFromSighting( SOLDIERTYPE *pSoldier, BOOLEAN fFromSightingEnemy { // Place it back into inv.... AutoPlaceObject( pSoldier, pSoldier->pTempObject, FALSE ); - + //AXP 25.03.2007: Not needed anymore, grenade costs are only deducted on throwing the object //AXP 24.03.2007: Give APs back if we wanted to throw grenade, but interrupt/spotting occured //if ( pSoldier->pThrowParams->ubActionCode == THROW_ARM_ITEM ) //{ // DeductPoints( pSoldier, -MinAPsToAttack( pSoldier, pSoldier->sTargetGridNo, FALSE ), 0 ); //} - + MemFree( pSoldier->pTempObject ); pSoldier->pTempObject = NULL; pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; @@ -9411,14 +9494,15 @@ void HaultSoldierFromSighting( SOLDIERTYPE *pSoldier, BOOLEAN fFromSightingEnemy // Decrement attack counter... DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., ending throw because saw something") ); - ReduceAttackBusyCount( pSoldier->ubID, FALSE ); + DebugAttackBusy("@@@@@@@ Reducing attacker busy count..., ending throw because saw something\n"); + FreeUpAttacker( ); // ATE: Goto stationary stance...... SoldierGotoStationaryStance( pSoldier ); DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); } - + // Kaiden: Added fix from UB for seeing new enemies when throwing Knives. // ATE: Dave, don't kill me @@ -9428,7 +9512,8 @@ void HaultSoldierFromSighting( SOLDIERTYPE *pSoldier, BOOLEAN fFromSightingEnemy { // Decrement attack counter... DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., ending throw knife because saw something") ); - ReduceAttackBusyCount( pSoldier->ubID, FALSE ); + DebugAttackBusy("@@@@@@@ Reducing attacker busy count..., ending throw knife because saw something"); + FreeUpAttacker( ); // ATE: Goto stationary stance...... SoldierGotoStationaryStance( pSoldier ); @@ -9460,9 +9545,11 @@ void HaultSoldierFromSighting( SOLDIERTYPE *pSoldier, BOOLEAN fFromSightingEnemy // things that can happen - 1 of them is that sLastTarget will get unset // after turn is done - so set flag here to tell it not to... pSoldier->fDontUnsetLastTargetFromTurn = TRUE; - + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., ending fire because saw something") ); - ReduceAttackBusyCount( pSoldier->ubID, FALSE ); + DebugAttackBusy("@@@@@@@ Reducing attacker busy count..., ending fire because saw something\n"); + FreeUpAttacker( ); + } // OK, if we are stopped at our destination, cancel pending action... @@ -9482,10 +9569,10 @@ void HaultSoldierFromSighting( SOLDIERTYPE *pSoldier, BOOLEAN fFromSightingEnemy pSoldier->fContinueMoveAfterStanceChange = FALSE; } - if ( !pSoldier->fTurningToShoot ) - { - pSoldier->fTurningFromPronePosition = FALSE; - } + if ( !pSoldier->fTurningToShoot ) + { + pSoldier->fTurningFromPronePosition = FALSE; + } } // Unset UI! @@ -9525,7 +9612,7 @@ void EVENT_StopMerc( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bDirection ) // Cancel path data! pSoldier->usPathIndex = pSoldier->usPathDataSize = 0; - + // Set ext tile waiting flag off! pSoldier->fDelayedMovement = FALSE; @@ -9536,7 +9623,7 @@ void EVENT_StopMerc( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bDirection ) pSoldier->sDestXPos = (INT16)pSoldier->dXPos; pSoldier->sDestYPos = (INT16)pSoldier->dYPos; EVENT_SetSoldierDirection(pSoldier, bDirection); - + if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_MOVING ) { SoldierGotoStationaryStance( pSoldier ); @@ -9548,7 +9635,8 @@ void EVENT_StopMerc( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bDirection ) pSoldier->fTurningToShoot = FALSE; // Release attacker DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., ending fire because saw something") ); - ReduceAttackBusyCount( pSoldier->ubID, FALSE ); + DebugAttackBusy("@@@@@@@ Reducing attacker busy count..., ending fire because saw something\n"); + FreeUpAttacker( ); } // Turn off multi-move speed override.... @@ -9572,7 +9660,7 @@ void ReLoadSoldierAnimationDueToHandItemChange( SOLDIERTYPE *pSoldier, UINT16 us // CHECK FOR AIMING ANIMATIONS BOOLEAN fOldRifle = FALSE; BOOLEAN fNewRifle = FALSE; - + // Shutoff burst.... // ( we could be on, then change gun that does not have burst ) if ( Weapon[ usNewItem ].ubShotsPerBurst == 0 && !Weapon[pSoldier->inv[HANDPOS].usItem ].NoSemiAuto ) @@ -9602,7 +9690,7 @@ void ReLoadSoldierAnimationDueToHandItemChange( SOLDIERTYPE *pSoldier, UINT16 us { if ( Item[ usOldItem ].usItemClass == IC_GUN ) { -// if ( (Item[ usOldItem ].fFlags & ITEM_TWO_HANDED) && usOldItem != ROCKET_LAUNCHER ) + // if ( (Item[ usOldItem ].fFlags & ITEM_TWO_HANDED) && usOldItem != ROCKET_LAUNCHER ) if ( (Item[ usOldItem ].twohanded ) && !Item[usOldItem].rocketlauncher ) { fOldRifle = TRUE; @@ -9614,7 +9702,7 @@ void ReLoadSoldierAnimationDueToHandItemChange( SOLDIERTYPE *pSoldier, UINT16 us { if ( Item[ usNewItem ].usItemClass == IC_GUN ) { -// if ( (Item[ usNewItem ].fFlags & ITEM_TWO_HANDED) && usNewItem != ROCKET_LAUNCHER ) + // if ( (Item[ usNewItem ].fFlags & ITEM_TWO_HANDED) && usNewItem != ROCKET_LAUNCHER ) if ( (Item[ usNewItem ].twohanded ) && !Item[usNewItem].rocketlauncher ) { fNewRifle = TRUE; @@ -9625,29 +9713,29 @@ void ReLoadSoldierAnimationDueToHandItemChange( SOLDIERTYPE *pSoldier, UINT16 us // Switch on stance! switch( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: - - if ( fOldRifle && !fNewRifle ) - { - // Put it away! - EVENT_InitNewSoldierAnim( pSoldier, LOWER_RIFLE, 0 , FALSE ); - } - else if ( !fOldRifle && fNewRifle ) - { - // Bring it up! - EVENT_InitNewSoldierAnim( pSoldier, RAISE_RIFLE, 0 , FALSE ); - } - else - { - SetSoldierAnimationSurface( pSoldier, pSoldier->usAnimState ); - } - break; - - case ANIM_CROUCH: - case ANIM_PRONE: + case ANIM_STAND: + if ( fOldRifle && !fNewRifle ) + { + // Put it away! + EVENT_InitNewSoldierAnim( pSoldier, LOWER_RIFLE, 0 , FALSE ); + } + else if ( !fOldRifle && fNewRifle ) + { + // Bring it up! + EVENT_InitNewSoldierAnim( pSoldier, RAISE_RIFLE, 0 , FALSE ); + } + else + { SetSoldierAnimationSurface( pSoldier, pSoldier->usAnimState ); - break; + } + break; + + case ANIM_CROUCH: + case ANIM_PRONE: + + SetSoldierAnimationSurface( pSoldier, pSoldier->usAnimState ); + break; } } @@ -9708,7 +9796,7 @@ UINT16 *CreateEnemyGlow16BPPPalette( SGPPaletteEntry *pPalette, UINT32 rscale, U return( p16BPPPalette ); } - + UINT16 *CreateEnemyGreyGlow16BPPPalette( SGPPaletteEntry *pPalette, UINT32 rscale, UINT32 gscale, BOOLEAN fAdjustGreen ) { UINT16 *p16BPPPalette, r16, g16, b16, usColor; @@ -9824,7 +9912,7 @@ BOOLEAN CheckForBreathCollapse( SOLDIERTYPE *pSoldier ) if ( pSoldier->bBreathMax > 70 ) { if ( pSoldier->bBreath < 20 && !(pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_LOW_BREATH ) && - gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND ) + gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND ) { // WARN! TacticalCharacterDialogue( pSoldier, QUOTE_OUT_OF_BREATH ); @@ -9837,14 +9925,14 @@ BOOLEAN CheckForBreathCollapse( SOLDIERTYPE *pSoldier ) // Check for drowing..... //if ( pSoldier->bBreath < 10 && !(pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_DROWNING ) && pSoldier->bOverTerrainType == DEEP_WATER ) //{ - // WARN! + // WARN! // TacticalCharacterDialogue( pSoldier, QUOTE_DROWNING ); - - // Set flag indicating we were warned! + + // Set flag indicating we were warned! // pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_DROWNING; - // WISDOM GAIN (25): Starting to drown - // StatChange( pSoldier, WISDOMAMT, 25, FALSE ); + // WISDOM GAIN (25): Starting to drown + // StatChange( pSoldier, WISDOMAMT, 25, FALSE ); //} @@ -9885,10 +9973,10 @@ BOOLEAN InternalIsValidStance( SOLDIERTYPE *pSoldier, INT8 bDirection, INT8 bNew } } - if ( pSoldier->ubBodyType == ROBOTNOWEAPON && bNewStance != ANIM_STAND ) - { - return( FALSE ); - } + if ( pSoldier->ubBodyType == ROBOTNOWEAPON && bNewStance != ANIM_STAND ) + { + return( FALSE ); + } // Check if we are in water? if ( AM_AN_EPC( pSoldier ) ) @@ -9924,27 +10012,27 @@ BOOLEAN InternalIsValidStance( SOLDIERTYPE *pSoldier, INT8 bDirection, INT8 bNew switch( bNewStance ) { - case ANIM_STAND: + case ANIM_STAND: - usAnimState = STANDING; - break; + usAnimState = STANDING; + break; - case ANIM_CROUCH: + case ANIM_CROUCH: - usAnimState = CROUCHING; - break; + usAnimState = CROUCHING; + break; - case ANIM_PRONE: + case ANIM_PRONE: - usAnimState = PRONE; - break; + usAnimState = PRONE; + break; - default: + default: - // Something gone funny here.... - usAnimState = pSoldier->usAnimState; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Wrong desired stance given: %d, %d.", bNewStance, pSoldier->usAnimState ); + // Something gone funny here.... + usAnimState = pSoldier->usAnimState; + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Wrong desired stance given: %d, %d.", bNewStance, pSoldier->usAnimState ); } usAnimSurface = DetermineSoldierAnimationSurface( pSoldier, usAnimState ); @@ -9993,17 +10081,17 @@ void SelectMoveAnimationFromStance( SOLDIERTYPE *pSoldier ) // Determine which animation to do...depending on stance and gun in hand... switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: - EVENT_InitNewSoldierAnim( pSoldier, WALKING, 0 , FALSE ); - break; + case ANIM_STAND: + EVENT_InitNewSoldierAnim( pSoldier, WALKING, 0 , FALSE ); + break; - case ANIM_PRONE: - EVENT_InitNewSoldierAnim( pSoldier, CRAWLING, 0 , FALSE ); - break; + case ANIM_PRONE: + EVENT_InitNewSoldierAnim( pSoldier, CRAWLING, 0 , FALSE ); + break; - case ANIM_CROUCH: - EVENT_InitNewSoldierAnim( pSoldier, SWATTING, 0 , FALSE ); - break; + case ANIM_CROUCH: + EVENT_InitNewSoldierAnim( pSoldier, SWATTING, 0 , FALSE ); + break; } @@ -10021,7 +10109,7 @@ void GetActualSoldierAnimDims( SOLDIERTYPE *pSoldier, INT16 *psHeight, INT16 *ps { *psHeight = (INT16)5; *psWidth = (INT16)5; - + return; } @@ -10063,12 +10151,12 @@ void GetActualSoldierAnimOffsets( SOLDIERTYPE *pSoldier, INT16 *sOffsetX, INT16 return; } - if ( gAnimSurfaceDatabase[ usAnimSurface ].hVideoObject == NULL ) - { + if ( gAnimSurfaceDatabase[ usAnimSurface ].hVideoObject == NULL ) + { *sOffsetX = (INT16)0; *sOffsetY = (INT16)0; return; - } + } pTrav = &(gAnimSurfaceDatabase[ usAnimSurface ].hVideoObject->pETRLEObject[ pSoldier->usAniFrame ] ); @@ -10103,7 +10191,7 @@ BOOLEAN SoldierCarriesTwoHandedWeapon( SOLDIERTYPE *pSoldier ) usItem = pSoldier->inv[ HANDPOS ].usItem; -// if ( usItem != NOTHING && (Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) + // if ( usItem != NOTHING && (Item[ usItem ].fFlags & ITEM_TWO_HANDED) ) if ( usItem != NOTHING && (Item[ usItem ].twohanded ) ) { return( TRUE ); @@ -10117,44 +10205,44 @@ BOOLEAN SoldierCarriesTwoHandedWeapon( SOLDIERTYPE *pSoldier ) INT32 CheckBleeding( SOLDIERTYPE *pSoldier ) { - INT8 bBandaged; //,savedOurTurn; - INT32 iBlood = NOBLOOD; + INT8 bBandaged; //,savedOurTurn; + INT32 iBlood = NOBLOOD; - if ( pSoldier->bLife != 0 ) - { - // if merc is hurt beyond the minimum required to bleed, or he's dying - if ( ( pSoldier->bBleeding > MIN_BLEEDING_THRESHOLD) || pSoldier->bLife < OKLIFE ) - { + if ( pSoldier->bLife != 0 ) + { + // if merc is hurt beyond the minimum required to bleed, or he's dying + if ( ( pSoldier->bBleeding > MIN_BLEEDING_THRESHOLD) || pSoldier->bLife < OKLIFE ) + { // if he's NOT in the process of being bandaged or DOCTORed if ( ( pSoldier->ubServiceCount == 0 ) && ( AnyDoctorWhoCanHealThisPatient( pSoldier, HEALABLE_EVER ) == NULL ) ) { - // may drop blood whether or not any bleeding takes place this turn - if ( pSoldier->bTilesMoved < 1 ) + // may drop blood whether or not any bleeding takes place this turn + if ( pSoldier->bTilesMoved < 1 ) { iBlood = ( ( pSoldier->bBleeding - MIN_BLEEDING_THRESHOLD ) / BLOODDIVISOR ); // + pSoldier->dying; if ( iBlood > MAXBLOODQUANTITY ) { - iBlood = MAXBLOODQUANTITY; + iBlood = MAXBLOODQUANTITY; } } - else + else { iBlood = NOBLOOD; } - // Are we in a different mode? - if ( !(gTacticalStatus.uiFlags & TURNBASED ) || !(gTacticalStatus.uiFlags & INCOMBAT ) ) + // Are we in a different mode? + if ( !(gTacticalStatus.uiFlags & TURNBASED ) || !(gTacticalStatus.uiFlags & INCOMBAT ) ) { pSoldier->dNextBleed -= (FLOAT)RT_NEXT_BLEED_MODIFIER; } - else + else { // Do a single step descrease pSoldier->dNextBleed--; } - // if it's time to lose some blood - if ( pSoldier->dNextBleed <= 0) + // if it's time to lose some blood + if ( pSoldier->dNextBleed <= 0) { // first, calculate if soldier is bandaged bBandaged = pSoldier->bLifeMax - pSoldier->bBleeding - pSoldier->bLife; @@ -10183,23 +10271,23 @@ INT32 CheckBleeding( SOLDIERTYPE *pSoldier ) // soldier might as well be dead! if (pSoldier->bLifeMax >= OKLIFE) { - // bleeding while "dying" costs a PERMANENT point of life each time! - pSoldier->bLifeMax--; - pSoldier->bBleeding--; + // bleeding while "dying" costs a PERMANENT point of life each time! + pSoldier->bLifeMax--; + pSoldier->bBleeding--; } } } - // either way, a point of life (health) is lost because of bleeding - // This will also update the life bar + // either way, a point of life (health) is lost because of bleeding + // This will also update the life bar - SoldierBleed( pSoldier, FALSE ); + SoldierBleed( pSoldier, FALSE ); - // if he's not dying (which includes him saying the dying quote just - // now), and he hasn't warned us that he's bleeding yet, he does so - // Also, not if they are being bandaged.... - if ( ( pSoldier->bLife >= OKLIFE ) && !pSoldier->fDyingComment && !pSoldier->fWarnedAboutBleeding && !gTacticalStatus.fAutoBandageMode && pSoldier->ubServiceCount == 0 ) + // if he's not dying (which includes him saying the dying quote just + // now), and he hasn't warned us that he's bleeding yet, he does so + // Also, not if they are being bandaged.... + if ( ( pSoldier->bLife >= OKLIFE ) && !pSoldier->fDyingComment && !pSoldier->fWarnedAboutBleeding && !gTacticalStatus.fAutoBandageMode && pSoldier->ubServiceCount == 0 ) { TacticalCharacterDialogue( pSoldier, QUOTE_STARTING_TO_BLEED ); @@ -10207,13 +10295,13 @@ INT32 CheckBleeding( SOLDIERTYPE *pSoldier ) pSoldier->fWarnedAboutBleeding = TRUE; } - pSoldier->dNextBleed = CalcSoldierNextBleed( pSoldier ); + pSoldier->dNextBleed = CalcSoldierNextBleed( pSoldier ); } } } } - return( iBlood ); + return( iBlood ); } @@ -10261,82 +10349,82 @@ void SoldierCollapse( SOLDIERTYPE *pSoldier ) // If we are an animal, etc, don't do anything.... switch( pSoldier->ubBodyType ) { - case ADULTFEMALEMONSTER: - case AM_MONSTER: - case YAF_MONSTER: - case YAM_MONSTER: - case LARVAE_MONSTER: - case INFANT_MONSTER: - case QUEENMONSTER: + case ADULTFEMALEMONSTER: + case AM_MONSTER: + case YAF_MONSTER: + case YAM_MONSTER: + case LARVAE_MONSTER: + case INFANT_MONSTER: + case QUEENMONSTER: - // Give breath back.... - DeductPoints( pSoldier,0, (INT16)-5000 ); - return; - break; + // Give breath back.... + DeductPoints( pSoldier,0, (INT16)-5000 ); + return; + break; } pSoldier->bCollapsed = TRUE; ReceivingSoldierCancelServices( pSoldier ); - // CC has requested - handle sight here... + // CC has requested - handle sight here... HandleSight( pSoldier, SIGHT_LOOK ); // Check height switch( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: + case ANIM_STAND: - if ( pSoldier->bOverTerrainType == DEEP_WATER ) - { - EVENT_InitNewSoldierAnim( pSoldier, DEEP_WATER_DIE, 0, FALSE ); - } - else if ( pSoldier->bOverTerrainType == LOW_WATER ) - { - EVENT_InitNewSoldierAnim( pSoldier, WATER_DIE, 0, FALSE ); - } - else - { - BeginTyingToFall( pSoldier ); - EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0, FALSE ); - } - break; + if ( pSoldier->bOverTerrainType == DEEP_WATER ) + { + EVENT_InitNewSoldierAnim( pSoldier, DEEP_WATER_DIE, 0, FALSE ); + } + else if ( pSoldier->bOverTerrainType == LOW_WATER ) + { + EVENT_InitNewSoldierAnim( pSoldier, WATER_DIE, 0, FALSE ); + } + else + { + BeginTyingToFall( pSoldier ); + EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0, FALSE ); + } + break; - case ANIM_CROUCH: + case ANIM_CROUCH: - // Crouched or prone, only for mercs! - BeginTyingToFall( pSoldier ); + // Crouched or prone, only for mercs! + BeginTyingToFall( pSoldier ); - if ( fMerc ) - { - EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_CROUCH, 0 , FALSE); - } - else - { - // For civs... use fall from stand... - EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0 , FALSE); - } - break; + if ( fMerc ) + { + EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_CROUCH, 0 , FALSE); + } + else + { + // For civs... use fall from stand... + EVENT_InitNewSoldierAnim( pSoldier, FALLFORWARD_FROMHIT_STAND, 0 , FALSE); + } + break; - case ANIM_PRONE: + case ANIM_PRONE: - switch( pSoldier->usAnimState ) - { - case FALLFORWARD_FROMHIT_STAND: - case ENDFALLFORWARD_FROMHIT_CROUCH: + switch( pSoldier->usAnimState ) + { + case FALLFORWARD_FROMHIT_STAND: + case ENDFALLFORWARD_FROMHIT_CROUCH: - ChangeSoldierState( pSoldier, STAND_FALLFORWARD_STOP, 0, FALSE ); - break; + ChangeSoldierState( pSoldier, STAND_FALLFORWARD_STOP, 0, FALSE ); + break; - case FALLBACK_HIT_STAND: - ChangeSoldierState( pSoldier, FALLBACKHIT_STOP, 0, FALSE ); - break; + case FALLBACK_HIT_STAND: + ChangeSoldierState( pSoldier, FALLBACKHIT_STOP, 0, FALSE ); + break; - default: - EVENT_InitNewSoldierAnim( pSoldier, PRONE_LAY_FROMHIT, 0 , FALSE ); - break; - } - break; + default: + EVENT_InitNewSoldierAnim( pSoldier, PRONE_LAY_FROMHIT, 0 , FALSE ); + break; + } + break; } if (pSoldier->uiStatusFlags & SOLDIER_ENEMY) @@ -10351,9 +10439,9 @@ void SoldierCollapse( SOLDIERTYPE *pSoldier ) if ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) && (pSoldier->uiStatusFlags & SOLDIER_UNDERAICONTROL)) { - #ifdef TESTAICONTROL +#ifdef TESTAICONTROL DebugAI( String("Ending turn for %d because of error from HandleItem", pSoldier->ubID ) ); - #endif +#endif EndAIGuysTurn( pSoldier ); } @@ -10362,7 +10450,7 @@ void SoldierCollapse( SOLDIERTYPE *pSoldier ) // DON'T DE-SELECT GUY..... //else //{ - // Check if this is our selected guy... + // Check if this is our selected guy... // if ( pSoldier->ubID == gusSelectedSoldier ) // { // SelectNextAvailSoldier( pSoldier ); @@ -10393,7 +10481,7 @@ FLOAT CalcSoldierNextUnmovingBleed( SOLDIERTYPE *pSoldier ) // if bandaged, give 1/2 of the bandaged life points back into equation bBandaged = pSoldier->bLifeMax - pSoldier->bLife - pSoldier->bBleeding; - + return( (FLOAT)1 + (FLOAT)( (pSoldier->bLife + bBandaged / 2) / 10 ) ); // min = 1 } @@ -10511,7 +10599,7 @@ void PositionSoldierLight( SOLDIERTYPE *pSoldier ) void SetCheckSoldierLightFlag( SOLDIERTYPE *pSoldier ) { - PositionSoldierLight( pSoldier ); + PositionSoldierLight( pSoldier ); //pSoldier->uiStatusFlags |= SOLDIER_RECHECKLIGHT; } @@ -10560,74 +10648,74 @@ void PickPickupAnimation( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT16 sGridNo // Don't show animation of getting item, if we are not standing switch ( gAnimControl[ pSoldier->usAnimState ].ubHeight ) { - case ANIM_STAND: - - // OK, if we are looking at z-level >0, AND - // we have a strucxture with items in it - // look for orientation and use angle accordingly.... - if ( bZLevel > 0 ) + case ANIM_STAND: + + // OK, if we are looking at z-level >0, AND + // we have a strucxture with items in it + // look for orientation and use angle accordingly.... + if ( bZLevel > 0 ) + { + //#if 0 + // Get direction to face.... + if ( ( pStructure = FindStructure( (INT16)sGridNo, ( STRUCTURE_HASITEMONTOP | STRUCTURE_OPENABLE ) ) ) != NULL ) { -//#if 0 - // Get direction to face.... - if ( ( pStructure = FindStructure( (INT16)sGridNo, ( STRUCTURE_HASITEMONTOP | STRUCTURE_OPENABLE ) ) ) != NULL ) + fDoNormalPickup = FALSE; + + // OK, look at orientation + switch( pStructure->ubWallOrientation ) { - fDoNormalPickup = FALSE; + case OUTSIDE_TOP_LEFT: + case INSIDE_TOP_LEFT: - // OK, look at orientation - switch( pStructure->ubWallOrientation ) - { - case OUTSIDE_TOP_LEFT: - case INSIDE_TOP_LEFT: + bDirection = (INT8)NORTH; + break; - bDirection = (INT8)NORTH; - break; + case OUTSIDE_TOP_RIGHT: + case INSIDE_TOP_RIGHT: - case OUTSIDE_TOP_RIGHT: - case INSIDE_TOP_RIGHT: + bDirection = (INT8)WEST; + break; - bDirection = (INT8)WEST; - break; + default: - default: - - bDirection = pSoldier->bDirection; - break; - } - - //pSoldier->ubPendingDirection = bDirection; - EVENT_SetSoldierDesiredDirection( pSoldier, bDirection ); - EVENT_SetSoldierDirection( pSoldier, bDirection ); - - // Change to pickup animation - EVENT_InitNewSoldierAnim( pSoldier, ADJACENT_GET_ITEM, 0 , FALSE ); + bDirection = pSoldier->bDirection; + break; } -//#endif - } - if ( fDoNormalPickup ) - { - EVENT_InitNewSoldierAnim( pSoldier, PICKUP_ITEM, 0 , FALSE ); - } + //pSoldier->ubPendingDirection = bDirection; + EVENT_SetSoldierDesiredDirection( pSoldier, bDirection ); + EVENT_SetSoldierDirection( pSoldier, bDirection ); - if (!(pSoldier->uiStatusFlags & SOLDIER_PC)) - { - // set "pending action" value for AI so it will wait - pSoldier->bAction = AI_ACTION_PENDING_ACTION; + // Change to pickup animation + EVENT_InitNewSoldierAnim( pSoldier, ADJACENT_GET_ITEM, 0 , FALSE ); } - break; - - case ANIM_CROUCH: - case ANIM_PRONE: + //#endif + } - UnSetUIBusy( pSoldier->ubID ); - HandleSoldierPickupItem( pSoldier, iItemIndex, sGridNo, bZLevel ); - SoldierGotoStationaryStance( pSoldier ); - if (!(pSoldier->uiStatusFlags & SOLDIER_PC)) - { - // reset action value for AI because we're done! - ActionDone( pSoldier ); - } - break; + if ( fDoNormalPickup ) + { + EVENT_InitNewSoldierAnim( pSoldier, PICKUP_ITEM, 0 , FALSE ); + } + + if (!(pSoldier->uiStatusFlags & SOLDIER_PC)) + { + // set "pending action" value for AI so it will wait + pSoldier->bAction = AI_ACTION_PENDING_ACTION; + } + break; + + case ANIM_CROUCH: + case ANIM_PRONE: + + UnSetUIBusy( pSoldier->ubID ); + HandleSoldierPickupItem( pSoldier, iItemIndex, sGridNo, bZLevel ); + SoldierGotoStationaryStance( pSoldier ); + if (!(pSoldier->uiStatusFlags & SOLDIER_PC)) + { + // reset action value for AI because we're done! + ActionDone( pSoldier ); + } + break; } } } @@ -10638,17 +10726,18 @@ void PickDropItemAnimation( SOLDIERTYPE *pSoldier ) // Don't show animation of getting item, if we are not standing switch ( gAnimControl[ pSoldier->usAnimState ].ubHeight ) { - case ANIM_STAND: - - EVENT_InitNewSoldierAnim( pSoldier, DROP_ITEM, 0 , FALSE ); - break; - - case ANIM_CROUCH: - case ANIM_PRONE: + case ANIM_STAND: - SoldierHandleDropItem( pSoldier ); - SoldierGotoStationaryStance( pSoldier ); - break; + pSoldier->bAction = AI_ACTION_PENDING_ACTION; + EVENT_InitNewSoldierAnim( pSoldier, DROP_ITEM, 0 , FALSE ); + break; + + case ANIM_CROUCH: + case ANIM_PRONE: + + SoldierHandleDropItem( pSoldier ); + SoldierGotoStationaryStance( pSoldier ); + break; } } @@ -10799,7 +10888,7 @@ void EVENT_SoldierBeginAttachCan( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ub // SOmething wrong here... return; } - + // OK set flag! pDoorStatus->ubFlags |= DOOR_HAS_TIN_CAN; @@ -10907,12 +10996,12 @@ void ChangeToFallbackAnimation( SOLDIERTYPE *pSoldier, INT8 bDirection ) void SetSoldierCowerState( SOLDIERTYPE *pSoldier, BOOLEAN fOn ) { - // Robot's don't cower! - if ( pSoldier->ubBodyType == ROBOTNOWEAPON ) - { + // Robot's don't cower! + if ( pSoldier->ubBodyType == ROBOTNOWEAPON ) + { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("ERROR: Robot was told to cower!" ) ); - return; - } + return; + } // OK< set flag and do anim... if ( fOn ) @@ -10920,7 +11009,7 @@ void SetSoldierCowerState( SOLDIERTYPE *pSoldier, BOOLEAN fOn ) if ( !( pSoldier->uiStatusFlags & SOLDIER_COWERING ) ) { EVENT_InitNewSoldierAnim( pSoldier, START_COWER, 0, FALSE ); - + pSoldier->uiStatusFlags |= SOLDIER_COWERING; pSoldier->ubDesiredHeight = ANIM_CROUCH; @@ -10931,7 +11020,7 @@ void SetSoldierCowerState( SOLDIERTYPE *pSoldier, BOOLEAN fOn ) if ( (pSoldier->uiStatusFlags & SOLDIER_COWERING) ) { EVENT_InitNewSoldierAnim( pSoldier, END_COWER, 0, FALSE ); - + pSoldier->uiStatusFlags &= (~SOLDIER_COWERING ); pSoldier->ubDesiredHeight = ANIM_STAND; @@ -10941,43 +11030,44 @@ void SetSoldierCowerState( SOLDIERTYPE *pSoldier, BOOLEAN fOn ) void MercStealFromMerc( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pTarget ) { - INT16 sActionGridNo, sGridNo, sAdjustedGridNo; - UINT8 ubDirection; + INT16 sActionGridNo, sGridNo, sAdjustedGridNo; + UINT8 ubDirection; - // OK, find an adjacent gridno.... - sGridNo = pTarget->sGridNo; + // OK, find an adjacent gridno.... + sGridNo = pTarget->sGridNo; - // See if we can get there to punch - sActionGridNo = FindAdjacentGridEx( pSoldier, sGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); - if ( sActionGridNo != -1 ) + // See if we can get there to punch + sActionGridNo = FindAdjacentGridEx( pSoldier, sGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); + if ( sActionGridNo != -1 ) + { + // SEND PENDING ACTION + pSoldier->ubPendingAction = MERC_STEAL; + pSoldier->sPendingActionData2 = pTarget->sGridNo; + pSoldier->bPendingActionData3 = ubDirection; + pSoldier->ubPendingActionAnimCount = 0; + + // CHECK IF WE ARE AT THIS GRIDNO NOW + if ( pSoldier->sGridNo != sActionGridNo ) { - // SEND PENDING ACTION - pSoldier->ubPendingAction = MERC_STEAL; - pSoldier->sPendingActionData2 = pTarget->sGridNo; - pSoldier->bPendingActionData3 = ubDirection; - pSoldier->ubPendingActionAnimCount = 0; - - // CHECK IF WE ARE AT THIS GRIDNO NOW - if ( pSoldier->sGridNo != sActionGridNo ) - { - // WALK UP TO DEST FIRST - SendGetNewSoldierPathEvent( pSoldier, sActionGridNo, pSoldier->usUIMovementMode ); - } - else - { - EVENT_SetSoldierDesiredDirection( pSoldier, ubDirection ); - EVENT_InitNewSoldierAnim( pSoldier, STEAL_ITEM, 0 , FALSE ); - } - - // OK, set UI - gTacticalStatus.ubAttackBusyCount++; - // reset attacking item (hand) - pSoldier->usAttackingWeapon = 0; - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting STEAL attack, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); - - SetUIBusy( pSoldier->ubID ); + // WALK UP TO DEST FIRST + SendGetNewSoldierPathEvent( pSoldier, sActionGridNo, pSoldier->usUIMovementMode ); } + else + { + EVENT_SetSoldierDesiredDirection( pSoldier, ubDirection ); + EVENT_InitNewSoldierAnim( pSoldier, STEAL_ITEM, 0 , FALSE ); + } + + // OK, set UI +// gTacticalStatus.ubAttackBusyCount++; + // reset attacking item (hand) + pSoldier->usAttackingWeapon = 0; + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Starting STEAL attack, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); + DebugAttackBusy( String( "!!!!!!! Starting STEAL attack, attack count now %d\n", gTacticalStatus.ubAttackBusyCount ) ); + + SetUIBusy( pSoldier->ubID ); + } } SOLDIERTYPE *pTMilitiaSoldier; @@ -11064,27 +11154,27 @@ BOOLEAN PlayerSoldierStartTalking( SOLDIERTYPE *pSoldier, UINT8 ubTargetID, BOOL if ( pTSoldier->ubProfile != NO_PROFILE && pTSoldier->ubWhatKindOfMercAmI == MERC_TYPE__EPC ) { return( InitiateConversation( pTSoldier, pSoldier, APPROACH_EPC_WHO_IS_RECRUITED, 0 ) ); - //Converse( pTSoldier->ubProfile, pSoldier->ubProfile, APPROACH_EPC_WHO_IS_RECRUITED, 0 ); + //Converse( pTSoldier->ubProfile, pSoldier->ubProfile, APPROACH_EPC_WHO_IS_RECRUITED, 0 ); } else if (pTSoldier->bNeutral) { switch( pTSoldier->ubProfile ) { - case JIM: - case JACK: - case OLAF: - case RAY: - case OLGA: - case TYRONE: - // Start combat etc - DeleteTalkingMenu(); - CancelAIAction( pTSoldier, TRUE ); - AddToShouldBecomeHostileOrSayQuoteList( pTSoldier->ubID ); - break; - default: - // Start talking! - return( InitiateConversation( pTSoldier, pSoldier, NPC_INITIAL_QUOTE, 0 ) ); - break; + case JIM: + case JACK: + case OLAF: + case RAY: + case OLGA: + case TYRONE: + // Start combat etc + DeleteTalkingMenu(); + CancelAIAction( pTSoldier, TRUE ); + AddToShouldBecomeHostileOrSayQuoteList( pTSoldier->ubID ); + break; + default: + // Start talking! + return( InitiateConversation( pTSoldier, pSoldier, NPC_INITIAL_QUOTE, 0 ) ); + break; } } else @@ -11100,12 +11190,12 @@ BOOLEAN PlayerSoldierStartTalking( SOLDIERTYPE *pSoldier, UINT8 ubTargetID, BOOL BOOLEAN IsValidSecondHandShot( SOLDIERTYPE *pSoldier ) { if ( Item[ pSoldier->inv[ SECONDHANDPOS ].usItem ].usItemClass == IC_GUN && - !(Item[ pSoldier->inv[SECONDHANDPOS ].usItem ].twohanded ) && - !pSoldier->bDoBurst && - !Item[pSoldier->inv[ HANDPOS ].usItem].grenadelauncher && - Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass == IC_GUN && - pSoldier->inv[SECONDHANDPOS].bGunStatus >= USABLE && - pSoldier->inv[SECONDHANDPOS].ubGunShotsLeft > 0 ) + !(Item[ pSoldier->inv[SECONDHANDPOS ].usItem ].twohanded ) && + !pSoldier->bDoBurst && + !Item[pSoldier->inv[ HANDPOS ].usItem].grenadelauncher && + Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass == IC_GUN && + pSoldier->inv[SECONDHANDPOS].bGunStatus >= USABLE && + pSoldier->inv[SECONDHANDPOS].ubGunShotsLeft > 0 ) { return( TRUE ); } @@ -11118,13 +11208,13 @@ BOOLEAN IsValidSecondHandShotForReloadingPurposes( SOLDIERTYPE *pSoldier ) // should be maintained as same as function above with line // about ammo taken out! if ( Item[ pSoldier->inv[ SECONDHANDPOS ].usItem ].usItemClass == IC_GUN && - !pSoldier->bDoBurst && - !Item[pSoldier->inv[ HANDPOS ].usItem].grenadelauncher && - Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass == IC_GUN && - pSoldier->inv[SECONDHANDPOS].bGunStatus >= USABLE //&& -// pSoldier->inv[SECONDHANDPOS].ubGunShotsLeft > 0 && -// gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_PRONE ) - ) + !pSoldier->bDoBurst && + !Item[pSoldier->inv[ HANDPOS ].usItem].grenadelauncher && + Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass == IC_GUN && + pSoldier->inv[SECONDHANDPOS].bGunStatus >= USABLE //&& + // pSoldier->inv[SECONDHANDPOS].ubGunShotsLeft > 0 && + // gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_PRONE ) + ) { return( TRUE ); } @@ -11137,7 +11227,7 @@ BOOLEAN IsValidSecondHandShotForReloadingPurposes( SOLDIERTYPE *pSoldier ) BOOLEAN CanRobotBeControlled( SOLDIERTYPE *pSoldier ) { SOLDIERTYPE *pController; - + if ( !( pSoldier->uiStatusFlags & SOLDIER_ROBOT ) ) { return( FALSE ); @@ -11212,8 +11302,8 @@ BOOLEAN ControllingRobot( SOLDIERTYPE *pSoldier ) // Are we in the same sector....? // ARM: CHANGED TO WORK IN MAPSCREEN, DON'T USE WorldSector HERE if ( pRobot->sSectorX == pSoldier->sSectorX && - pRobot->sSectorY == pSoldier->sSectorY && - pRobot->bSectorZ == pSoldier->bSectorZ ) + pRobot->sSectorY == pSoldier->sSectorY && + pRobot->bSectorZ == pSoldier->bSectorZ ) { // they have to be either both in sector, or both on the road if ( pRobot->fBetweenSectors == pSoldier->fBetweenSectors ) @@ -11273,7 +11363,7 @@ void UpdateRobotControllerGivenRobot( SOLDIERTYPE *pRobot ) { if ( ControllingRobot( pTeamSoldier ) ) { - pRobot->ubRobotRemoteHolderID = pTeamSoldier->ubID; + pRobot->ubRobotRemoteHolderID = pTeamSoldier->ubID; return; } } @@ -11293,7 +11383,7 @@ void UpdateRobotControllerGivenController( SOLDIERTYPE *pSoldier ) { return; } - + // set up soldier ptr as first element in mercptrs list cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; @@ -11313,13 +11403,13 @@ void HandleSoldierTakeDamageFeedback( SOLDIERTYPE *pSoldier ) // Do sound..... // if ( pSoldier->bLife >= CONSCIOUSNESS ) { - // ATE: Limit how often we grunt... - if ( ( GetJA2Clock( ) - pSoldier->uiTimeSinceLastBleedGrunt ) > 1000 ) - { - pSoldier->uiTimeSinceLastBleedGrunt = GetJA2Clock( ); + // ATE: Limit how often we grunt... + if ( ( GetJA2Clock( ) - pSoldier->uiTimeSinceLastBleedGrunt ) > 1000 ) + { + pSoldier->uiTimeSinceLastBleedGrunt = GetJA2Clock( ); - DoMercBattleSound( pSoldier, (INT8)( BATTLE_SOUND_HIT1 + Random( 2 ) ) ); - } + DoMercBattleSound( pSoldier, (INT8)( BATTLE_SOUND_HIT1 + Random( 2 ) ) ); + } } // Flash portrait.... @@ -11347,31 +11437,33 @@ void HandleSystemNewAISituation( SOLDIERTYPE *pSoldier, BOOLEAN fResetABC ) // if this guy isn't under direct AI control, WHO GIVES A FLYING FLICK? if ( pSoldier->uiStatusFlags & SOLDIER_UNDERAICONTROL ) { - if ( pSoldier->fTurningToShoot ) - { - pSoldier->fTurningToShoot = FALSE; - // Release attacker - // OK - this is hightly annoying , but due to the huge combinations of - // things that can happen - 1 of them is that sLastTarget will get unset - // after turn is done - so set flag here to tell it not to... - pSoldier->fDontUnsetLastTargetFromTurn = TRUE; - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., ending fire because saw something: DONE IN SYSTEM NEW SITUATION") ); - ReduceAttackBusyCount( pSoldier->ubID, FALSE ); - } + if ( pSoldier->fTurningToShoot ) + { + pSoldier->fTurningToShoot = FALSE; + // Release attacker + // OK - this is hightly annoying , but due to the huge combinations of + // things that can happen - 1 of them is that sLastTarget will get unset + // after turn is done - so set flag here to tell it not to... + pSoldier->fDontUnsetLastTargetFromTurn = TRUE; + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., ending fire because saw something: DONE IN SYSTEM NEW SITUATION") ); + DebugAttackBusy( "@@@@@@@ Reducing attacker busy count..., ending fire because saw something: DONE IN SYSTEM NEW SITUATION\n" ); + FreeUpAttacker( ); + } - if ( pSoldier->pTempObject != NULL ) - { - // Place it back into inv.... - AutoPlaceObject( pSoldier, pSoldier->pTempObject, FALSE ); - MemFree( pSoldier->pTempObject ); - pSoldier->pTempObject = NULL; - pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; - pSoldier->usPendingAnimation2 = NO_PENDING_ANIMATION; + if ( pSoldier->pTempObject != NULL ) + { + // Place it back into inv.... + AutoPlaceObject( pSoldier, pSoldier->pTempObject, FALSE ); + MemFree( pSoldier->pTempObject ); + pSoldier->pTempObject = NULL; + pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; + pSoldier->usPendingAnimation2 = NO_PENDING_ANIMATION; - // Decrement attack counter... - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., ending throw because saw something: DONE IN SYSTEM NEW SITUATION") ); - ReduceAttackBusyCount( pSoldier->ubID, FALSE ); - } + // Decrement attack counter... + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., ending throw because saw something: DONE IN SYSTEM NEW SITUATION") ); + DebugAttackBusy("@@@@@@@ Reducing attacker busy count..., ending throw because saw something: DONE IN SYSTEM NEW SITUATION\n"); + FreeUpAttacker( ); + } } } @@ -11394,11 +11486,11 @@ void InternalPlaySoldierFootstepSound( SOLDIERTYPE * pSoldier ) bVolume = HIGHVOLUME; } - if ( pSoldier->uiStatusFlags & SOLDIER_ROBOT ) - { + if ( pSoldier->uiStatusFlags & SOLDIER_ROBOT ) + { PlaySoldierJA2Sample( pSoldier->ubID, ROBOT_BEEP, RATE_11025, SoundVolume( bVolume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - return; - } + return; + } //if ( SoldierOnScreen( pSoldier->ubID ) ) { @@ -11542,9 +11634,9 @@ void DebugValidateSoldierData( ) // check for invalid sector data if ( ( pSoldier->bAssignment != IN_TRANSIT ) && - ( ( pSoldier->sSectorX <= 0 ) || ( pSoldier->sSectorX >= 17 ) || - ( pSoldier->sSectorY <= 0 ) || ( pSoldier->sSectorY >= 17 ) || - ( pSoldier->bSectorZ < 0 ) || ( pSoldier->bSectorZ > 3 ) ) ) + ( ( pSoldier->sSectorX <= 0 ) || ( pSoldier->sSectorX >= 17 ) || + ( pSoldier->sSectorY <= 0 ) || ( pSoldier->sSectorY >= 17 ) || + ( pSoldier->bSectorZ < 0 ) || ( pSoldier->bSectorZ > 3 ) ) ) { swprintf( sString, L"Soldier Data Error: Soldier %d is located at %d/%d/%d.", cnt, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); fProblemDetected = TRUE; @@ -11554,12 +11646,12 @@ void DebugValidateSoldierData( ) if ( fProblemDetected ) { SAIReportError( sString ); -/* + /* if ( guiCurrentScreen == MAP_SCREEN ) - DoMapMessageBox( MSG_BOX_BASIC_STYLE, sString, MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); + DoMapMessageBox( MSG_BOX_BASIC_STYLE, sString, MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback ); else - DoMessageBox( MSG_BOX_BASIC_STYLE, sString, GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_OK, NULL, NULL ); -*/ + DoMessageBox( MSG_BOX_BASIC_STYLE, sString, GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_OK, NULL, NULL ); + */ break; } } @@ -11577,15 +11669,15 @@ void BeginTyingToFall( SOLDIERTYPE *pSoldier ) pSoldier->bStartFallDir = pSoldier->bDirection; pSoldier->fTryingToFall = TRUE; - // Randomize direction - if ( Random( 50 ) < 25 ) - { - pSoldier->fFallClockwise = TRUE; - } - else - { - pSoldier->fFallClockwise = FALSE; - } + // Randomize direction + if ( Random( 50 ) < 25 ) + { + pSoldier->fFallClockwise = TRUE; + } + else + { + pSoldier->fFallClockwise = FALSE; + } } void SetSoldierAsUnderAiControl( SOLDIERTYPE *pSoldierToSet ) diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 7167c269..6a07960e 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -793,7 +793,7 @@ typedef struct UINT32 uiChangeMechanicalTime; UINT32 uiUniqueSoldierIdValue; // the unique value every instance of a soldier gets - 1 is the first valid value - INT8 bBeingAttackedCount; // Being attacked counter + INT8 bBeingAttackedCount; // Being attacked counter is obsolete and can be renamed and used as something else INT8 bNewItemCount[ NUM_INV_SLOTS ]; INT8 bNewItemCycleCount[ NUM_INV_SLOTS ]; @@ -1096,7 +1096,8 @@ UINT8 atan8FromAngle( DOUBLE dAngle ); INT8 CalcActionPoints(SOLDIERTYPE *pSold ); BOOLEAN IsActionInterruptable( SOLDIERTYPE *pSoldier ); INT16 GetDirectionToGridNoFromGridNo( INT16 sGridNoDest, INT16 sGridNoSrc ); -void ReleaseSoldiersAttacker( SOLDIERTYPE *pSoldier ); +// This function is now obsolete. Call ReduceAttackBusyCount instead. +// void ReleaseSoldiersAttacker( SOLDIERTYPE *pSoldier ); BOOLEAN MercInWater( SOLDIERTYPE *pSoldier ); UINT16 GetNewSoldierStateFromNewStance( SOLDIERTYPE *pSoldier, UINT8 ubDesiredStance ); UINT16 GetMoveStateBasedOnStance( SOLDIERTYPE *pSoldier, UINT8 ubStanceHeight ); diff --git a/Tactical/Soldier Create.cpp b/Tactical/Soldier Create.cpp index 36604969..41af7145 100644 --- a/Tactical/Soldier Create.cpp +++ b/Tactical/Soldier Create.cpp @@ -42,6 +42,9 @@ #include "PreBattle Interface.h" #include "Auto Resolve.h" #include "Morale.h" + #include "ai.h" + #include "Strategic Mines.h" + #include "math.h" #endif diff --git a/Tactical/Soldier Find.cpp b/Tactical/Soldier Find.cpp index ffa9a18f..af64e83d 100644 --- a/Tactical/Soldier Find.cpp +++ b/Tactical/Soldier Find.cpp @@ -50,6 +50,9 @@ #include "EditorMercs.h" #include "soldier tile.h" #include "soldier find.h" + #include "Vehicles.h" + #include "GameSettings.h" + #include "ui cursors.h" #endif @@ -93,13 +96,13 @@ extern UINT32 guiUITargetSoldierId; BOOLEAN FindSoldierFromMouse( UINT16 *pusSoldierIndex, UINT32 *pMercFlags ) { - INT16 sMapPos; + UINT16 usMapPos; *pMercFlags = 0; - if ( GetMouseMapPos( &sMapPos ) ) + if ( GetMouseMapPos( &usMapPos ) ) { - if ( FindSoldier( sMapPos, pusSoldierIndex, pMercFlags ,FINDSOLDIERSAMELEVEL( gsInterfaceLevel ) ) ) + if ( FindSoldier( usMapPos, pusSoldierIndex, pMercFlags ,FINDSOLDIERSAMELEVEL( gsInterfaceLevel ) ) ) { return( TRUE ); } @@ -110,13 +113,13 @@ BOOLEAN FindSoldierFromMouse( UINT16 *pusSoldierIndex, UINT32 *pMercFlags ) BOOLEAN SelectiveFindSoldierFromMouse( UINT16 *pusSoldierIndex, UINT32 *pMercFlags ) { - INT16 sMapPos; + UINT16 usMapPos; *pMercFlags = 0; - if ( GetMouseMapPos( &sMapPos ) ) + if ( GetMouseMapPos( &usMapPos ) ) { - if ( FindSoldier( sMapPos, pusSoldierIndex, pMercFlags , FINDSOLDIERSAMELEVEL( gsInterfaceLevel ) ) ) + if ( FindSoldier( usMapPos, pusSoldierIndex, pMercFlags , FINDSOLDIERSAMELEVEL( gsInterfaceLevel ) ) ) { return( TRUE ); } diff --git a/Tactical/Soldier Init List.cpp b/Tactical/Soldier Init List.cpp index 6ce4247f..437162aa 100644 --- a/Tactical/Soldier Init List.cpp +++ b/Tactical/Soldier Init List.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Tactical All.h" #else + #include "builddefines.h" #include #include @@ -26,6 +27,24 @@ #include "Animation Data.h" #include "message.h" #include "Font Control.h" + #include "Sound Control.h" + #include "Quests.h" + #include "Render Fun.h" + #include "meanwhile.h" + #include "Map Screen Interface Map.h" + #include "mapscreen.h" + #include "Debug Control.h" + #include "Inventory Choosing.h" + #include "Strategic AI.h" + #include "strategic.h" + #include "Campaign Types.h" + #include "ai.h" + #include "NPC.h" + #include "Scheduling.h" + #include "opplist.h" + #include "MessageBoxScreen.h" + #include "screenids.h" + #include "SaveLoadScreen.h" #endif #include "Map Edgepoints.h" diff --git a/Tactical/Soldier Profile.cpp b/Tactical/Soldier Profile.cpp index 05f5baf3..8e80f470 100644 --- a/Tactical/Soldier Profile.cpp +++ b/Tactical/Soldier Profile.cpp @@ -46,6 +46,13 @@ #include "Interface Dialogue.h" #include "GameSettings.h" #include "strategic town reputation.h" + #include "interface utils.h" + #include "Game Event Hook.h" + #include "Map Information.h" + #include "history.h" + #include "personnel.h" + #include "environment.h" + #include "Player Command.h" #endif #ifdef JA2EDITOR diff --git a/Tactical/Soldier Tile.cpp b/Tactical/Soldier Tile.cpp index 5fc186a9..be8b8153 100644 --- a/Tactical/Soldier Tile.cpp +++ b/Tactical/Soldier Tile.cpp @@ -54,6 +54,10 @@ #include "soldier tile.h" #include "soldier add.h" #include "fov.h" + #include "Font Control.h" + #include "message.h" + #include "Text.h" + #include "NPC.h" #endif extern INT8 gbNumMercsUntilWaitingOver; diff --git a/Tactical/Soldier macros.h b/Tactical/Soldier macros.h index 139d9f22..cedf4f7d 100644 --- a/Tactical/Soldier macros.h +++ b/Tactical/Soldier macros.h @@ -5,6 +5,7 @@ #include "teamturns.h" #include "soldier profile.h" #include "assignments.h" +#include "Animation Data.h" // MACROS #define RPC_RECRUITED( p ) ( ( p->ubProfile == NO_PROFILE ) ? FALSE : ( gMercProfiles[ p->ubProfile ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED ) ) diff --git a/Tactical/SoldierTooltips.cpp b/Tactical/SoldierTooltips.cpp index 1f1a81d4..cf4c06c6 100644 --- a/Tactical/SoldierTooltips.cpp +++ b/Tactical/SoldierTooltips.cpp @@ -1,4 +1,26 @@ +#ifdef PRECOMPILEDHEADERS #include "Tactical All.h" +#else +#include "Types.h" +#include "Windows.h" +#include "Soldier Control.h" +#include "Input.h" +#include "english.h" +#include "Isometric Utils.h" +#include "GameSettings.h" +#include "Overhead.h" +#include "Game Clock.h" +#include "Text.h" +#include "lighting.h" +#include "Interface.h" +#include "weapons.h" +#include "renderworld.h" +#include "Font Control.h" +#include "font.h" +#include "local.h" +#include "vsurface.h" +#include "line.h" +#endif struct MOUSETT { @@ -35,7 +57,7 @@ void SoldierTooltip( SOLDIERTYPE* pSoldier ) MOUSETT *pRegion = &mouseTT; CHAR16 pStrInfo[ sizeof( pRegion->FastHelpText ) ]; int iNVG = 0; - INT16 sSoldierGridNo; + UINT16 usSoldierGridNo; BOOLEAN fDisplayBigSlotItem = FALSE; BOOLEAN fMercIsUsingScope = FALSE; UINT16 iCarriedRL = 0; @@ -46,12 +68,12 @@ void SoldierTooltip( SOLDIERTYPE* pSoldier ) fDrawTooltip = TRUE; // get the gridno the cursor is at - GetMouseMapPos( &sSoldierGridNo ); + GetMouseMapPos( &usSoldierGridNo ); // get the distance to enemy's tile from the selected merc if ( gusSelectedSoldier != NOBODY ) { - iRangeToTarget = GetRangeInCellCoordsFromGridNoDiff( MercPtrs[ gusSelectedSoldier ]->sGridNo, sSoldierGridNo ) / 10; + iRangeToTarget = GetRangeInCellCoordsFromGridNoDiff( MercPtrs[ gusSelectedSoldier ]->sGridNo, usSoldierGridNo ) / 10; } // WANNE: If we want to show the tooltip of milita and no merc is present in the sector else @@ -129,9 +151,9 @@ void SoldierTooltip( SOLDIERTYPE* pSoldier ) { // display "debug" info if ( gGameExternalOptions.fEnableSoldierTooltipLocation ) - swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_LOCATION], pStrInfo, sSoldierGridNo ); + swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_LOCATION], pStrInfo, usSoldierGridNo ); if ( gGameExternalOptions.fEnableSoldierTooltipBrightness ) - swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_BRIGHTNESS], pStrInfo, SHADE_MIN - LightTrueLevel( sSoldierGridNo, gsInterfaceLevel ), SHADE_MIN ); + swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_BRIGHTNESS], pStrInfo, SHADE_MIN - LightTrueLevel( usSoldierGridNo, gsInterfaceLevel ), SHADE_MIN ); if ( gGameExternalOptions.fEnableSoldierTooltipRangeToTarget ) swprintf( pStrInfo, gzTooltipStrings[STR_TT_CAT_RANGE_TO_TARGET], pStrInfo, iRangeToTarget ); if ( gGameExternalOptions.fEnableSoldierTooltipID ) diff --git a/Tactical/Spread Burst.cpp b/Tactical/Spread Burst.cpp index e6b1fb05..841df7e8 100644 --- a/Tactical/Spread Burst.cpp +++ b/Tactical/Spread Burst.cpp @@ -16,6 +16,7 @@ #include "render dirty.h" #include "interface.h" #include "spread burst.h" + #include "points.h" #endif diff --git a/Tactical/Squads.cpp b/Tactical/Squads.cpp index 6ce9e4a5..b81f5ee9 100644 --- a/Tactical/Squads.cpp +++ b/Tactical/Squads.cpp @@ -14,6 +14,10 @@ #include "Vehicles.h" #include "Map Screen Helicopter.h" #include "Soldier Profile.h" + #include "Debug.h" + #include "jascreens.h" + #include "screenids.h" + #include "Soldier macros.h" #endif diff --git a/Tactical/Strategic Exit GUI.cpp b/Tactical/Strategic Exit GUI.cpp index 4d6611be..335493e7 100644 --- a/Tactical/Strategic Exit GUI.cpp +++ b/Tactical/Strategic Exit GUI.cpp @@ -3,6 +3,7 @@ #include "PreBattle Interface.h" #include "creature spreading.h" #else + #include "builddefines.h" #include #include "Button System.h" #include "mousesystem.h" @@ -24,6 +25,16 @@ #include "input.h" #include "english.h" #include "text.h" + #include "Strategic Movement.h" + #include "Squads.h" + #include "Assignments.h" + #include "Soldier macros.h" + #include "Map Screen Interface Map.h" + #include "PreBattle Interface.h" + #include "strategic.h" + #include "MessageBoxScreen.h" + #include "Quests.h" + #include "Creature Spreading.h" #endif BOOLEAN gfInSectorExitMenu = FALSE; diff --git a/Tactical/Tactical Save.cpp b/Tactical/Tactical Save.cpp index d48c4081..e8978bbd 100644 --- a/Tactical/Tactical Save.cpp +++ b/Tactical/Tactical Save.cpp @@ -31,6 +31,23 @@ #include "debug.h" #include "Random.h" #include "quests.h" + #include "Animated ProgressBar.h" + #include "Text.h" + #include "meanwhile.h" + #include "Enemy Soldier Save.h" + #include "SmokeEffects.h" + #include "LightEffects.h" + #include "PATHAI.H" + #include "GameVersion.h" + #include "strategic.h" + #include "Map Screen Interface Map.h" + #include "Strategic Status.h" + #include "Soldier macros.h" + #include "sgp.h" + #include "MessageBoxScreen.h" + #include "screenids.h" + #include "Queen Command.h" + #include "Map Screen Interface Map Inventory.h" #endif BOOLEAN gfWasInMeanwhile = FALSE; @@ -1741,13 +1758,113 @@ BOOLEAN LoadRottingCorpsesFromTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMa } +// Rewritten to load the temp file once, update with the list, and then write it. This was getting insane as items piled up in sectors. +// A few dozen read, update, writes was okay but a few hundred is pushing it. - -BOOLEAN AddWorldItemsToUnLoadedSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ, INT16 sGridNo, UINT32 uiNumberOfItems, WORLDITEM *pWorldItem, BOOLEAN fOverWrite ) +BOOLEAN AddWorldItemsToUnLoadedSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ, INT16 sGridNo, UINT32 uiNumberOfItemsToAdd, WORLDITEM *pWorldItem, BOOLEAN fOverWrite ) { UINT32 uiLoop; BOOLEAN fLoop=fOverWrite; + UINT32 uiLastItemPos; + UINT32 uiNumberOfItems; + WORLDITEM *pWorldItems; + if( !GetNumberOfWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, &uiNumberOfItems, TRUE ) ) + { + //Errror getting the numbers of the items from the sector + return( FALSE ); + } + + //Allocate memory for the item + pWorldItems = (WORLDITEM *) MemAlloc( sizeof( WORLDITEM ) * uiNumberOfItems ); + if( pWorldItems == NULL ) + { + //Error Allocating memory for the temp item array + return( FALSE ); + } + + //Clear the memory + memset( pWorldItems, 0, sizeof( WORLDITEM ) * uiNumberOfItems ); + + //Load in the sectors Item Info + if( !LoadWorldItemsFromTempItemFile( sMapX, sMapY, bMapZ, pWorldItems ) ) + { + //error reading in the items from the Item mod file + MemFree( pWorldItems ); + return( FALSE ); + } + + + //if we are to replace the entire file + if( fOverWrite ) + { + //first loop through and mark all entries that they dont exists + for( UINT32 cnt=0; cnt #ifdef PRECOMPILEDHEADERS - #include "Tactical All.h" - #include "Language Defines.h" - #include "HelpScreen.h" - #include "Prebattle Interface.h" - #include "ambient control.h" - #include "DisplayCover.h" - #include "_Ja25Englishtext.h" +#include "Tactical All.h" +#include "Language Defines.h" +#include "HelpScreen.h" +#include "Prebattle Interface.h" +#include "ambient control.h" +#include "DisplayCover.h" +#include "_Ja25Englishtext.h" #else - #include - #include - #include "wcheck.h" - #include "stdlib.h" - #include "debug.h" - #include "math.h" - #include "jascreens.h" - #include "pathai.h" - #include "Soldier Control.h" - #include "Animation Control.h" - #include "Animation Data.h" - #include "Event Pump.h" - #include "Timer Control.h" - #include "cursors.h" - #include "Handle UI.h" - #include "Isometric Utils.h" - #include "input.h" - #include "overhead.h" - #include "Sys Globals.h" - #include "screenids.h" - #include "interface.h" - #include "cursor control.h" - #include "points.h" - #include "Interactive Tiles.h" - #include "interface cursors.h" - #include "weapons.h" - #include "lighting.h" - #include "sound control.h" - #include "environment.h" - #include "Music Control.h" - #include "ai.h" - #include "renderworld.h" - #include "font control.h" - #include "worldman.h" - #include "Handle UI Plan.h" - #include "message.h" - #ifdef NETWORKED - #include "Networking.h" - #include "Communication.h" - #endif - #include "overhead map.h" - #include "world items.h" - #include "Game Clock.h" - #include "interface items.h" - #include "physics.h" - #include "ui cursors.h" - #include "worldman.h" - #include "strategicmap.h" - #include "soldier profile.h" - #include "soldier create.h" - #include "soldier add.h" - #include "dialogue control.h" - #include "interface dialogue.h" - #include "opplist.h" - #include "interactive tiles.h" - #include "messageboxscreen.h" - #include "gameloop.h" - #include "gamescreen.h" - #include "spread burst.h" - #include "tile animation.h" - #include "merc entering.h" - #include "explosion control.h" - #include "QuestDebug.h" - #include "assignments.h" - #include "EditScreen.h" - #include "SaveLoadGame.h" - #include "Structure Wrap.h" - #include "los.h" - #include "Exit Grids.h" - #include "Strategic Exit GUI.h" - #include "auto bandage.h" - #include "Options Screen.h" - #include "squads.h" - #include "interface panels.h" - #include "soldier tile.h" - #include "Soldier functions.h" - #include "Game Events.h" - #include "english.h" - #include "Random.h" - #include "Assignments.h" - #include "Map Screen Interface.h" - #include "renderworld.h" - #include "Quest Debug System.h" - //#include "medical.h" - #include "Arms Dealer Init.h" - #include "ShopKeeper Interface.h" - #include "GameSettings.h" - #include "vehicles.h" - #include "GameVersion.h" - #include "SaveLoadScreen.h" - #include "Air raid.h" - #include "meanwhile.h" - #include "text.h" - #include "Inventory Choosing.h" - #include "soldier macros.h" - #include "HelpScreen.h" +#include "builddefines.h" +#include +#include +#include "wcheck.h" +#include "stdlib.h" +#include "debug.h" +#include "math.h" +#include "jascreens.h" +#include "pathai.h" +#include "Soldier Control.h" +#include "Animation Control.h" +#include "Animation Data.h" +#include "Event Pump.h" +#include "Timer Control.h" +#include "cursors.h" +#include "Handle UI.h" +#include "Isometric Utils.h" +#include "input.h" +#include "overhead.h" +#include "Sys Globals.h" +#include "screenids.h" +#include "interface.h" +#include "cursor control.h" +#include "points.h" +#include "Interactive Tiles.h" +#include "interface cursors.h" +#include "weapons.h" +#include "lighting.h" +#include "sound control.h" +#include "environment.h" +#include "Music Control.h" +#include "ai.h" +#include "renderworld.h" +#include "font control.h" +#include "worldman.h" +#include "Handle UI Plan.h" +#include "message.h" +#ifdef NETWORKED +#include "Networking.h" +#include "Communication.h" +#endif +#include "overhead map.h" +#include "world items.h" +#include "Game Clock.h" +#include "interface items.h" +#include "physics.h" +#include "ui cursors.h" +#include "worldman.h" +#include "strategicmap.h" +#include "soldier profile.h" +#include "soldier create.h" +#include "soldier add.h" +#include "dialogue control.h" +#include "interface dialogue.h" +#include "opplist.h" +#include "interactive tiles.h" +#include "messageboxscreen.h" +#include "gameloop.h" +#include "gamescreen.h" +#include "spread burst.h" +#include "tile animation.h" +#include "merc entering.h" +#include "explosion control.h" +#include "QuestDebug.h" +#include "assignments.h" +#include "EditScreen.h" +#include "SaveLoadGame.h" +#include "Structure Wrap.h" +#include "los.h" +#include "Exit Grids.h" +#include "Strategic Exit GUI.h" +#include "auto bandage.h" +#include "Options Screen.h" +#include "squads.h" +#include "interface panels.h" +#include "soldier tile.h" +#include "Soldier functions.h" +#include "Game Events.h" +#include "english.h" +#include "Random.h" +#include "Assignments.h" +#include "Map Screen Interface.h" +#include "renderworld.h" +#include "Quest Debug System.h" +//#include "medical.h" +#include "Arms Dealer Init.h" +#include "ShopKeeper Interface.h" +#include "GameSettings.h" +#include "vehicles.h" +#include "GameVersion.h" +#include "SaveLoadScreen.h" +#include "Air raid.h" +#include "meanwhile.h" +#include "text.h" +#include "Inventory Choosing.h" +#include "soldier macros.h" +#include "HelpScreen.h" +#include "cheats.h" +#include "displaycover.h" +#include "Tactical Save.h" +#include "history.h" +#include "Queen Command.h" +#include "PreBattle Interface.h" +#include "_Ja25EnglishText.h" +#include "Militia Control.h" +#include "Ambient Control.h" +#include "Strategic AI.h" #endif - #include "Quest Debug System.h" +#include "Quest Debug System.h" @@ -231,8 +242,8 @@ extern void DetermineWhichMilitiaControlMenusCanBeShown( void ); //lalien void GetTBMouseButtonInput( UINT32 *puiNewEvent ) { - QueryTBLeftButton( puiNewEvent ); - QueryTBRightButton( puiNewEvent ); + QueryTBLeftButton( puiNewEvent ); + QueryTBRightButton( puiNewEvent ); } void QueryTBLeftButton( UINT32 *puiNewEvent ) @@ -246,9 +257,9 @@ void QueryTBLeftButton( UINT32 *puiNewEvent ) // LEFT MOUSE BUTTON - if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) + if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) { - if (!GetMouseMapPos( (INT16 *)&usMapPos ) && !gfUIShowExitSouth ) + if (!GetMouseMapPos( &usMapPos ) && !gfUIShowExitSouth ) { return; } @@ -263,154 +274,154 @@ void QueryTBLeftButton( UINT32 *puiNewEvent ) { switch( gCurrentUIMode ) { - case CONFIRM_ACTION_MODE: + case CONFIRM_ACTION_MODE: - if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) - { - pSoldier->sStartGridNo = usMapPos; - } - break; + if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + { + pSoldier->sStartGridNo = usMapPos; + } + break; - case MOVE_MODE: + case MOVE_MODE: - if ( giUIMessageOverlay != -1 ) + if ( giUIMessageOverlay != -1 ) + { + EndUIMessage( ); + } + else + { + if ( !HandleCheckForExitArrowsInput( FALSE ) && gpItemPointer == NULL ) { - EndUIMessage( ); - } - else - { - if ( !HandleCheckForExitArrowsInput( FALSE ) && gpItemPointer == NULL ) + // First check if we clicked on a guy, if so, make selected if it's ours + if ( gfUIFullTargetFound && ( guiUIFullTargetFlags & OWNED_MERC ) ) { - // First check if we clicked on a guy, if so, make selected if it's ours - if ( gfUIFullTargetFound && ( guiUIFullTargetFlags & OWNED_MERC ) ) + if ( !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) { - if ( !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) - { - fClickHoldIntercepted = TRUE; + fClickHoldIntercepted = TRUE; - // Select guy - if( GetSoldier( &pSoldier, gusUIFullTargetID ) && gpItemPointer == NULL ) - { - if( pSoldier->bAssignment >= ON_DUTY ) - { - // do nothing - fClickHoldIntercepted = FALSE; - } - else - { - *puiNewEvent = I_SELECT_MERC; - } - } - else - { - *puiNewEvent = I_SELECT_MERC; - } - } - } - else - { - if ( InUIPlanMode( ) ) - { - AddUIPlan( usMapPos, UIPLAN_ACTION_MOVETO ); + // Select guy + if( GetSoldier( &pSoldier, gusUIFullTargetID ) && gpItemPointer == NULL ) + { + if( pSoldier->bAssignment >= ON_DUTY ) + { + // do nothing + fClickHoldIntercepted = FALSE; + } + else + { + *puiNewEvent = I_SELECT_MERC; + } } else { - // We're on terrain in which we can walk, walk - // If we're on terrain, - if ( gusSelectedSoldier != NO_SOLDIER ) - { - INT8 bReturnVal = FALSE; - - GetSoldier( &pSoldier, gusSelectedSoldier ); - - bReturnVal = HandleMoveModeInteractiveClick( usMapPos, puiNewEvent ); - - // All's OK for interactive tile? - if ( bReturnVal == -2 ) - { - // Confirm! - if ( SelectedMercCanAffordMove( ) ) - { - *puiNewEvent = C_WAIT_FOR_CONFIRM; - } - } - else if ( bReturnVal == 0 ) - { - if ( gfUIAllMoveOn ) - { - *puiNewEvent = C_WAIT_FOR_CONFIRM; - } - else - { - if ( gsCurrentActionPoints == 0 ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); - } - else if ( SelectedMercCanAffordMove( ) ) - { - BOOLEAN fResult; - - if ( ( fResult = UIOKMoveDestination( MercPtrs[ gusSelectedSoldier ], usMapPos ) ) == 1 ) - { - // ATE: CHECK IF WE CAN GET TO POSITION - // Check if we are not in combat - GetSoldier( &pSoldier, gusSelectedSoldier ); - - if ( gsCurrentActionPoints == 0 ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); - } - else - { - *puiNewEvent = C_WAIT_FOR_CONFIRM; - } - } - else - { - if ( fResult == 2 ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NOBODY_USING_REMOTE_STR ] ); - } - else - { - //if ( usMapPos != sMoveClickGridNo || pSoldier->uiStatusFlags & SOLDIER_ROBOT ) - //{ - // sMoveClickGridNo = usMapPos; - - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANT_MOVE_THERE_STR ] ); - // Goto hand cursor mode.... - // *puiNewEvent = M_CHANGE_TO_HANDMODE; - // gsOverItemsGridNo = usMapPos; - // gsOverItemsLevel = gsInterfaceLevel; - //} - //else - //{ - // sMoveClickGridNo = 0; - // *puiNewEvent = M_CHANGE_TO_HANDMODE; - //} - - } - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, L"Invalid move destination." ); - } - } - } - } - // OK, our first right-click is an all-cycle - gfUICanBeginAllMoveCycle = FALSE; - } - fClickHoldIntercepted = TRUE; - + *puiNewEvent = I_SELECT_MERC; } } } else { - fClickHoldIntercepted = TRUE; - fIgnoreLeftUp = TRUE; - } + if ( InUIPlanMode( ) ) + { + AddUIPlan( usMapPos, UIPLAN_ACTION_MOVETO ); + } + else + { + // We're on terrain in which we can walk, walk + // If we're on terrain, + if ( gusSelectedSoldier != NO_SOLDIER ) + { + INT8 bReturnVal = FALSE; + GetSoldier( &pSoldier, gusSelectedSoldier ); + + bReturnVal = HandleMoveModeInteractiveClick( usMapPos, puiNewEvent ); + + // All's OK for interactive tile? + if ( bReturnVal == -2 ) + { + // Confirm! + if ( SelectedMercCanAffordMove( ) ) + { + *puiNewEvent = C_WAIT_FOR_CONFIRM; + } + } + else if ( bReturnVal == 0 ) + { + if ( gfUIAllMoveOn ) + { + *puiNewEvent = C_WAIT_FOR_CONFIRM; + } + else + { + if ( gsCurrentActionPoints == 0 ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); + } + else if ( SelectedMercCanAffordMove( ) ) + { + BOOLEAN fResult; + + if ( ( fResult = UIOKMoveDestination( MercPtrs[ gusSelectedSoldier ], usMapPos ) ) == 1 ) + { + // ATE: CHECK IF WE CAN GET TO POSITION + // Check if we are not in combat + GetSoldier( &pSoldier, gusSelectedSoldier ); + + if ( gsCurrentActionPoints == 0 ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); + } + else + { + *puiNewEvent = C_WAIT_FOR_CONFIRM; + } + } + else + { + if ( fResult == 2 ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NOBODY_USING_REMOTE_STR ] ); + } + else + { + //if ( usMapPos != sMoveClickGridNo || pSoldier->uiStatusFlags & SOLDIER_ROBOT ) + //{ + // sMoveClickGridNo = usMapPos; + + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANT_MOVE_THERE_STR ] ); + // Goto hand cursor mode.... + // *puiNewEvent = M_CHANGE_TO_HANDMODE; + // gsOverItemsGridNo = usMapPos; + // gsOverItemsLevel = gsInterfaceLevel; + //} + //else + //{ + // sMoveClickGridNo = 0; + // *puiNewEvent = M_CHANGE_TO_HANDMODE; + //} + + } + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, L"Invalid move destination." ); + } + } + } + } + // OK, our first right-click is an all-cycle + gfUICanBeginAllMoveCycle = FALSE; + } + fClickHoldIntercepted = TRUE; + + } + } } - break; + else + { + fClickHoldIntercepted = TRUE; + fIgnoreLeftUp = TRUE; + } + + } + break; } } if ( gfUIWaitingForUserSpeechAdvance ) @@ -424,33 +435,33 @@ void QueryTBLeftButton( UINT32 *puiNewEvent ) switch( gCurrentUIMode ) { - case MOVE_MODE: + case MOVE_MODE: - // First check if we clicked on a guy, if so, make selected if it's ours - if ( gfUIFullTargetFound ) - { - // Select guy - if ( ( guiUIFullTargetFlags & SELECTED_MERC) && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) && !( MercPtrs[ gusUIFullTargetID ]->uiStatusFlags & SOLDIER_VEHICLE ) ) - { - *puiNewEvent = M_CHANGE_TO_ADJPOS_MODE; - fIgnoreLeftUp = FALSE; - } - } - break; + // First check if we clicked on a guy, if so, make selected if it's ours + if ( gfUIFullTargetFound ) + { + // Select guy + if ( ( guiUIFullTargetFlags & SELECTED_MERC) && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) && !( MercPtrs[ gusUIFullTargetID ]->uiStatusFlags & SOLDIER_VEHICLE ) ) + { + *puiNewEvent = M_CHANGE_TO_ADJPOS_MODE; + fIgnoreLeftUp = FALSE; + } + } + break; } // IF HERE, DO A CLICK-HOLD IF IN INTERVAL if ( COUNTERDONE( LMOUSECLICK_DELAY_COUNTER ) && !fClickHoldIntercepted ) { -/* removed warning C4060 (jonathanl) + /* removed warning C4060 (jonathanl) // Switch on UI mode switch( gCurrentUIMode ) { } -*/ + */ } - + } else @@ -463,11 +474,11 @@ void QueryTBLeftButton( UINT32 *puiNewEvent ) // FIRST CHECK FOR ANYTIME ( NON-INTERVAL ) CLICKS switch( gCurrentUIMode ) { - case ADJUST_STANCE_MODE: + case ADJUST_STANCE_MODE: - // If button has come up, change to mocve mode - *puiNewEvent = PADJ_ADJUST_STANCE; - break; + // If button has come up, change to mocve mode + *puiNewEvent = PADJ_ADJUST_STANCE; + break; } // CHECK IF WE CLICKED-HELD @@ -479,32 +490,32 @@ void QueryTBLeftButton( UINT32 *puiNewEvent ) { case CONFIRM_ACTION_MODE: - if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + { + if ( pSoldier->bDoBurst ) { - if ( pSoldier->bDoBurst ) + pSoldier->sEndGridNo = usMapPos; + + gfBeginBurstSpreadTracking = FALSE; + + if ( pSoldier->sEndGridNo != pSoldier->sStartGridNo ) { - pSoldier->sEndGridNo = usMapPos; + pSoldier->fDoSpread = TRUE; - gfBeginBurstSpreadTracking = FALSE; - - if ( pSoldier->sEndGridNo != pSoldier->sStartGridNo ) - { - pSoldier->fDoSpread = TRUE; - - PickBurstLocations( pSoldier ); - - *puiNewEvent = CA_MERC_SHOOT; - } - else - { - pSoldier->fDoSpread = FALSE; - } - - fClickHoldIntercepted = TRUE; + PickBurstLocations( pSoldier ); + *puiNewEvent = CA_MERC_SHOOT; } + else + { + pSoldier->fDoSpread = FALSE; + } + + fClickHoldIntercepted = TRUE; + } - break; + } + break; } @@ -545,137 +556,137 @@ void QueryTBLeftButton( UINT32 *puiNewEvent ) { switch( gCurrentUIMode ) { - case MENU_MODE: + case MENU_MODE: - // If we get a hit here and we're in menu mode, quit the menu mode - EndMenuEvent( guiCurrentEvent ); - break; - - case IDLE_MODE: + // If we get a hit here and we're in menu mode, quit the menu mode + EndMenuEvent( guiCurrentEvent ); + break; - // First check if we clicked on a guy, if so, make selected if it's ours - if ( gfUIFullTargetFound ) - { - // Select guy - if ( guiUIFullTargetFlags & OWNED_MERC && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) - { - *puiNewEvent = I_SELECT_MERC; - } + case IDLE_MODE: - } - break; - - case MOVE_MODE: - - // Check if we should activate an interactive tile! + // First check if we clicked on a guy, if so, make selected if it's ours + if ( gfUIFullTargetFound ) + { // Select guy - if ( ( guiUIFullTargetFlags & OWNED_MERC ) && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) + if ( guiUIFullTargetFlags & OWNED_MERC && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) { - // Select guy - if( GetSoldier( &pSoldier, gusUIFullTargetID ) && ( gpItemPointer == NULL ) && !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) - { - if( pSoldier->bAssignment >= ON_DUTY ) - { - PopupAssignmentMenuInTactical( pSoldier ); - } - } - } - break; - - case CONFIRM_MOVE_MODE: - - *puiNewEvent = C_MOVE_MERC; - break; - - case HANDCURSOR_MODE: - - HandleHandCursorClick( usMapPos, puiNewEvent ); - break; - - case JUMPOVER_MODE: - - if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) - { - if ( EnoughPoints( pSoldier, gsCurrentActionPoints, 0, TRUE ) ) - { - *puiNewEvent = JP_JUMP; - } + *puiNewEvent = I_SELECT_MERC; } - break; - - case ACTION_MODE: - - if ( InUIPlanMode( ) ) - { - AddUIPlan( usMapPos, UIPLAN_ACTION_FIRE ); - } - else - { - if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) - { - if ( !HandleUIReloading( pSoldier ) ) - { - // ATE: Reset refine aim.. - pSoldier->bShownAimTime = 0; - - if ( gsCurrentActionPoints == 0 ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); - } - // Determine if we have enough action points! - else if ( UIMouseOnValidAttackLocation( pSoldier ) && SelectedMercCanAffordAttack( ) ) - { - *puiNewEvent = A_CHANGE_TO_CONFIM_ACTION; - pSoldier->sStartGridNo = usMapPos; - } - } - - } - } - break; - - case CONFIRM_ACTION_MODE: - - *puiNewEvent = CA_MERC_SHOOT; - break; - - case LOOKCURSOR_MODE: - // If we cannot actually do anything, return to movement mode - *puiNewEvent = LC_LOOK; - break; - - case TALKCURSOR_MODE: - - if ( HandleTalkInit( ) ) - { - *puiNewEvent = TA_TALKINGMENU; - } - break; - - case GETTINGITEM_MODE: - - // Remove menu! - // RemoveItemPickupMenu( ); - break; - - case TALKINGMENU_MODE: - - //HandleTalkingMenuEscape( TRUE ); - break; - - case EXITSECTORMENU_MODE: - - RemoveSectorExitMenu( FALSE ); - break; - - case OPENDOOR_MENU_MODE: - - CancelOpenDoorMenu( ); - HandleOpenDoorMenu( ); - *puiNewEvent = A_CHANGE_TO_MOVE; - break; } + break; + + case MOVE_MODE: + + // Check if we should activate an interactive tile! + // Select guy + if ( ( guiUIFullTargetFlags & OWNED_MERC ) && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) + { + // Select guy + if( GetSoldier( &pSoldier, gusUIFullTargetID ) && ( gpItemPointer == NULL ) && !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) + { + if( pSoldier->bAssignment >= ON_DUTY ) + { + PopupAssignmentMenuInTactical( pSoldier ); + } + } + } + break; + + case CONFIRM_MOVE_MODE: + + *puiNewEvent = C_MOVE_MERC; + break; + + case HANDCURSOR_MODE: + + HandleHandCursorClick( usMapPos, puiNewEvent ); + break; + + case JUMPOVER_MODE: + + if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + { + if ( EnoughPoints( pSoldier, gsCurrentActionPoints, 0, TRUE ) ) + { + *puiNewEvent = JP_JUMP; + } + } + break; + + case ACTION_MODE: + + if ( InUIPlanMode( ) ) + { + AddUIPlan( usMapPos, UIPLAN_ACTION_FIRE ); + } + else + { + if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + { + if ( !HandleUIReloading( pSoldier ) ) + { + // ATE: Reset refine aim.. + pSoldier->bShownAimTime = 0; + + if ( gsCurrentActionPoints == 0 ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); + } + // Determine if we have enough action points! + else if ( UIMouseOnValidAttackLocation( pSoldier ) && SelectedMercCanAffordAttack( ) ) + { + *puiNewEvent = A_CHANGE_TO_CONFIM_ACTION; + pSoldier->sStartGridNo = usMapPos; + } + } + + } + } + break; + + case CONFIRM_ACTION_MODE: + + *puiNewEvent = CA_MERC_SHOOT; + break; + + case LOOKCURSOR_MODE: + // If we cannot actually do anything, return to movement mode + *puiNewEvent = LC_LOOK; + break; + + case TALKCURSOR_MODE: + + if ( HandleTalkInit( ) ) + { + *puiNewEvent = TA_TALKINGMENU; + } + break; + + case GETTINGITEM_MODE: + + // Remove menu! + // RemoveItemPickupMenu( ); + break; + + case TALKINGMENU_MODE: + + //HandleTalkingMenuEscape( TRUE ); + break; + + case EXITSECTORMENU_MODE: + + RemoveSectorExitMenu( FALSE ); + break; + + case OPENDOOR_MENU_MODE: + + CancelOpenDoorMenu( ); + HandleOpenDoorMenu( ); + *puiNewEvent = A_CHANGE_TO_MOVE; + break; + + } } } } @@ -725,12 +736,12 @@ void QueryTBRightButton( UINT32 *puiNewEvent ) SOLDIERTYPE *pSoldier; UINT16 usMapPos; BOOLEAN fDone = FALSE; - if (!GetMouseMapPos( (INT16 *) &usMapPos ) ) + if (!GetMouseMapPos( &usMapPos ) ) { return; } - if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) + if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) { // RIGHT MOUSE BUTTON @@ -756,62 +767,62 @@ void QueryTBRightButton( UINT32 *puiNewEvent ) // Switch on UI mode switch( gCurrentUIMode ) { - case IDLE_MODE: - case ACTION_MODE: - case HANDCURSOR_MODE: - case LOOKCURSOR_MODE: - case TALKCURSOR_MODE: - case MOVE_MODE: + case IDLE_MODE: + case ACTION_MODE: + case HANDCURSOR_MODE: + case LOOKCURSOR_MODE: + case TALKCURSOR_MODE: + case MOVE_MODE: - // Check if we're on terrain - //if ( !gfUIFullTargetFound ) - //{ - // ATE: - fDone = FALSE; + // Check if we're on terrain + //if ( !gfUIFullTargetFound ) + //{ + // ATE: + fDone = FALSE; - if ( ( guiUIFullTargetFlags & OWNED_MERC ) && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) + if ( ( guiUIFullTargetFlags & OWNED_MERC ) && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) + { + // Select guy + if( GetSoldier( &pSoldier, gusUIFullTargetID ) && ( gpItemPointer == NULL ) && !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) + { + //if( pSoldier->bAssignment >= ON_DUTY ) { - // Select guy - if( GetSoldier( &pSoldier, gusUIFullTargetID ) && ( gpItemPointer == NULL ) && !( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) ) - { - //if( pSoldier->bAssignment >= ON_DUTY ) - { - PopupAssignmentMenuInTactical( pSoldier ); - fClickHoldIntercepted = TRUE; - } - } - } - - if( fDone == TRUE ) - { - break; - } - - if ( gusSelectedSoldier != NOBODY && !fClickHoldIntercepted ) - { - *puiNewEvent = U_MOVEMENT_MENU; + PopupAssignmentMenuInTactical( pSoldier ); fClickHoldIntercepted = TRUE; } - //} - //else - //{ - // If we are on a selected guy - // if ( guiUIFullTargetFlags & SELECTED_MERC && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) - // { - //*puiNewEvent = U_POSITION_MENU; - //fClickHoldIntercepted = TRUE; - // } + } + } + + if( fDone == TRUE ) + { + break; + } + + if ( gusSelectedSoldier != NOBODY && !fClickHoldIntercepted ) + { + *puiNewEvent = U_MOVEMENT_MENU; + fClickHoldIntercepted = TRUE; + } + //} + //else + //{ + // If we are on a selected guy + // if ( guiUIFullTargetFlags & SELECTED_MERC && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) + // { + //*puiNewEvent = U_POSITION_MENU; + //fClickHoldIntercepted = TRUE; + // } // else if ( guiUIFullTargetFlags & OWNED_MERC ) // { - // If we are on a non-selected guy selected guy + // If we are on a non-selected guy selected guy // } - //} - break; + //} + break; } } } - + } } @@ -822,125 +833,125 @@ void QueryTBRightButton( UINT32 *puiNewEvent ) if ( fLeftButtonDown ) { - fIgnoreLeftUp = TRUE; + fIgnoreLeftUp = TRUE; - if ( gpItemPointer == NULL ) - { - // ATE: - if ( gusSelectedSoldier != NOBODY ) + if ( gpItemPointer == NULL ) + { + // ATE: + if ( gusSelectedSoldier != NOBODY ) + { + switch( gCurrentUIMode ) { - switch( gCurrentUIMode ) + case CONFIRM_MOVE_MODE: + case MOVE_MODE: + + if ( gfUICanBeginAllMoveCycle ) { - case CONFIRM_MOVE_MODE: - case MOVE_MODE: - - if ( gfUICanBeginAllMoveCycle ) - { - *puiNewEvent = M_CYCLE_MOVE_ALL; - } - else - { - if ( !gfFirstCycleMovementStarted ) - { - gfFirstCycleMovementStarted = TRUE; - - // OK, set this guy's movement mode to crawling fo rthat we will start cycling in run..... - if ( MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != RUNNING ) - { - // ATE: UNLESS WE ARE IN RUNNING MODE ALREADY - MercPtrs[ gusSelectedSoldier ]->usUIMovementMode = CRAWLING; - } - } - - // Give event to cycle movement - *puiNewEvent = M_CYCLE_MOVEMENT; - break; - } + *puiNewEvent = M_CYCLE_MOVE_ALL; } - - // ATE: Added cancel of burst mode.... - if ( gfBeginBurstSpreadTracking ) + else { - gfBeginBurstSpreadTracking = FALSE; - gfRTClickLeftHoldIntercepted = TRUE; - MercPtrs[ gusSelectedSoldier ]->fDoSpread = FALSE; - fClickHoldIntercepted = TRUE; - *puiNewEvent = A_END_ACTION; - gCurrentUIMode = MOVE_MODE; + if ( !gfFirstCycleMovementStarted ) + { + gfFirstCycleMovementStarted = TRUE; + + // OK, set this guy's movement mode to crawling fo rthat we will start cycling in run..... + if ( MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != RUNNING ) + { + // ATE: UNLESS WE ARE IN RUNNING MODE ALREADY + MercPtrs[ gusSelectedSoldier ]->usUIMovementMode = CRAWLING; + } + } + + // Give event to cycle movement + *puiNewEvent = M_CYCLE_MOVEMENT; + break; } } - } + + // ATE: Added cancel of burst mode.... + if ( gfBeginBurstSpreadTracking ) + { + gfBeginBurstSpreadTracking = FALSE; + gfRTClickLeftHoldIntercepted = TRUE; + MercPtrs[ gusSelectedSoldier ]->fDoSpread = FALSE; + fClickHoldIntercepted = TRUE; + *puiNewEvent = A_END_ACTION; + gCurrentUIMode = MOVE_MODE; + } + } + } } else { if ( !fClickHoldIntercepted && !fClickIntercepted ) { - if ( gpItemPointer == NULL ) + if ( gpItemPointer == NULL ) { - // ATE: - if ( gusSelectedSoldier != NOBODY ) + // ATE: + if ( gusSelectedSoldier != NOBODY ) { // Switch on UI mode switch( gCurrentUIMode ) { - case IDLE_MODE: + case IDLE_MODE: - break; + break; - case MOVE_MODE: + case MOVE_MODE: - // We have here a change to action mode - *puiNewEvent = M_CHANGE_TO_ACTION; - fClickIntercepted = TRUE; - break; + // We have here a change to action mode + *puiNewEvent = M_CHANGE_TO_ACTION; + fClickIntercepted = TRUE; + break; - case ACTION_MODE: + case ACTION_MODE: - // We have here a change to action mode - *puiNewEvent = A_CHANGE_TO_MOVE; - fClickIntercepted = TRUE; - break; + // We have here a change to action mode + *puiNewEvent = A_CHANGE_TO_MOVE; + fClickIntercepted = TRUE; + break; - case CONFIRM_MOVE_MODE: + case CONFIRM_MOVE_MODE: - *puiNewEvent = A_CHANGE_TO_MOVE; - fClickIntercepted = TRUE; - break; + *puiNewEvent = A_CHANGE_TO_MOVE; + fClickIntercepted = TRUE; + break; - case HANDCURSOR_MODE: - // If we cannot actually do anything, return to movement mode - *puiNewEvent = A_CHANGE_TO_MOVE; - break; + case HANDCURSOR_MODE: + // If we cannot actually do anything, return to movement mode + *puiNewEvent = A_CHANGE_TO_MOVE; + break; - case LOOKCURSOR_MODE: - case TALKCURSOR_MODE: + case LOOKCURSOR_MODE: + case TALKCURSOR_MODE: - // If we cannot actually do anything, return to movement mode - *puiNewEvent = A_CHANGE_TO_MOVE; - break; + // If we cannot actually do anything, return to movement mode + *puiNewEvent = A_CHANGE_TO_MOVE; + break; - case CONFIRM_ACTION_MODE: + case CONFIRM_ACTION_MODE: - if ( GetSoldier( &pSoldier, gusSelectedSoldier ) ) - { - HandleRightClickAdjustCursor( pSoldier, usMapPos ); - } - fClickIntercepted = TRUE; - break; + if ( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + { + HandleRightClickAdjustCursor( pSoldier, usMapPos ); + } + fClickIntercepted = TRUE; + break; - case MENU_MODE: + case MENU_MODE: - // If we get a hit here and we're in menu mode, quit the menu mode - EndMenuEvent( guiCurrentEvent ); - fClickIntercepted = TRUE; - break; + // If we get a hit here and we're in menu mode, quit the menu mode + EndMenuEvent( guiCurrentEvent ); + fClickIntercepted = TRUE; + break; } } } else { - if ( gfUIFullTargetFound ) + if ( gfUIFullTargetFound ) { gfItemPointerDifferentThanDefault = !gfItemPointerDifferentThanDefault; } @@ -974,12 +985,12 @@ void GetTBMousePositionInput( UINT32 *puiNewEvent ) static UINT32 uiMoveTargetSoldierId = NO_SOLDIER; - if (!GetMouseMapPos( (INT16 *)&usMapPos ) ) + if (!GetMouseMapPos( &usMapPos ) ) { return; } - if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) + if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA ) { // Handle highlighting stuff HandleObjectHighlighting( ); @@ -987,255 +998,255 @@ void GetTBMousePositionInput( UINT32 *puiNewEvent ) // Check if we have an item in our hands... if ( gpItemPointer != NULL ) { - *puiNewEvent = A_ON_TERRAIN; - return; + *puiNewEvent = A_ON_TERRAIN; + return; } // Switch on modes switch( gCurrentUIMode ) { - case LOCKUI_MODE: - *puiNewEvent = LU_ON_TERRAIN; - break; + case LOCKUI_MODE: + *puiNewEvent = LU_ON_TERRAIN; + break; - case LOCKOURTURN_UI_MODE: - *puiNewEvent = LA_ON_TERRAIN; - break; + case LOCKOURTURN_UI_MODE: + *puiNewEvent = LA_ON_TERRAIN; + break; - case IDLE_MODE: - *puiNewEvent = I_ON_TERRAIN; - break; + case IDLE_MODE: + *puiNewEvent = I_ON_TERRAIN; + break; - case ENEMYS_TURN_MODE: - *puiNewEvent = ET_ON_TERRAIN; - break; + case ENEMYS_TURN_MODE: + *puiNewEvent = ET_ON_TERRAIN; + break; - case LOOKCURSOR_MODE: - *puiNewEvent = LC_ON_TERRAIN; - break; + case LOOKCURSOR_MODE: + *puiNewEvent = LC_ON_TERRAIN; + break; - case TALKCURSOR_MODE: - if ( uiMoveTargetSoldierId != NOBODY ) + case TALKCURSOR_MODE: + if ( uiMoveTargetSoldierId != NOBODY ) + { + if( gfUIFullTargetFound ) { - if( gfUIFullTargetFound ) - { - if ( gusUIFullTargetID != uiMoveTargetSoldierId ) - { - *puiNewEvent = A_CHANGE_TO_MOVE; - return; - } - } - else - { - *puiNewEvent = A_CHANGE_TO_MOVE; - return; - } - } - *puiNewEvent = T_ON_TERRAIN; - break; - - case MOVE_MODE: - - uiMoveTargetSoldierId = NO_SOLDIER; - - // Check for being on terrain - if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) - { - if ( IsValidJumpLocation( pSoldier, usMapPos, TRUE ) ) - { - gsJumpOverGridNo = usMapPos; - *puiNewEvent = JP_ON_TERRAIN; - return; - } - else - { - if( gfUIFullTargetFound ) - { - // ATE: Don't do this automatically for enemies...... - if ( MercPtrs[ gusUIFullTargetID ]->bTeam != ENEMY_TEAM ) - { - uiMoveTargetSoldierId = gusUIFullTargetID; - if ( IsValidTalkableNPC( (UINT8)gusUIFullTargetID, FALSE, FALSE, FALSE ) && !_KeyDown( SHIFT ) && !AM_AN_EPC( pSoldier ) && !ValidQuickExchangePosition( ) ) - { - *puiNewEvent = T_CHANGE_TO_TALKING; - return; - } - } - } - } - } - *puiNewEvent = M_ON_TERRAIN; - break; - - case ACTION_MODE: - - // First check if we are on a guy, if so, make selected if it's ours - // Check if the guy is visible - guiUITargetSoldierId = NOBODY; - - fOnValidGuy = FALSE; - - if ( gfUIFullTargetFound ) - //if ( gfUIFullTargetFound ) - { - if ( IsValidTargetMerc( (UINT8)gusUIFullTargetID ) ) - { - guiUITargetSoldierId = gusUIFullTargetID; - - if ( MercPtrs[ gusUIFullTargetID ]->bTeam != gbPlayerNum ) - { - fOnValidGuy = TRUE; - } - else - { - if ( gUIActionModeChangeDueToMouseOver ) - { - *puiNewEvent = A_CHANGE_TO_MOVE; - return; - } - } - } - } - else - { - if ( gUIActionModeChangeDueToMouseOver ) + if ( gusUIFullTargetID != uiMoveTargetSoldierId ) { *puiNewEvent = A_CHANGE_TO_MOVE; return; } } - *puiNewEvent = A_ON_TERRAIN; - break; - - case GETTINGITEM_MODE: - - break; - - case TALKINGMENU_MODE: - - if ( HandleTalkingMenu( ) ) + else { *puiNewEvent = A_CHANGE_TO_MOVE; + return; } - break; + } + *puiNewEvent = T_ON_TERRAIN; + break; - case EXITSECTORMENU_MODE: + case MOVE_MODE: - if ( HandleSectorExitMenu( ) ) + uiMoveTargetSoldierId = NO_SOLDIER; + + // Check for being on terrain + if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + { + if ( IsValidJumpLocation( pSoldier, usMapPos, TRUE ) ) { - *puiNewEvent = A_CHANGE_TO_MOVE; + gsJumpOverGridNo = usMapPos; + *puiNewEvent = JP_ON_TERRAIN; + return; } - break; - - case OPENDOOR_MENU_MODE: - bHandleCode = HandleOpenDoorMenu( ); // I think its nicer to avoid assignments in conditionals (jonathanl) - if ( bHandleCode ) + else { - // OK, IF we are not canceling, set ui back! - if ( bHandleCode == 2 ) + if( gfUIFullTargetFound ) { - *puiNewEvent = A_CHANGE_TO_MOVE; + // ATE: Don't do this automatically for enemies...... + if ( MercPtrs[ gusUIFullTargetID ]->bTeam != ENEMY_TEAM ) + { + uiMoveTargetSoldierId = gusUIFullTargetID; + if ( IsValidTalkableNPC( (UINT8)gusUIFullTargetID, FALSE, FALSE, FALSE ) && !_KeyDown( SHIFT ) && !AM_AN_EPC( pSoldier ) && !ValidQuickExchangePosition( ) ) + { + *puiNewEvent = T_CHANGE_TO_TALKING; + return; + } + } + } + } + } + *puiNewEvent = M_ON_TERRAIN; + break; + + case ACTION_MODE: + + // First check if we are on a guy, if so, make selected if it's ours + // Check if the guy is visible + guiUITargetSoldierId = NOBODY; + + fOnValidGuy = FALSE; + + if ( gfUIFullTargetFound ) + //if ( gfUIFullTargetFound ) + { + if ( IsValidTargetMerc( (UINT8)gusUIFullTargetID ) ) + { + guiUITargetSoldierId = gusUIFullTargetID; + + if ( MercPtrs[ gusUIFullTargetID ]->bTeam != gbPlayerNum ) + { + fOnValidGuy = TRUE; } else { + if ( gUIActionModeChangeDueToMouseOver ) + { + *puiNewEvent = A_CHANGE_TO_MOVE; + return; + } } } - break; + } + else + { + if ( gUIActionModeChangeDueToMouseOver ) + { + *puiNewEvent = A_CHANGE_TO_MOVE; + return; + } + } + *puiNewEvent = A_ON_TERRAIN; + break; - case JUMPOVER_MODE: + case GETTINGITEM_MODE: - // ATE: Make sure! - if ( gsJumpOverGridNo != usMapPos ) + break; + + case TALKINGMENU_MODE: + + if ( HandleTalkingMenu( ) ) + { + *puiNewEvent = A_CHANGE_TO_MOVE; + } + break; + + case EXITSECTORMENU_MODE: + + if ( HandleSectorExitMenu( ) ) + { + *puiNewEvent = A_CHANGE_TO_MOVE; + } + break; + + case OPENDOOR_MENU_MODE: + bHandleCode = HandleOpenDoorMenu( ); // I think its nicer to avoid assignments in conditionals (jonathanl) + if ( bHandleCode ) + { + // OK, IF we are not canceling, set ui back! + if ( bHandleCode == 2 ) { *puiNewEvent = A_CHANGE_TO_MOVE; } else { - *puiNewEvent = JP_ON_TERRAIN; } - break; + } + break; - case CONFIRM_MOVE_MODE: + case JUMPOVER_MODE: - if ( usMapPos != usOldMapPos ) + // ATE: Make sure! + if ( gsJumpOverGridNo != usMapPos ) + { + *puiNewEvent = A_CHANGE_TO_MOVE; + } + else + { + *puiNewEvent = JP_ON_TERRAIN; + } + break; + + case CONFIRM_MOVE_MODE: + + if ( usMapPos != usOldMapPos ) + { + // Switch event out of confirm mode + *puiNewEvent = A_CHANGE_TO_MOVE; + + // Set off ALL move.... + gfUIAllMoveOn = FALSE; + + // ERASE PATH + ErasePath( TRUE ); + } + break; + + case CONFIRM_ACTION_MODE: + + // DONOT CANCEL IF BURST + if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) + { + if ( pSoldier->bDoBurst ) + { + pSoldier->sEndGridNo = usMapPos; + + if ( pSoldier->sEndGridNo != pSoldier->sStartGridNo && fLeftButtonDown ) + { + pSoldier->fDoSpread = TRUE; + gfBeginBurstSpreadTracking = TRUE; + } + + if ( pSoldier->fDoSpread ) + { + // Accumulate gridno + AccumulateBurstLocation( usMapPos ); + + *puiNewEvent = CA_ON_TERRAIN; + break; + } + } + } + + // First check if we are on a guy, if so, make selected if it's ours + if ( gfUIFullTargetFound ) + { + if ( guiUITargetSoldierId != gusUIFullTargetID ) { // Switch event out of confirm mode - *puiNewEvent = A_CHANGE_TO_MOVE; - - // Set off ALL move.... - gfUIAllMoveOn = FALSE; - - // ERASE PATH - ErasePath( TRUE ); - } - break; - - case CONFIRM_ACTION_MODE: - - // DONOT CANCEL IF BURST - if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) - { - if ( pSoldier->bDoBurst ) - { - pSoldier->sEndGridNo = usMapPos; - - if ( pSoldier->sEndGridNo != pSoldier->sStartGridNo && fLeftButtonDown ) - { - pSoldier->fDoSpread = TRUE; - gfBeginBurstSpreadTracking = TRUE; - } - - if ( pSoldier->fDoSpread ) - { - // Accumulate gridno - AccumulateBurstLocation( usMapPos ); - - *puiNewEvent = CA_ON_TERRAIN; - break; - } - } - } - - // First check if we are on a guy, if so, make selected if it's ours - if ( gfUIFullTargetFound ) - { - if ( guiUITargetSoldierId != gusUIFullTargetID ) - { - // Switch event out of confirm mode - *puiNewEvent = CA_END_CONFIRM_ACTION; - } - else - { - *puiNewEvent = CA_ON_TERRAIN; - } + *puiNewEvent = CA_END_CONFIRM_ACTION; } else { - // OK, if we were on a guy, and now we are off, go back! - if ( fOnValidGuy ) + *puiNewEvent = CA_ON_TERRAIN; + } + } + else + { + // OK, if we were on a guy, and now we are off, go back! + if ( fOnValidGuy ) + { + // Switch event out of confirm mode + *puiNewEvent = CA_END_CONFIRM_ACTION; + } + else + { + if ( ConfirmActionCancel( usMapPos, usOldMapPos ) ) { // Switch event out of confirm mode *puiNewEvent = CA_END_CONFIRM_ACTION; } else { - if ( ConfirmActionCancel( usMapPos, usOldMapPos ) ) - { - // Switch event out of confirm mode - *puiNewEvent = CA_END_CONFIRM_ACTION; - } - else - { - *puiNewEvent = CA_ON_TERRAIN; - } + *puiNewEvent = CA_ON_TERRAIN; } } - break; - - case HANDCURSOR_MODE: + } + break; - *puiNewEvent = HC_ON_TERRAIN; - break; + case HANDCURSOR_MODE: + + *puiNewEvent = HC_ON_TERRAIN; + break; } @@ -1258,68 +1269,68 @@ void GetPolledKeyboardInput( UINT32 *puiNewEvent ) // CHECK FOR CTRL switch( gCurrentUIMode ) { - case DONT_CHANGEMODE: - case CONFIRM_MOVE_MODE: - case CONFIRM_ACTION_MODE: - case LOOKCURSOR_MODE: - case TALKCURSOR_MODE: - case IDLE_MODE: - case MOVE_MODE: - case ACTION_MODE: - case HANDCURSOR_MODE: + case DONT_CHANGEMODE: + case CONFIRM_MOVE_MODE: + case CONFIRM_ACTION_MODE: + case LOOKCURSOR_MODE: + case TALKCURSOR_MODE: + case IDLE_MODE: + case MOVE_MODE: + case ACTION_MODE: + case HANDCURSOR_MODE: - if ( _KeyDown( CTRL ) ) - { - if ( fCtrlDown == FALSE ) - { - ErasePath( TRUE ); - gfPlotNewMovement = TRUE; - } - fCtrlDown = TRUE; - *puiNewEvent = HC_ON_TERRAIN; - - } - if ( !(_KeyDown( CTRL ) ) && fCtrlDown ) - { - fCtrlDown = FALSE; - *puiNewEvent = M_ON_TERRAIN; - gfPlotNewMovement = TRUE; - } - break; + if ( _KeyDown( CTRL ) ) + { + if ( fCtrlDown == FALSE ) + { + ErasePath( TRUE ); + gfPlotNewMovement = TRUE; + } + fCtrlDown = TRUE; + *puiNewEvent = HC_ON_TERRAIN; + + } + if ( !(_KeyDown( CTRL ) ) && fCtrlDown ) + { + fCtrlDown = FALSE; + *puiNewEvent = M_ON_TERRAIN; + gfPlotNewMovement = TRUE; + } + break; } // CHECK FOR ALT switch( gCurrentUIMode ) { - case MOVE_MODE: + case MOVE_MODE: - if ( _KeyDown( ALT ) ) + if ( _KeyDown( ALT ) ) + { + if ( fAltDown == FALSE ) + { + // Get currently selected guy and change reverse.... + if ( gusSelectedSoldier != NOBODY ) { - if ( fAltDown == FALSE ) - { - // Get currently selected guy and change reverse.... - if ( gusSelectedSoldier != NOBODY ) - { - gUIUseReverse = TRUE; - ErasePath( TRUE ); - gfPlotNewMovement = TRUE; - } - } - fAltDown = TRUE; - + gUIUseReverse = TRUE; + ErasePath( TRUE ); + gfPlotNewMovement = TRUE; } - if ( !(_KeyDown( ALT ) ) && fAltDown ) - { - if ( gusSelectedSoldier != NOBODY ) - { - gUIUseReverse = FALSE; - ErasePath( TRUE ); - gfPlotNewMovement = TRUE; - } + } + fAltDown = TRUE; - fAltDown = FALSE; - } - break; + } + if ( !(_KeyDown( ALT ) ) && fAltDown ) + { + if ( gusSelectedSoldier != NOBODY ) + { + gUIUseReverse = FALSE; + ErasePath( TRUE ); + gfPlotNewMovement = TRUE; + } + + fAltDown = FALSE; + } + break; } // Check realtime input! @@ -1347,7 +1358,7 @@ void GetPolledKeyboardInput( UINT32 *puiNewEvent ) fShifted2 = TRUE; if ( gCurrentUIMode != MOVE_MODE && gCurrentUIMode != CONFIRM_MOVE_MODE ) { - //puiNewEvent = M_ON_TERRAIN; + //puiNewEvent = M_ON_TERRAIN; } } if ( !(_KeyDown( SHIFT ) ) && fShifted2 ) @@ -1355,13 +1366,13 @@ void GetPolledKeyboardInput( UINT32 *puiNewEvent ) fShifted2 = FALSE; if ( gCurrentUIMode != ACTION_MODE && gCurrentUIMode != CONFIRM_ACTION_MODE ) { - // *puiNewEvent = A_ON_TERRAIN; + // *puiNewEvent = A_ON_TERRAIN; } } } - if( _KeyDown( DEL ) ) + if( _KeyDown( DEL ) ) { DisplayCoverOfSelectedGridNo( ); @@ -1397,7 +1408,7 @@ extern BOOLEAN gfUserTurnRegionActive; void GetKeyboardInput( UINT32 *puiNewEvent ) { - InputAtom InputEvent; + InputAtom InputEvent; BOOLEAN fKeyTaken = FALSE; POINT MousePos; //SOLDIERTYPE *pSoldier; @@ -1409,27 +1420,27 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) GetCursorPos(&MousePos); - GetMouseMapPos( (INT16 *)&usMapPos ); + GetMouseMapPos( &usMapPos ); - while (DequeueEvent(&InputEvent) == TRUE) - { + while (DequeueEvent(&InputEvent) == TRUE) + { // HOOK INTO MOUSE HOOKS switch(InputEvent.usEvent) - { - case LEFT_BUTTON_DOWN: - MouseSystemHook(LEFT_BUTTON_DOWN, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown); - break; - case LEFT_BUTTON_UP: - MouseSystemHook(LEFT_BUTTON_UP, (INT16)MousePos.x, (INT16)MousePos.y ,_LeftButtonDown, _RightButtonDown); - break; - case RIGHT_BUTTON_DOWN: - MouseSystemHook(RIGHT_BUTTON_DOWN, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown); - break; - case RIGHT_BUTTON_UP: - MouseSystemHook(RIGHT_BUTTON_UP, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown); - break; + { + case LEFT_BUTTON_DOWN: + MouseSystemHook(LEFT_BUTTON_DOWN, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown); + break; + case LEFT_BUTTON_UP: + MouseSystemHook(LEFT_BUTTON_UP, (INT16)MousePos.x, (INT16)MousePos.y ,_LeftButtonDown, _RightButtonDown); + break; + case RIGHT_BUTTON_DOWN: + MouseSystemHook(RIGHT_BUTTON_DOWN, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown); + break; + case RIGHT_BUTTON_UP: + MouseSystemHook(RIGHT_BUTTON_UP, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown); + break; - } + } // handle for fast help text for interface stuff if( IsTheInterfaceFastHelpTextActive() ) @@ -1488,22 +1499,22 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) /* if( (InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == ) ) { - HandlePlayerPauseUnPauseOfGame( ); + HandlePlayerPauseUnPauseOfGame( ); } */ - if ((InputEvent.usEvent == KEY_UP )&& ( InputEvent.usParam == PAUSE ) && !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV) ) - { + if ((InputEvent.usEvent == KEY_UP )&& ( InputEvent.usParam == PAUSE ) && !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV) ) + { // Pause game! HandlePlayerPauseUnPauseOfGame( ); - } + } // FIRST DO KEYS THAT ARE USED EVERYWHERE! - if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == 'x') && ( InputEvent.usKeyState & ALT_DOWN )) - { + if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == 'x') && ( InputEvent.usKeyState & ALT_DOWN )) + { HandleShortCutExitState( ); //*puiNewEvent = I_EXIT; - } + } if ((InputEvent.usEvent == KEY_UP )&& ( InputEvent.usParam == ESC) ) { @@ -1562,14 +1573,14 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) { if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == ENTER ) && ( InputEvent.usKeyState & ALT_DOWN ) ) { - // ESCAPE ENEMY'S TURN - EndAIDeadlock(); + // ESCAPE ENEMY'S TURN + EndAIDeadlock(); - // Decrease global busy counter... - gTacticalStatus.ubAttackBusyCount = 0; + // Decrease global busy counter... + gTacticalStatus.ubAttackBusyCount = 0; - guiPendingOverrideEvent = LU_ENDUILOCK; - UIHandleLUIEndLock( NULL ); + guiPendingOverrideEvent = LU_ENDUILOCK; + UIHandleLUIEndLock( NULL ); } } @@ -1583,13 +1594,13 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) { if ( CHEATER_CHEAT_LEVEL( ) && (InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == ENTER ) && ( InputEvent.usKeyState & CTRL_DOWN ) ) { - //UNLOCK UI - EscapeUILock( ); + //UNLOCK UI + EscapeUILock( ); } else if ( (InputEvent.usEvent == KEY_DOWN ) && InputEvent.usParam == ENTER ) { - // Cycle through enemys - CycleThroughKnownEnemies( ); + // Cycle through enemys + CycleThroughKnownEnemies( ); } } } @@ -1603,31 +1614,31 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) // Do some checks based on what mode we are in switch( gCurrentUIMode ) { - case EXITSECTORMENU_MODE: + case EXITSECTORMENU_MODE: - HandleSectorExitMenuKeys( &InputEvent, puiNewEvent ); - continue; + HandleSectorExitMenuKeys( &InputEvent, puiNewEvent ); + continue; - case GETTINGITEM_MODE: + case GETTINGITEM_MODE: - HandleItemMenuKeys( &InputEvent, puiNewEvent ); - continue; + HandleItemMenuKeys( &InputEvent, puiNewEvent ); + continue; - case MENU_MODE: + case MENU_MODE: - HandleMenuKeys( &InputEvent, puiNewEvent ); - continue; + HandleMenuKeys( &InputEvent, puiNewEvent ); + continue; - case OPENDOOR_MENU_MODE: + case OPENDOOR_MENU_MODE: - HandleOpenDoorMenuKeys( &InputEvent, puiNewEvent ); - continue; + HandleOpenDoorMenuKeys( &InputEvent, puiNewEvent ); + continue; } // CHECK ESC KEYS HERE.... - if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == ESC )) - { + if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == ESC )) + { //EscapeUILock( ); #ifdef JA2TESTVERSION if ( InAirRaid( ) ) @@ -1636,7 +1647,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) } #endif - // Cancel out of spread burst... + // Cancel out of spread burst... gfBeginBurstSpreadTracking = FALSE; gfRTClickLeftHoldIntercepted = TRUE; if ( gusSelectedSoldier != NO_SOLDIER ) @@ -1674,25 +1685,25 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) *puiNewEvent = A_CHANGE_TO_MOVE; } - if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) ) - { - if ( gusSelectedSoldier != NO_SOLDIER ) - { - // If soldier is not stationary, stop - StopSoldier( MercPtrs[ gusSelectedSoldier ] ); - *puiNewEvent = A_CHANGE_TO_MOVE; - } - // ATE: OK, stop any mercs who are moving by selection method.... - StopRubberBandedMercFromMoving( ); - } + if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) ) + { + if ( gusSelectedSoldier != NO_SOLDIER ) + { + // If soldier is not stationary, stop + StopSoldier( MercPtrs[ gusSelectedSoldier ] ); + *puiNewEvent = A_CHANGE_TO_MOVE; + } + // ATE: OK, stop any mercs who are moving by selection method.... + StopRubberBandedMercFromMoving( ); + } - } + } // CHECK ESC KEYS HERE.... - if ((InputEvent.usEvent == KEY_DOWN ) && ( InputEvent.usParam == BACKSPACE ) ) - { - StopAnyCurrentlyTalkingSpeech( ); - } + if ((InputEvent.usEvent == KEY_DOWN ) && ( InputEvent.usParam == BACKSPACE ) ) + { + StopAnyCurrentlyTalkingSpeech( ); + } // IF UI HAS LOCKED, ONLY ALLOW EXIT! @@ -1702,8 +1713,8 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) } // Check all those we want if enemy's turn - if ((InputEvent.usEvent == KEY_UP )&& ( InputEvent.usParam == 'q') ) - { + if ((InputEvent.usEvent == KEY_UP )&& ( InputEvent.usParam == 'q') ) + { if ( InputEvent.usKeyState & ALT_DOWN ) { if ( CHEATER_CHEAT_LEVEL( ) ) @@ -1725,18 +1736,18 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) InvalidateWorldRedundency(); SetRenderFlags( RENDER_FLAG_FULL ); } - + } else if ( InputEvent.usKeyState & CTRL_DOWN ) - { + { #ifdef JA2BETAVERSION if ( CHEATER_CHEAT_LEVEL( ) ) { LeaveTacticalScreen( ANIEDIT_SCREEN ); } #endif - } - else + } + else { if ( INFORMATION_CHEAT_LEVEL( ) ) { @@ -1770,8 +1781,8 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) } #ifdef JA2TESTVERSION - if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '0') && ( InputEvent.usKeyState & ALT_DOWN )) - { + if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '0') && ( InputEvent.usKeyState & ALT_DOWN )) + { INT32 i = 0; INT16 sGridNo; INT32 iTime = GetJA2Clock( ); @@ -1790,23 +1801,23 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) #ifdef NETWORKED // DEF: Test Networking - if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '0') && ( InputEvent.usKeyState & ALT_DOWN )) - { + if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '0') && ( InputEvent.usKeyState & ALT_DOWN )) + { DisplayMultiPlayerInfo(); - } - if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '9') && ( InputEvent.usKeyState & ALT_DOWN )) - { + } + if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '9') && ( InputEvent.usKeyState & ALT_DOWN )) + { DisplayDirectPlayInfo(); - } - if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '8') && ( InputEvent.usKeyState & ALT_DOWN )) - { + } + if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '8') && ( InputEvent.usKeyState & ALT_DOWN )) + { DisplayDirectPlayPlayerInfo(); - } + } - if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '7') && ( InputEvent.usKeyState & ALT_DOWN )) - { + if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '7') && ( InputEvent.usKeyState & ALT_DOWN )) + { SetDisplayFlag(); - } + } #endif if( InputEvent.usEvent == KEY_DOWN ) @@ -1873,951 +1884,951 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) } break; - case TAB: - // nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel - if ( ( gpItemPointer == NULL ) && - ( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ UPDOWN_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) - { - UIHandleChangeLevel( NULL ); + case TAB: + // nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel + if ( ( gpItemPointer == NULL ) && + ( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ UPDOWN_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) + { + UIHandleChangeLevel( NULL ); - if ( gsCurInterfacePanel == SM_PANEL ) - { - // Remember soldier's new value - gpSMCurrentMerc->bUIInterfaceLevel = (INT8)gsInterfaceLevel; - } + if ( gsCurInterfacePanel == SM_PANEL ) + { + // Remember soldier's new value + gpSMCurrentMerc->bUIInterfaceLevel = (INT8)gsInterfaceLevel; } - break; + } + break; - case F1: - if( fShift ) - { - HandleSelectMercSlot( 0, LOCATE_MERC_ONCE ); - } + case F1: + if( fShift ) + { + HandleSelectMercSlot( 0, LOCATE_MERC_ONCE ); + } #ifdef JA2TESTVERSION - else if( fAlt ) - { - TestMeanWhile( 15 ); - } - else if( fCtrl ) - { - TestMeanWhile( 10 ); - } + else if( fAlt ) + { + TestMeanWhile( 15 ); + } + else if( fCtrl ) + { + TestMeanWhile( 10 ); + } #endif - else - HandleSelectMercSlot( 0, LOCATEANDSELECT_MERC ); - break; - case F2: - if( fShift ) - HandleSelectMercSlot( 1, LOCATE_MERC_ONCE ); + else + HandleSelectMercSlot( 0, LOCATEANDSELECT_MERC ); + break; + case F2: + if( fShift ) + HandleSelectMercSlot( 1, LOCATE_MERC_ONCE ); #ifdef JA2TESTVERSION - else if( fAlt ) - { - TestMeanWhile( 1 ); - } - else if( fCtrl ) - { - TestMeanWhile( 11 ); - } + else if( fAlt ) + { + TestMeanWhile( 1 ); + } + else if( fCtrl ) + { + TestMeanWhile( 11 ); + } #endif - else - HandleSelectMercSlot( 1, LOCATEANDSELECT_MERC ); - break; - case F3: - if( fShift ) - HandleSelectMercSlot( 2, LOCATE_MERC_ONCE ); + else + HandleSelectMercSlot( 1, LOCATEANDSELECT_MERC ); + break; + case F3: + if( fShift ) + HandleSelectMercSlot( 2, LOCATE_MERC_ONCE ); #ifdef JA2TESTVERSION - else if( fAlt ) - { - TestMeanWhile( 2 ); - } - else if( fCtrl ) - { - TestMeanWhile( 12 ); - } + else if( fAlt ) + { + TestMeanWhile( 2 ); + } + else if( fCtrl ) + { + TestMeanWhile( 12 ); + } #endif - else - HandleSelectMercSlot( 2, LOCATEANDSELECT_MERC ); - break; - case F4: - if( fShift ) - HandleSelectMercSlot( 3, LOCATE_MERC_ONCE ); + else + HandleSelectMercSlot( 2, LOCATEANDSELECT_MERC ); + break; + case F4: + if( fShift ) + HandleSelectMercSlot( 3, LOCATE_MERC_ONCE ); #ifdef JA2TESTVERSION - else if( fAlt ) - { - TestMeanWhile( 3 ); - } - else if( fCtrl ) - { - TestMeanWhile( 13 ); - } + else if( fAlt ) + { + TestMeanWhile( 3 ); + } + else if( fCtrl ) + { + TestMeanWhile( 13 ); + } #endif - else - HandleSelectMercSlot( 3, LOCATEANDSELECT_MERC ); - break; - case F5: - if( fShift ) - HandleSelectMercSlot( 4, LOCATE_MERC_ONCE ); + else + HandleSelectMercSlot( 3, LOCATEANDSELECT_MERC ); + break; + case F5: + if( fShift ) + HandleSelectMercSlot( 4, LOCATE_MERC_ONCE ); #ifdef JA2TESTVERSION - else if( fAlt ) - { - TestMeanWhile( 4 ); - } - else if( fCtrl ) - { - TestMeanWhile( 14 ); - } + else if( fAlt ) + { + TestMeanWhile( 4 ); + } + else if( fCtrl ) + { + TestMeanWhile( 14 ); + } #endif - else - HandleSelectMercSlot( 4, LOCATEANDSELECT_MERC ); - break; - case F6: - if( fShift ) - HandleSelectMercSlot( 5, LOCATE_MERC_ONCE ); + else + HandleSelectMercSlot( 4, LOCATEANDSELECT_MERC ); + break; + case F6: + if( fShift ) + HandleSelectMercSlot( 5, LOCATE_MERC_ONCE ); #ifdef JA2TESTVERSION - else if( fAlt ) - { - TestMeanWhile( 5 ); - } - else if( fCtrl ) - { - TestMeanWhile( 15 ); - } + else if( fAlt ) + { + TestMeanWhile( 5 ); + } + else if( fCtrl ) + { + TestMeanWhile( 15 ); + } #endif - else - HandleSelectMercSlot( 5, LOCATEANDSELECT_MERC ); - break; + else + HandleSelectMercSlot( 5, LOCATEANDSELECT_MERC ); + break; #ifdef JA2TESTVERSION - case F7: - if( fAlt ) - { - TestMeanWhile( 16 ); - } - break; - case F8: + case F7: + if( fAlt ) + { + TestMeanWhile( 16 ); + } + break; + case F8: - if( fAlt ) - { - TestMeanWhile( 7 ); - } - break; + if( fAlt ) + { + TestMeanWhile( 7 ); + } + break; - case F9: + case F9: - if( fCtrl ) - { - TestMeanWhile( 8 ); - } - else - { - #ifdef JA2EDITOR - *puiNewEvent = I_ENTER_EDIT_MODE; - gfMercResetUponEditorEntry = !fAlt; - #endif - } - break; - case F10: + if( fCtrl ) + { + TestMeanWhile( 8 ); + } + else + { +#ifdef JA2EDITOR + *puiNewEvent = I_ENTER_EDIT_MODE; + gfMercResetUponEditorEntry = !fAlt; +#endif + } + break; + case F10: - if( fAlt ) - { - TestMeanWhile( 9 ); - } - break; + if( fAlt ) + { + TestMeanWhile( 9 ); + } + break; #endif - case F11: + case F11: - if( fAlt ) - { + if( fAlt ) + { #ifdef JA2TESTVERSION - SOLDIERTYPE *pSoldier; + SOLDIERTYPE *pSoldier; - // Get selected soldier - if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) - { - if( pSoldier->ubID == 46 ) - { - // Change guy to drunk larry - ForceSoldierProfileID( pSoldier, 47 ); - } - else - { - // Change guy to normal larry - ForceSoldierProfileID( pSoldier, 46 ); - } - - // Dirty interface - DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); - } -#endif - } - - else + // Get selected soldier + if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) { - if( DEBUG_CHEAT_LEVEL( ) ) + if( pSoldier->ubID == 46 ) { - GetMouseMapPos( &gsQdsEnteringGridNo ); - LeaveTacticalScreen( QUEST_DEBUG_SCREEN ); + // Change guy to drunk larry + ForceSoldierProfileID( pSoldier, 47 ); + } + else + { + // Change guy to normal larry + ForceSoldierProfileID( pSoldier, 46 ); } - } - break; - case F12: + // Dirty interface + DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); + } +#endif + } + + else + { + if( DEBUG_CHEAT_LEVEL( ) ) + { + GetMouseMapPos( &gusQdsEnteringGridNo ); + LeaveTacticalScreen( QUEST_DEBUG_SCREEN ); + } + } + break; + + case F12: #ifdef JA2TESTVERSION - if( fAlt ) - { - UINT8 ubProfile = TONY; + if( fAlt ) + { + UINT8 ubProfile = TONY; - GetMouseMapPos( &gsQdsEnteringGridNo ); - AddShopkeeperToGridNo( ubProfile, gsQdsEnteringGridNo ); - EnterShopKeeperInterfaceScreen( ubProfile ); - } + GetMouseMapPos( &gusQdsEnteringGridNo ); + AddShopkeeperToGridNo( ubProfile, gusQdsEnteringGridNo ); + EnterShopKeeperInterfaceScreen( ubProfile ); + } #endif - //clear tactical of messages - if( fCtrl ) + //clear tactical of messages + if( fCtrl ) + { + ClearTacticalMessageQueue( ); + } + else if ( !fAlt ) + { + ClearDisplayedListOfTacticalStrings( ); + } + break; + + case '1': + + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) { - ClearTacticalMessageQueue( ); + //ChangeSoldiersBodyType( TANK_NW, TRUE ); + // MercPtrs[ gusSelectedSoldier ]->uiStatusFlags |= SOLDIER_CREATURE; + //EVENT_InitNewSoldierAnim( MercPtrs[ gusSelectedSoldier ], CRIPPLE_BEG, 0 , TRUE ); } - else if ( !fAlt ) + } + else + ChangeCurrentSquad( 0 ); + break; + + case '2': + + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) { - ClearDisplayedListOfTacticalStrings( ); + ChangeSoldiersBodyType( INFANT_MONSTER, TRUE ); } - break; - - case '1': - - if( fAlt ) + } + else if( fCtrl ) //toggle between the different npc debug modes + { + if ( CHEATER_CHEAT_LEVEL( ) ) { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - //ChangeSoldiersBodyType( TANK_NW, TRUE ); - // MercPtrs[ gusSelectedSoldier ]->uiStatusFlags |= SOLDIER_CREATURE; - //EVENT_InitNewSoldierAnim( MercPtrs[ gusSelectedSoldier ], CRIPPLE_BEG, 0 , TRUE ); - } + ToggleQuestDebugModes( QD_NPC_MSG ); } - else - ChangeCurrentSquad( 0 ); - break; + } + else + ChangeCurrentSquad( 1 ); + break; - case '2': - - if( fAlt ) + case '3': + + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - ChangeSoldiersBodyType( INFANT_MONSTER, TRUE ); - } + EVENT_InitNewSoldierAnim( MercPtrs[ gusSelectedSoldier ], KID_SKIPPING, 0 , TRUE ); + + //ChangeSoldiersBodyType( LARVAE_MONSTER, TRUE ); + //MercPtrs[ gusSelectedSoldier ]->usAttackingWeapon = TANK_CANNON; + //LocateSoldier( gusSelectedSoldier, FALSE ); + //EVENT_FireSoldierWeapon( MercPtrs[ gusSelectedSoldier ], usMapPos ); } - else if( fCtrl ) //toggle between the different npc debug modes + } + else + ChangeCurrentSquad( 2 ); + + break; + + case '4': + + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - ToggleQuestDebugModes( QD_NPC_MSG ); - } + ChangeSoldiersBodyType( CRIPPLECIV, TRUE ); } - else - ChangeCurrentSquad( 1 ); - break; + } + else + ChangeCurrentSquad( 3 ); - case '3': + //ChangeSoldiersBodyType( BLOODCAT, FALSE ); + break; - if( fAlt ) + case '5': + + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - EVENT_InitNewSoldierAnim( MercPtrs[ gusSelectedSoldier ], KID_SKIPPING, 0 , TRUE ); - - //ChangeSoldiersBodyType( LARVAE_MONSTER, TRUE ); - //MercPtrs[ gusSelectedSoldier ]->usAttackingWeapon = TANK_CANNON; - //LocateSoldier( gusSelectedSoldier, FALSE ); - //EVENT_FireSoldierWeapon( MercPtrs[ gusSelectedSoldier ], usMapPos ); - } + ChangeSoldiersBodyType( YAM_MONSTER, TRUE ); } - else - ChangeCurrentSquad( 2 ); + } + else + ChangeCurrentSquad( 4 ); + break; - break; + case '6': + ChangeCurrentSquad( 5 ); + break; - case '4': + case '7': + ChangeCurrentSquad( 6 ); + break; - if( fAlt ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - ChangeSoldiersBodyType( CRIPPLECIV, TRUE ); - } - } - else - ChangeCurrentSquad( 3 ); + case '8': + ChangeCurrentSquad( 7 ); + break; - //ChangeSoldiersBodyType( BLOODCAT, FALSE ); - break; + case '9': + ChangeCurrentSquad( 8 ); + break; - case '5': + case '0': + ChangeCurrentSquad( 9 ); + break; - if( fAlt ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - ChangeSoldiersBodyType( YAM_MONSTER, TRUE ); - } - } - else - ChangeCurrentSquad( 4 ); - break; + case 'x': - case '6': - ChangeCurrentSquad( 5 ); - break; + if ( !fCtrl && !fAlt ) + { + // Exchange places... + SOLDIERTYPE *pSoldier1, *pSoldier2; - case '7': - ChangeCurrentSquad( 6 ); - break; - - case '8': - ChangeCurrentSquad( 7 ); - break; - - case '9': - ChangeCurrentSquad( 8 ); - break; - - case '0': - ChangeCurrentSquad( 9 ); - break; - - case 'x': - - if ( !fCtrl && !fAlt ) - { - // Exchange places... - SOLDIERTYPE *pSoldier1, *pSoldier2; - - //Check if we have a good selected guy - if ( gusSelectedSoldier != NOBODY ) - { - pSoldier1 = MercPtrs[ gusSelectedSoldier ]; - - if ( gfUIFullTargetFound ) - { - // Get soldier... - pSoldier2 = MercPtrs[ gusUIFullTargetID ]; - - // Check if both OK.... - if ( pSoldier1->bLife >= OKLIFE && pSoldier2->ubID != gusSelectedSoldier ) - { - if ( pSoldier2->bLife >= OKLIFE ) - { - if (CanSoldierReachGridNoInGivenTileLimit( pSoldier1, pSoldier2->sGridNo, 1, (INT8)gsInterfaceLevel ) ) - { - // Exclude enemies.... - if ( !pSoldier2->bNeutral && (pSoldier2->bSide != gbPlayerNum ) ) - { - - } - else - { - if ( CanExchangePlaces( pSoldier1, pSoldier2, TRUE ) ) - { - // All's good! - SwapMercPositions( pSoldier1, pSoldier2 ); - - DeductPoints( pSoldier1, AP_EXCHANGE_PLACES, 0 ); - DeductPoints( pSoldier2, AP_EXCHANGE_PLACES, 0 ); - } - } - } - } - } - } - - } - } - break; - - case '/': - - // Center to guy.... + //Check if we have a good selected guy if ( gusSelectedSoldier != NOBODY ) { - LocateSoldier( gusSelectedSoldier, 10 ); - } - break; + pSoldier1 = MercPtrs[ gusSelectedSoldier ]; - - case 'a': - - if ( fCtrl ) - { -#ifdef GERMAN - if ( gubCheatLevel == 3 ) + if ( gfUIFullTargetFound ) { - gubCheatLevel++; - fGoodCheatLevelKey = TRUE; - } - else if ( gubCheatLevel == 5 ) - { - gubCheatLevel++; - // ATE; We're done.... start cheat mode.... - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_CHEAT_LEVEL_TWO ] ); - SetHistoryFact( HISTORY_CHEAT_ENABLED, 0, GetWorldTotalMin(), -1, -1 ); - } - else - { - RESET_CHEAT_LEVEL(); - } -#else - if ( gubCheatLevel == 1 ) - { - gubCheatLevel++; - fGoodCheatLevelKey = TRUE; - } - else - { - RESET_CHEAT_LEVEL(); - } -#endif - } - else if ( fAlt ) - { -#ifdef JA2TESTVERSION - // ToggleMercsNeverQuit(); - static UINT8 ubAmbientSound = 0; + // Get soldier... + pSoldier2 = MercPtrs[ gusUIFullTargetID ]; - ubAmbientSound++; - - if ( ubAmbientSound >= NUM_STEADY_STATE_AMBIENCES ) - { - ubAmbientSound = 1; - } - - SetSteadyStateAmbience( ubAmbientSound ); - -#endif - } - else - { - BeginAutoBandage( ); - } - break; - - case 'j': - - if( fAlt ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - gfNextFireJam = TRUE; - } - } - else if ( fCtrl ) - { -#ifdef JA2BETAVERSION - if ( CHEATER_CHEAT_LEVEL( ) ) - { - ToggleNPCRecordDisplay(); - } -#endif - } - else - { - SOLDIERTYPE *pjSoldier; - if ( GetSoldier( &pjSoldier, gusSelectedSoldier ) ) - { - BOOLEAN fNearHeigherLevel; - BOOLEAN fNearLowerLevel; - INT8 bDirection; - - GetMercClimbDirection( pjSoldier->ubID, &fNearLowerLevel, &fNearHeigherLevel ); - - if ( fNearLowerLevel ) + // Check if both OK.... + if ( pSoldier1->bLife >= OKLIFE && pSoldier2->ubID != gusSelectedSoldier ) { - BeginSoldierClimbDownRoof( pjSoldier ); - } - if ( fNearHeigherLevel ) - { - BeginSoldierClimbUpRoof( pjSoldier ); - } - - if ( FindFenceJumpDirection( pjSoldier, pjSoldier->sGridNo, pjSoldier->bDirection, &bDirection ) ) - { - BeginSoldierClimbFence( pjSoldier ); - } - } - } - break; - - case 'b': - - if( fAlt ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - *puiNewEvent = I_NEW_BADMERC; - } - } - else if( fCtrl ) - { -#ifndef GERMAN - if ( gubCheatLevel == 2 ) - { - gubCheatLevel++; - fGoodCheatLevelKey = TRUE; - } - else if ( gubCheatLevel == 3 ) - { - gubCheatLevel++; - fGoodCheatLevelKey = TRUE; - } - else if ( gubCheatLevel == 5 ) - { - gubCheatLevel++; - fGoodCheatLevelKey = TRUE; - } - else - { - RESET_CHEAT_LEVEL( ); - } -#else - if ( gubCheatLevel == 6 ) - { - gubCheatLevel++; - fGoodCheatLevelKey = TRUE; - } - else - { - RESET_CHEAT_LEVEL( ); - } -#endif - //gGameSettings.fOptions[ TOPTION_HIDE_BULLETS ] ^= TRUE; - } - else - { - // nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel - if ( ( gpItemPointer == NULL ) && - ( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ BURSTMODE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) - { - SetBurstMode(); - } - } - break; - case 'c': - - if( fAlt ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - CreateNextCivType(); - } - } - else if( fCtrl ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - ToggleCliffDebug(); - } - } - else - { - HandleStanceChangeFromUIKeys( ANIM_CROUCH ); - } - break; - - case 'd': - if( gTacticalStatus.uiFlags & TURNBASED && gTacticalStatus.uiFlags & INCOMBAT ) - { - if( gTacticalStatus.ubCurrentTeam == gbPlayerNum ) - { - // nothing in hand and the Done button for whichever panel we're in must be enabled - if ( ( gpItemPointer == NULL ) && !gfDisableTacticalPanelButtons && - ( ( ( gsCurInterfacePanel == SM_PANEL ) && ( ButtonList[ iSMPanelButtons[ SM_DONE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) || - ( ( gsCurInterfacePanel == TEAM_PANEL ) && ( ButtonList[ iTEAMPanelButtons[ TEAM_DONE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) ) - { - if( fAlt ) + if ( pSoldier2->bLife >= OKLIFE ) { - INT32 cnt; - SOLDIERTYPE *pSoldier; - - if ( CHEATER_CHEAT_LEVEL( ) ) + if (CanSoldierReachGridNoInGivenTileLimit( pSoldier1, pSoldier2->sGridNo, 1, (INT8)gsInterfaceLevel ) ) { - for ( pSoldier = MercPtrs[ gbPlayerNum ], cnt = 0; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++) - { - if ( pSoldier->bActive && pSoldier->bLife > 0 ) + // Exclude enemies.... + if ( !pSoldier2->bNeutral && (pSoldier2->bSide != gbPlayerNum ) ) + { + + } + else + { + if ( CanExchangePlaces( pSoldier1, pSoldier2, TRUE ) ) { - // Get APs back... - CalcNewActionPoints( pSoldier ); - - fInterfacePanelDirty = DIRTYLEVEL2; + // All's good! + SwapMercPositions( pSoldier1, pSoldier2 ); + + DeductPoints( pSoldier1, AP_EXCHANGE_PLACES, 0 ); + DeductPoints( pSoldier2, AP_EXCHANGE_PLACES, 0 ); } } } } - else //End turn only if in combat and it is the player's turn - *puiNewEvent = I_ENDTURN; } } + } -#ifdef JA2TESTVERSION - else if( fCtrl ) - AdvanceToNextDay(); -#endif - break; + } + break; - + case '/': - case 'e': + // Center to guy.... + if ( gusSelectedSoldier != NOBODY ) + { + LocateSoldier( gusSelectedSoldier, 10 ); + } + break; - if( fAlt ) + + case 'a': + + if ( fCtrl ) + { +#ifdef GERMAN + if ( gubCheatLevel == 3 ) { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - ToggleViewAllMercs(); - ToggleViewAllItems(); - } + gubCheatLevel++; + fGoodCheatLevelKey = TRUE; } -#ifdef JA2BETAVERSION - else if( fCtrl ) + else if ( gubCheatLevel == 5 ) { - ToggleMapEdgepoints(); + gubCheatLevel++; + // ATE; We're done.... start cheat mode.... + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_CHEAT_LEVEL_TWO ] ); + SetHistoryFact( HISTORY_CHEAT_ENABLED, 0, GetWorldTotalMin(), -1, -1 ); } -#endif else { - SOLDIERTYPE *pSoldier; - - if ( gusSelectedSoldier != NOBODY ) - { - pSoldier = MercPtrs[ gusSelectedSoldier ]; - - if ( pSoldier->bOppCnt > 0 ) - { - // Cycle.... - CycleVisibleEnemies( pSoldier ); - } - else - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_ENEMIES_IN_SIGHT_STR ] ); - } - } + RESET_CHEAT_LEVEL(); } - break; +#else + if ( gubCheatLevel == 1 ) + { + gubCheatLevel++; + fGoodCheatLevelKey = TRUE; + } + else + { + RESET_CHEAT_LEVEL(); + } +#endif + } + else if ( fAlt ) + { +#ifdef JA2TESTVERSION + // ToggleMercsNeverQuit(); + static UINT8 ubAmbientSound = 0; - case 'f': - if( fCtrl ) - { - if ( INFORMATION_CHEAT_LEVEL( ) ) + ubAmbientSound++; + + if ( ubAmbientSound >= NUM_STEADY_STATE_AMBIENCES ) + { + ubAmbientSound = 1; + } + + SetSteadyStateAmbience( ubAmbientSound ); + +#endif + } + else + { + BeginAutoBandage( ); + } + break; + + case 'j': + + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + gfNextFireJam = TRUE; + } + } + else if ( fCtrl ) + { +#ifdef JA2BETAVERSION + if ( CHEATER_CHEAT_LEVEL( ) ) + { + ToggleNPCRecordDisplay(); + } +#endif + } + else + { + SOLDIERTYPE *pjSoldier; + if ( GetSoldier( &pjSoldier, gusSelectedSoldier ) ) + { + BOOLEAN fNearHeigherLevel; + BOOLEAN fNearLowerLevel; + INT8 bDirection; + + GetMercClimbDirection( pjSoldier->ubID, &fNearLowerLevel, &fNearHeigherLevel ); + + if ( fNearLowerLevel ) { - //Toggle Frame Rate Display - gbFPSDisplay = !gbFPSDisplay; - DisableFPSOverlay( (BOOLEAN)!gbFPSDisplay ); - if( !gbFPSDisplay ) - SetRenderFlags( RENDER_FLAG_FULL ); + BeginSoldierClimbDownRoof( pjSoldier ); + } + if ( fNearHeigherLevel ) + { + BeginSoldierClimbUpRoof( pjSoldier ); + } + + if ( FindFenceJumpDirection( pjSoldier, pjSoldier->sGridNo, pjSoldier->bDirection, &bDirection ) ) + { + BeginSoldierClimbFence( pjSoldier ); } } - else if( fAlt ) - { - if ( gGameSettings.fOptions[ TOPTION_TRACKING_MODE ] ) - { - gGameSettings.fOptions[ TOPTION_TRACKING_MODE ] = FALSE; + } + break; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_TACKING_MODE_OFF ] ); + case 'b': + + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + *puiNewEvent = I_NEW_BADMERC; + } + } + else if( fCtrl ) + { +#ifndef GERMAN + if ( gubCheatLevel == 2 ) + { + gubCheatLevel++; + fGoodCheatLevelKey = TRUE; + } + else if ( gubCheatLevel == 3 ) + { + gubCheatLevel++; + fGoodCheatLevelKey = TRUE; + } + else if ( gubCheatLevel == 5 ) + { + gubCheatLevel++; + fGoodCheatLevelKey = TRUE; + } + else + { + RESET_CHEAT_LEVEL( ); + } +#else + if ( gubCheatLevel == 6 ) + { + gubCheatLevel++; + fGoodCheatLevelKey = TRUE; + } + else + { + RESET_CHEAT_LEVEL( ); + } +#endif + //gGameSettings.fOptions[ TOPTION_HIDE_BULLETS ] ^= TRUE; + } + else + { + // nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel + if ( ( gpItemPointer == NULL ) && + ( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ BURSTMODE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) + { + SetBurstMode(); + } + } + break; + case 'c': + + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + CreateNextCivType(); + } + } + else if( fCtrl ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + ToggleCliffDebug(); + } + } + else + { + HandleStanceChangeFromUIKeys( ANIM_CROUCH ); + } + break; + + case 'd': + if( gTacticalStatus.uiFlags & TURNBASED && gTacticalStatus.uiFlags & INCOMBAT ) + { + if( gTacticalStatus.ubCurrentTeam == gbPlayerNum ) + { + // nothing in hand and the Done button for whichever panel we're in must be enabled + if ( ( gpItemPointer == NULL ) && !gfDisableTacticalPanelButtons && + ( ( ( gsCurInterfacePanel == SM_PANEL ) && ( ButtonList[ iSMPanelButtons[ SM_DONE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) || + ( ( gsCurInterfacePanel == TEAM_PANEL ) && ( ButtonList[ iTEAMPanelButtons[ TEAM_DONE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) ) + { + if( fAlt ) + { + INT32 cnt; + SOLDIERTYPE *pSoldier; + + if ( CHEATER_CHEAT_LEVEL( ) ) + { + for ( pSoldier = MercPtrs[ gbPlayerNum ], cnt = 0; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++) + { + if ( pSoldier->bActive && pSoldier->bLife > 0 ) + { + // Get APs back... + CalcNewActionPoints( pSoldier ); + + fInterfacePanelDirty = DIRTYLEVEL2; + } + } + } + } + else //End turn only if in combat and it is the player's turn + *puiNewEvent = I_ENDTURN; + } + } + } +#ifdef JA2TESTVERSION + else if( fCtrl ) + AdvanceToNextDay(); +#endif + break; + + + + case 'e': + + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + ToggleViewAllMercs(); + ToggleViewAllItems(); + } + } +#ifdef JA2BETAVERSION + else if( fCtrl ) + { + ToggleMapEdgepoints(); + } +#endif + else + { + SOLDIERTYPE *pSoldier; + + if ( gusSelectedSoldier != NOBODY ) + { + pSoldier = MercPtrs[ gusSelectedSoldier ]; + + if ( pSoldier->bOppCnt > 0 ) + { + // Cycle.... + CycleVisibleEnemies( pSoldier ); } else { - gGameSettings.fOptions[ TOPTION_TRACKING_MODE ] = TRUE; - - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_TACKING_MODE_ON ] ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_ENEMIES_IN_SIGHT_STR ] ); } } + } + break; + + case 'f': + if( fCtrl ) + { + if ( INFORMATION_CHEAT_LEVEL( ) ) + { + //Toggle Frame Rate Display + gbFPSDisplay = !gbFPSDisplay; + DisableFPSOverlay( (BOOLEAN)!gbFPSDisplay ); + if( !gbFPSDisplay ) + SetRenderFlags( RENDER_FLAG_FULL ); + } + } + else if( fAlt ) + { + if ( gGameSettings.fOptions[ TOPTION_TRACKING_MODE ] ) + { + gGameSettings.fOptions[ TOPTION_TRACKING_MODE ] = FALSE; + + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_TACKING_MODE_OFF ] ); + } else { - INT16 sGridNo; + gGameSettings.fOptions[ TOPTION_TRACKING_MODE ] = TRUE; - //Get the gridno the cursor is at - GetMouseMapPos( &sGridNo ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_TACKING_MODE_ON ] ); + } + } + else + { + UINT16 usGridNo; - //if there is a selected soldier, and the cursor location is valid - if( gusSelectedSoldier != NOBODY && sGridNo != NOWHERE ) + //Get the gridno the cursor is at + GetMouseMapPos( &usGridNo ); + + //if there is a selected soldier, and the cursor location is valid + if( gusSelectedSoldier != NOBODY && usGridNo != NOWHERE ) + { + //if the cursor is over someone + if( gfUIFullTargetFound ) { - //if the cursor is over someone - if( gfUIFullTargetFound ) - { - //Display the range to the target - DisplayRangeToTarget( MercPtrs[ gusSelectedSoldier ], MercPtrs[ gusUIFullTargetID ]->sGridNo ); - } - else - { - //Display the range to the target - DisplayRangeToTarget( MercPtrs[ gusSelectedSoldier ], sGridNo ); - } + //Display the range to the target + DisplayRangeToTarget( MercPtrs[ gusSelectedSoldier ], MercPtrs[ gusUIFullTargetID ]->sGridNo ); + } + else + { + //Display the range to the target + DisplayRangeToTarget( MercPtrs[ gusSelectedSoldier ], usGridNo ); } } - break; + } + break; - case 'F': - if ( !(gTacticalStatus.fEnemyInSector) ) + case 'F': + if ( !(gTacticalStatus.fEnemyInSector) ) + { + HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + + for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; uiLoop++ ) //for all items in sector + { + if ( (gWorldItems[ uiLoop ].fExists) && (gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_REACHABLE) )//item exists and is reachable { - HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); - - for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; uiLoop++ ) //for all items in sector - { - if ( (gWorldItems[ uiLoop ].fExists) && (gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_REACHABLE) )//item exists and is reachable + if (( Item[ gWorldItems[ uiLoop ].o.usItem ].usItemClass == IC_GUN ) && (gGameExternalOptions.gfShiftFUnloadWeapons == TRUE) )//item is a gun and unloading is allowed + { + //Remove magazine + if ( (gWorldItems[ uiLoop ].o.usGunAmmoItem != NONE) && (gWorldItems[ uiLoop ].o.ubGunShotsLeft > 0) ) { - if (( Item[ gWorldItems[ uiLoop ].o.usItem ].usItemClass == IC_GUN ) && (gGameExternalOptions.gfShiftFUnloadWeapons == TRUE) )//item is a gun and unloading is allowed - { - //Remove magazine - if ( (gWorldItems[ uiLoop ].o.usGunAmmoItem != NONE) && (gWorldItems[ uiLoop ].o.ubGunShotsLeft > 0) ) - { - OBJECTTYPE newObj; //Create object - CreateItem(gWorldItems[ uiLoop ].o.usGunAmmoItem, 100, &newObj); - newObj.ubShotsLeft[0] = gWorldItems[ uiLoop ].o.ubGunShotsLeft; - gWorldItems[ uiLoop ].o.ubGunShotsLeft = 0; - gWorldItems[ uiLoop ].o.usGunAmmoItem = NONE; + OBJECTTYPE newObj; //Create object + CreateItem(gWorldItems[ uiLoop ].o.usGunAmmoItem, 100, &newObj); + newObj.ubShotsLeft[0] = gWorldItems[ uiLoop ].o.ubGunShotsLeft; + gWorldItems[ uiLoop ].o.ubGunShotsLeft = 0; + gWorldItems[ uiLoop ].o.usGunAmmoItem = NONE; + // put it on the ground + AddItemToPool( gWorldItems[ uiLoop ].sGridNo, &newObj, 1, gWorldItems[ uiLoop ].ubLevel, 0 , -1 ); + } + } + + //remove attachments + if ( gGameExternalOptions.gfShiftFRemoveAttachments == TRUE ) + { + for (int bAttachPos = MAX_ATTACHMENTS-1; bAttachPos >= 0; bAttachPos--) + { + if (gWorldItems[ uiLoop ].o.usAttachItem[ bAttachPos ] != NOTHING) + { + if ( !Item[ gWorldItems[ uiLoop ].o.usAttachItem[ bAttachPos ] ].inseparable ) + { + OBJECTTYPE newObj; + if (RemoveAttachment( &(gWorldItems[ uiLoop ].o), bAttachPos, &newObj )) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ ATTACHMENT_REMOVED ] ); + } // put it on the ground AddItemToPool( gWorldItems[ uiLoop ].sGridNo, &newObj, 1, gWorldItems[ uiLoop ].ubLevel, 0 , -1 ); } } - - //remove attachments - if ( gGameExternalOptions.gfShiftFRemoveAttachments == TRUE ) - { - for (int bAttachPos = MAX_ATTACHMENTS-1; bAttachPos >= 0; bAttachPos--) - { - if (gWorldItems[ uiLoop ].o.usAttachItem[ bAttachPos ] != NOTHING) - { - if ( !Item[ gWorldItems[ uiLoop ].o.usAttachItem[ bAttachPos ] ].inseparable ) - { - OBJECTTYPE newObj; - if (RemoveAttachment( &(gWorldItems[ uiLoop ].o), bAttachPos, &newObj )) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ ATTACHMENT_REMOVED ] ); - } - // put it on the ground - AddItemToPool( gWorldItems[ uiLoop ].sGridNo, &newObj, 1, gWorldItems[ uiLoop ].ubLevel, 0 , -1 ); - } - } - } - } - - } } + + } - break; - - - - - - - case 'D': - if ( gGameSettings.fOptions[TOPTION_DROP_ALL] ) - { - gGameSettings.fOptions[TOPTION_DROP_ALL] = FALSE; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_DROP_ALL_OFF ] ); } - else - { - gGameSettings.fOptions[TOPTION_DROP_ALL] = TRUE; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_DROP_ALL_ON ] ); - } - break; - case 'q': - if ( gGameSettings.fOptions[TOPTION_GL_HIGH_ANGLE] ) - { - gGameSettings.fOptions[TOPTION_GL_HIGH_ANGLE] = FALSE; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_GL_LOW_ANGLE ] ); - } - else - { - gGameSettings.fOptions[TOPTION_GL_HIGH_ANGLE] = TRUE; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_GL_HIGH_ANGLE ] ); - } - break; + } + break; - case 'G': - if ( gGameSettings.fOptions[TOPTION_GL_BURST_CURSOR] ) - { - gGameSettings.fOptions[TOPTION_GL_BURST_CURSOR] = FALSE; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_GL_BURST_CURSOR_OFF ] ); - } - else - { - gGameSettings.fOptions[TOPTION_GL_BURST_CURSOR] = TRUE; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_GL_BURST_CURSOR_ON ] ); - } - break; - case 'g': - if( fCtrl ) - { + + + + case 'D': + if ( gGameSettings.fOptions[TOPTION_DROP_ALL] ) + { + gGameSettings.fOptions[TOPTION_DROP_ALL] = FALSE; + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_DROP_ALL_OFF ] ); + } + else + { + gGameSettings.fOptions[TOPTION_DROP_ALL] = TRUE; + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_DROP_ALL_ON ] ); + } + break; + case 'q': + if ( gGameSettings.fOptions[TOPTION_GL_HIGH_ANGLE] ) + { + gGameSettings.fOptions[TOPTION_GL_HIGH_ANGLE] = FALSE; + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_GL_LOW_ANGLE ] ); + } + else + { + gGameSettings.fOptions[TOPTION_GL_HIGH_ANGLE] = TRUE; + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_GL_HIGH_ANGLE ] ); + } + break; + + + case 'G': + if ( gGameSettings.fOptions[TOPTION_GL_BURST_CURSOR] ) + { + gGameSettings.fOptions[TOPTION_GL_BURST_CURSOR] = FALSE; + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_GL_BURST_CURSOR_OFF ] ); + } + else + { + gGameSettings.fOptions[TOPTION_GL_BURST_CURSOR] = TRUE; + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_GL_BURST_CURSOR_ON ] ); + } + break; + case 'g': + + if( fCtrl ) + { #ifdef GERMAN - if ( gubCheatLevel == 1 ) - { - gubCheatLevel++; - fGoodCheatLevelKey = TRUE; - } - else - { - RESET_CHEAT_LEVEL(); - } -#else - if ( gubCheatLevel == 0 ) - { - gubCheatLevel++; - fGoodCheatLevelKey = TRUE; - } - else - { - RESET_CHEAT_LEVEL(); - } -#endif - } - else if ( fAlt ) + if ( gubCheatLevel == 1 ) { - - if ( CHEATER_CHEAT_LEVEL( ) ) - { - *puiNewEvent = I_NEW_MERC; - } + gubCheatLevel++; + fGoodCheatLevelKey = TRUE; } else { - HandlePlayerTogglingLightEffects( TRUE ); + RESET_CHEAT_LEVEL(); } - break; - case 'H': - case 'h': - if ( fAlt ) +#else + if ( gubCheatLevel == 0 ) + { + gubCheatLevel++; + fGoodCheatLevelKey = TRUE; + } + else + { + RESET_CHEAT_LEVEL(); + } +#endif + } + else if ( fAlt ) + { + + if ( CHEATER_CHEAT_LEVEL( ) ) + { + *puiNewEvent = I_NEW_MERC; + } + } + else + { + HandlePlayerTogglingLightEffects( TRUE ); + } + break; + case 'H': + case 'h': + if ( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + if ( gfReportHitChances ) + { + gfReportHitChances = FALSE; + } + else + { + gfReportHitChances = TRUE; + } + } + } + else if( fCtrl ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + *puiNewEvent = I_TESTHIT; + } + } + else + { + ShouldTheHelpScreenComeUp( HELP_SCREEN_TACTICAL, TRUE ); + } + break; + + case 'i': + + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + CreateRandomItem(); + } + } + else if( fCtrl ) + { +#ifdef GERMAN + if ( gubCheatLevel == 0 ) + { + fGoodCheatLevelKey = TRUE; + gubCheatLevel++; + } +#else + if ( gubCheatLevel == 4 ) + { + gubCheatLevel++; + fGoodCheatLevelKey = TRUE; + // ATE; We're done.... start cheat mode.... + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_CHEAT_LEVEL_TWO ] ); + SetHistoryFact( HISTORY_CHEAT_ENABLED, 0, GetWorldTotalMin(), -1, -1 ); + } + else + { + RESET_CHEAT_LEVEL(); + } +#endif + } + else + { + if ( gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] ) + { + gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] = FALSE; + ToggleItemGlow( FALSE ); + } + else + { + gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] = TRUE; + ToggleItemGlow( TRUE ); + } + } + break; + + + case '$': + + + break; + + case 'k': + if( fAlt ) + { + if ( fCtrl ) { if ( CHEATER_CHEAT_LEVEL( ) ) { - if ( gfReportHitChances ) + // next shot by anybody is auto kill + if (gfNextShotKills) { - gfReportHitChances = FALSE; + gfNextShotKills = FALSE; } else { - gfReportHitChances = TRUE; + gfNextShotKills = TRUE; } } } - else if( fCtrl ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - *puiNewEvent = I_TESTHIT; - } - } else - { - ShouldTheHelpScreenComeUp( HELP_SCREEN_TACTICAL, TRUE ); - } - break; - - case 'i': - - if( fAlt ) { if ( CHEATER_CHEAT_LEVEL( ) ) { - CreateRandomItem(); + GrenadeTest1(); } } - else if( fCtrl ) + } + else if( fCtrl ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) { -#ifdef GERMAN - if ( gubCheatLevel == 0 ) - { - fGoodCheatLevelKey = TRUE; - gubCheatLevel++; - } -#else - if ( gubCheatLevel == 4 ) - { - gubCheatLevel++; - fGoodCheatLevelKey = TRUE; - // ATE; We're done.... start cheat mode.... - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_CHEAT_LEVEL_TWO ] ); - SetHistoryFact( HISTORY_CHEAT_ENABLED, 0, GetWorldTotalMin(), -1, -1 ); - } - else - { - RESET_CHEAT_LEVEL(); - } -#endif + GrenadeTest2(); } - else - { - if ( gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] ) - { - gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] = FALSE; - ToggleItemGlow( FALSE ); - } - else - { - gGameSettings.fOptions[ TOPTION_GLOW_ITEMS ] = TRUE; - ToggleItemGlow( TRUE ); - } - } - break; + } + else + { + BeginKeyPanelFromKeyShortcut( ); + } + break; + case INSERT: - case '$': - - - break; - - case 'k': - if( fAlt ) - { - if ( fCtrl ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - // next shot by anybody is auto kill - if (gfNextShotKills) - { - gfNextShotKills = FALSE; - } - else - { - gfNextShotKills = TRUE; - } - } - } - else - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - GrenadeTest1(); - } - } - } - else if( fCtrl ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - GrenadeTest2(); - } - } - else - { - BeginKeyPanelFromKeyShortcut( ); - } - break; - - case INSERT: - - // WANNE 2: commented this out, because the interface panel is not correctly redrawn! - // I do not know the bug ;( - //GoIntoOverheadMap(); - break; + // WANNE 2: commented this out, because the interface panel is not correctly redrawn! + // I do not know the bug ;( + //GoIntoOverheadMap(); + break; // Lalien: commented out, to fix "end move & LOS bug" (same button has two different actions) //case END: @@ -2833,202 +2844,202 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) // } // break; - case HOME: + case HOME: - if ( gGameSettings.fOptions[ TOPTION_3D_CURSOR ] ) - { - gGameSettings.fOptions[ TOPTION_3D_CURSOR ] = FALSE; + if ( gGameSettings.fOptions[ TOPTION_3D_CURSOR ] ) + { + gGameSettings.fOptions[ TOPTION_3D_CURSOR ] = FALSE; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_3DCURSOR_OFF ] ); - } - else - { - gGameSettings.fOptions[ TOPTION_3D_CURSOR ] = TRUE; + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_3DCURSOR_OFF ] ); + } + else + { + gGameSettings.fOptions[ TOPTION_3D_CURSOR ] = TRUE; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_3DCURSOR_ON ] ); - } - break; + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_3DCURSOR_ON ] ); + } + break; - #ifdef JA2BETAVERSION - case 'L': - gfDisplayStrategicAILogs ^= TRUE; - if( gfDisplayStrategicAILogs ) +#ifdef JA2BETAVERSION + case 'L': + gfDisplayStrategicAILogs ^= TRUE; + if( gfDisplayStrategicAILogs ) + { + ScreenMsg( FONT_LTKHAKI, MSG_INTERFACE, L"Strategic AI Log visually enabled." ); + } + else + { + ScreenMsg( FONT_LTKHAKI, MSG_INTERFACE, L"Strategic AI Log visually disabled." ); + } + break; +#endif + + case 'l': + /* + if( fAlt ) + { + if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) ) + { + LeaveTacticalScreen( GAME_SCREEN ); + + DoQuickLoad(); + } + } + + else if( fCtrl ) + { + if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) ) + { + + gfSaveGame = FALSE; + gfCameDirectlyFromGame = TRUE; + + guiPreviousOptionScreen = GAME_SCREEN; + LeaveTacticalScreen( SAVE_LOAD_SCREEN ); + } + *//* + if ( INFORMATION_CHEAT_LEVEL( ) ) + { + *puiNewEvent = I_LEVELNODEDEBUG; + CountLevelNodes(); + } + *//* + } + else + */ { + // nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel + if ( ( gpItemPointer == NULL ) && + ( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ LOOK_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) { - ScreenMsg( FONT_LTKHAKI, MSG_INTERFACE, L"Strategic AI Log visually enabled." ); + *puiNewEvent = LC_CHANGE_TO_LOOK; } - else - { - ScreenMsg( FONT_LTKHAKI, MSG_INTERFACE, L"Strategic AI Log visually disabled." ); } break; - #endif - - case 'l': -/* - if( fAlt ) - { - if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) ) - { - LeaveTacticalScreen( GAME_SCREEN ); - - DoQuickLoad(); - } - } - - else if( fCtrl ) + case 'm': + if( fAlt ) + { + if ( INFORMATION_CHEAT_LEVEL( ) ) { - if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) ) - { - - gfSaveGame = FALSE; - gfCameDirectlyFromGame = TRUE; - - guiPreviousOptionScreen = GAME_SCREEN; - LeaveTacticalScreen( SAVE_LOAD_SCREEN ); - } -*//* - if ( INFORMATION_CHEAT_LEVEL( ) ) - { - *puiNewEvent = I_LEVELNODEDEBUG; - CountLevelNodes(); - } -*//* + *puiNewEvent = I_LEVELNODEDEBUG; + CountLevelNodes(); } - else -*/ { + } + else if( fCtrl ) + { + if ( INFORMATION_CHEAT_LEVEL( ) ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Memory Used: %d + %d = %d vs: %d", guiMemTotal, giMemUsedInSurfaces, ( guiMemTotal + giMemUsedInSurfaces), ( giStartingMemValue - MemGetFree() ) ); + } + } + else + { + // nothing in hand and the Map Screen button for whichever panel we're in must be enabled + if ( ( gpItemPointer == NULL ) && !gfDisableTacticalPanelButtons && + ( ( ( gsCurInterfacePanel == SM_PANEL ) && ( ButtonList[ iSMPanelButtons[ SM_MAP_SCREEN_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) || + ( ( gsCurInterfacePanel == TEAM_PANEL ) && ( ButtonList[ iTEAMPanelButtons[ TEAM_MAP_SCREEN_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) ) + { + // go to Map screen + if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) ) + { + GoToMapScreenFromTactical(); + } + } + } + break; + + case PGDN: + + if ( CHEATER_CHEAT_LEVEL( ) ) + { + if( fCtrl ) + AttemptToChangeFloorLevel( +1 ); //try to enter a lower underground level + } + + if ( guiCurrentScreen != DEBUG_SCREEN ) + { + if ( gusSelectedSoldier != NOBODY ) + { // nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel - if ( ( gpItemPointer == NULL ) && - ( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ LOOK_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) + if ( ( gpItemPointer == NULL ) ) { - *puiNewEvent = LC_CHANGE_TO_LOOK; + GotoLowerStance( MercPtrs[ gusSelectedSoldier ] ); } } - break; - case 'm': - if( fAlt ) + } + break; + + + case PGUP: + + if ( CHEATER_CHEAT_LEVEL( ) ) + { + if( fCtrl ) + AttemptToChangeFloorLevel( -1 ); //try to go up towards ground level + } + + if ( guiCurrentScreen != DEBUG_SCREEN ) + { + if ( gusSelectedSoldier != NOBODY ) { - if ( INFORMATION_CHEAT_LEVEL( ) ) + // nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel + if ( ( gpItemPointer == NULL ) ) { - *puiNewEvent = I_LEVELNODEDEBUG; - CountLevelNodes(); + GotoHeigherStance( MercPtrs[ gusSelectedSoldier ] ); } } - else if( fCtrl ) - { - if ( INFORMATION_CHEAT_LEVEL( ) ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Memory Used: %d + %d = %d vs: %d", guiMemTotal, giMemUsedInSurfaces, ( guiMemTotal + giMemUsedInSurfaces), ( giStartingMemValue - MemGetFree() ) ); - } - } - else - { - // nothing in hand and the Map Screen button for whichever panel we're in must be enabled - if ( ( gpItemPointer == NULL ) && !gfDisableTacticalPanelButtons && - ( ( ( gsCurInterfacePanel == SM_PANEL ) && ( ButtonList[ iSMPanelButtons[ SM_MAP_SCREEN_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) || - ( ( gsCurInterfacePanel == TEAM_PANEL ) && ( ButtonList[ iTEAMPanelButtons[ TEAM_MAP_SCREEN_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) ) - { - // go to Map screen - if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) ) - { - GoToMapScreenFromTactical(); - } - } - } - break; - - case PGDN: - - if ( CHEATER_CHEAT_LEVEL( ) ) - { - if( fCtrl ) - AttemptToChangeFloorLevel( +1 ); //try to enter a lower underground level - } - - if ( guiCurrentScreen != DEBUG_SCREEN ) - { - if ( gusSelectedSoldier != NOBODY ) - { - // nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel - if ( ( gpItemPointer == NULL ) ) - { - GotoLowerStance( MercPtrs[ gusSelectedSoldier ] ); - } - } - } - break; + } + break; - case PGUP: + case '*': - if ( CHEATER_CHEAT_LEVEL( ) ) - { - if( fCtrl ) - AttemptToChangeFloorLevel( -1 ); //try to go up towards ground level - } - - if ( guiCurrentScreen != DEBUG_SCREEN ) - { - if ( gusSelectedSoldier != NOBODY ) - { - // nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel - if ( ( gpItemPointer == NULL ) ) - { - GotoHeigherStance( MercPtrs[ gusSelectedSoldier ] ); - } - } - } - break; - - - case '*': - - if ( gTacticalStatus.uiFlags & RED_ITEM_GLOW_ON ) - { - gTacticalStatus.uiFlags &= (~RED_ITEM_GLOW_ON ); - } - else - { - gTacticalStatus.uiFlags |= RED_ITEM_GLOW_ON; - } - break; + if ( gTacticalStatus.uiFlags & RED_ITEM_GLOW_ON ) + { + gTacticalStatus.uiFlags &= (~RED_ITEM_GLOW_ON ); + } + else + { + gTacticalStatus.uiFlags |= RED_ITEM_GLOW_ON; + } + break; - // swap sungoggles and nightgoggles - case 'N': - { + // swap sungoggles and nightgoggles + case 'N': + { /* CHRISL - Adjusted this option to allow the game to search through Helmet attachments as well as inventory positions. */ - SOLDIERTYPE *pTeamSoldier; + SOLDIERTYPE *pTeamSoldier; OBJECTTYPE * pObj; INT8 bLoop, bSlot1, bSlot2, bSlot3, temp, tempStatus=0; INT16 lastBonus=0, tempItem=0; - for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++) - { - if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) ) - { - //2 head slots - for (bSlot1 = HEAD1POS; bSlot1 <= HEAD2POS; bSlot1++) + for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++) + { + if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) ) + { + //2 head slots + for (bSlot1 = HEAD1POS; bSlot1 <= HEAD2POS; bSlot1++) + { + if ( Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus > 0 ) { - if ( Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus > 0 ) - { - lastBonus=0; - bSlot2 = ITEM_NOT_FOUND; + lastBonus=0; + bSlot2 = ITEM_NOT_FOUND; bSlot3 = ITEM_NOT_FOUND; - temp = 0; + temp = 0; pObj = &(pTeamSoldier->inv[HELMETPOS]); - while (temp != ITEM_NOT_FOUND) + while (temp != ITEM_NOT_FOUND) + { + temp = FindNightGoggles( pTeamSoldier, lastBonus ); + if ( temp > ITEM_NOT_FOUND ) { - temp = FindNightGoggles( pTeamSoldier, lastBonus ); - if ( temp > ITEM_NOT_FOUND ) - { - lastBonus = Item[pTeamSoldier->inv[temp].usItem].nightvisionrangebonus; - bSlot2 = temp; - } + lastBonus = Item[pTeamSoldier->inv[temp].usItem].nightvisionrangebonus; + bSlot2 = temp; } + } for (int i = 0; i < MAX_ATTACHMENTS; i++) - { + { if ( Item[ pObj->usAttachItem[i] ].nightvisionrangebonus > lastBonus && Item[ pObj->usAttachItem[i] ].usItemClass == IC_FACE ) { bSlot2 = ITEM_NOT_FOUND; @@ -3050,28 +3061,28 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) } else if ( bSlot2 != ITEM_NOT_FOUND ) { - SwapObjs( &(pTeamSoldier->inv[bSlot1]), &(pTeamSoldier->inv[bSlot2] ) ); - } - break; + SwapObjs( &(pTeamSoldier->inv[bSlot1]), &(pTeamSoldier->inv[bSlot2] ) ); } - else if(Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus > 0) - { - lastBonus=0; - bSlot2 = ITEM_NOT_FOUND; + break; + } + else if(Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus > 0) + { + lastBonus=0; + bSlot2 = ITEM_NOT_FOUND; bSlot3 = ITEM_NOT_FOUND; - temp = 0; + temp = 0; pObj = &(pTeamSoldier->inv[HELMETPOS]); - while (temp != ITEM_NOT_FOUND) + while (temp != ITEM_NOT_FOUND) + { + temp = FindSunGoggles( pTeamSoldier, lastBonus ); + if ( temp > ITEM_NOT_FOUND ) { - temp = FindSunGoggles( pTeamSoldier, lastBonus ); - if ( temp > ITEM_NOT_FOUND ) - { - lastBonus = Item[pTeamSoldier->inv[temp].usItem].brightlightvisionrangebonus; - bSlot2 = temp; - } + lastBonus = Item[pTeamSoldier->inv[temp].usItem].brightlightvisionrangebonus; + bSlot2 = temp; } + } for (int i = 0; i < MAX_ATTACHMENTS; i++) - { + { if ( Item[ pObj->usAttachItem[i] ].brightlightvisionrangebonus > lastBonus && Item[ pObj->usAttachItem[i] ].usItemClass == IC_FACE ) { bSlot2 = ITEM_NOT_FOUND; @@ -3093,166 +3104,229 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) } else if ( bSlot2 != ITEM_NOT_FOUND ) { - SwapObjs( &(pTeamSoldier->inv[bSlot1]), &(pTeamSoldier->inv[bSlot2] ) ); - } - break; + SwapObjs( &(pTeamSoldier->inv[bSlot1]), &(pTeamSoldier->inv[bSlot2] ) ); } + break; } - fCharacterInfoPanelDirty = TRUE; - fInterfacePanelDirty = DIRTYLEVEL2; - DeleteSoldierLight( pTeamSoldier ); - PositionSoldierLight( pTeamSoldier ); } + fCharacterInfoPanelDirty = TRUE; + fInterfacePanelDirty = DIRTYLEVEL2; + DeleteSoldierLight( pTeamSoldier ); + PositionSoldierLight( pTeamSoldier ); } + } /* CHRISL - Adjusted this option to allow the game to search through Helmet attachments as well as inventory positions. */ - } - break; + } + break; - case 'n': + case 'n': - if( fAlt ) + if( fAlt ) + { + static UINT16 gQuoteNum = 0; + + if ( INFORMATION_CHEAT_LEVEL( ) ) { - static UINT16 gQuoteNum = 0; - - if ( INFORMATION_CHEAT_LEVEL( ) ) + if( gfUIFullTargetFound ) { - if( gfUIFullTargetFound ) - { - TacticalCharacterDialogue( MercPtrs[ gusUIFullTargetID ], gQuoteNum ); - gQuoteNum++; - } + TacticalCharacterDialogue( MercPtrs[ gusUIFullTargetID ], gQuoteNum ); + gQuoteNum++; } } - else if( fCtrl ) - { + } + else if( fCtrl ) + { #ifdef GERMAN - if ( gubCheatLevel == 4 ) - { - fGoodCheatLevelKey = TRUE; - gubCheatLevel++; + if ( gubCheatLevel == 4 ) + { + fGoodCheatLevelKey = TRUE; + gubCheatLevel++; #if 0 - // ATE: Level one reached..... - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_CHEAT_LEVEL_ONE ] ); + // ATE: Level one reached..... + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_CHEAT_LEVEL_ONE ] ); #endif + } + else + { + RESET_CHEAT_LEVEL(); + } +#endif + +#if 0 + if ( INFORMATION_CHEAT_LEVEL( ) ) + { + if( gfUIShowCurIntTile ^= TRUE ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Turning Enhanced mouse detection ON." ); + gubIntTileCheckFlags = INTILE_CHECK_FULL; } else { - RESET_CHEAT_LEVEL(); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Turning Enhanced mouse detection OFF." ); + gubIntTileCheckFlags = INTILE_CHECK_SELECTIVE; } -#endif - -#if 0 - if ( INFORMATION_CHEAT_LEVEL( ) ) - { - if( gfUIShowCurIntTile ^= TRUE ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Turning Enhanced mouse detection ON." ); - gubIntTileCheckFlags = INTILE_CHECK_FULL; - } - else - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Turning Enhanced mouse detection OFF." ); - gubIntTileCheckFlags = INTILE_CHECK_SELECTIVE; - } - } -#endif } - else +#endif + } + else if( !CycleSoldierFindStack( usMapPos ) )// Are we over a merc stack? CycleIntTileFindStack( usMapPos ); // If not, now check if we are over a struct stack - break; + break; - case 'o': + case 'o': - if( fAlt ) + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) { - if ( CHEATER_CHEAT_LEVEL( ) ) + gStrategicStatus.usPlayerKills += NumEnemiesInAnySector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + ObliterateSector(); + } + } + else if(fCtrl) + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + CreatePlayerControlledMonster(); + } + } + else + { + // nothing in hand and the Options Screen button for whichever panel we're in must be enabled + if ( ( gpItemPointer == NULL ) && !gfDisableTacticalPanelButtons && + ( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ OPTIONS_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) + { + if( !fDisableMapInterfaceDueToBattle ) { - gStrategicStatus.usPlayerKills += NumEnemiesInAnySector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); - ObliterateSector(); + // go to Options screen + guiPreviousOptionScreen = GAME_SCREEN; + LeaveTacticalScreen( OPTIONS_SCREEN ); } } - else if(fCtrl) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - CreatePlayerControlledMonster(); - } - } - else - { - // nothing in hand and the Options Screen button for whichever panel we're in must be enabled - if ( ( gpItemPointer == NULL ) && !gfDisableTacticalPanelButtons && - ( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ OPTIONS_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) - { - if( !fDisableMapInterfaceDueToBattle ) - { - // go to Options screen - guiPreviousOptionScreen = GAME_SCREEN; - LeaveTacticalScreen( OPTIONS_SCREEN ); - } - } - } - break; + } + break; - case 'p': + case 'p': #ifdef JA2BETAVERSION - if( fAlt ) - ToggleRealTimeConfirm(); - else + if( fAlt ) + ToggleRealTimeConfirm(); + else #endif #ifdef JA2TESTVERSION - if( fCtrl ) - { - // CTRL-P: Display player's highest progress percentage - DumpSectorDifficultyInfo(); - } - else -#endif - HandleStanceChangeFromUIKeys( ANIM_PRONE ); - break; - - - - // Make auto reload with magazines from sector inventory - case 'R': - if (! ( gTacticalStatus.fEnemyInSector ) ) + if( fCtrl ) { - SOLDIERTYPE *pTeamSoldier; - INT8 bLoop; - OBJECTTYPE *pGun, *pAmmo; + // CTRL-P: Display player's highest progress percentage + DumpSectorDifficultyInfo(); + } + else +#endif + HandleStanceChangeFromUIKeys( ANIM_PRONE ); + break; - // Search for soldier - for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++) - { - if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) ) - { - // Search for gun in soldier inventory - for (UINT32 bLoop2 = 0; bLoop2 < NUM_INV_SLOTS; bLoop2++) - { - if ( (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass & IC_GUN) || (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass == IC_LAUNCHER) ) - { - pGun = &(pTeamSoldier->inv[bLoop2]); - //if magazine is not full - if ( pGun->ubGunShotsLeft < GetMagSize( pGun ) ) + + // Make auto reload with magazines from sector inventory + case 'R': + if (! ( gTacticalStatus.fEnemyInSector ) ) + { + SOLDIERTYPE *pTeamSoldier; + INT8 bLoop; + OBJECTTYPE *pGun, *pAmmo; + + // Search for soldier + for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++) + { + if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) ) + { + + // Search for gun in soldier inventory + for (UINT32 bLoop2 = 0; bLoop2 < NUM_INV_SLOTS; bLoop2++) + { + if ( (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass & IC_GUN) || (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass == IC_LAUNCHER) ) + { + pGun = &(pTeamSoldier->inv[bLoop2]); + //if magazine is not full + if ( pGun->ubGunShotsLeft < GetMagSize( pGun ) ) + { + + // Search for ammo in sector + for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; uiLoop++ ) { - - // Search for ammo in sector - for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; uiLoop++ ) + if ( gWorldItems[ uiLoop ].fExists) //item exists && (gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_REACHABLE) { - if ( gWorldItems[ uiLoop ].fExists) //item exists && (gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_REACHABLE) + if ( ( Item[ gWorldItems[ uiLoop ].o.usItem ].usItemClass & IC_AMMO ) ) // the item is ammo { - if ( ( Item[ gWorldItems[ uiLoop ].o.usItem ].usItemClass & IC_AMMO ) ) // the item is ammo + pAmmo = &( gWorldItems[ uiLoop ].o ); + + if ( CompatibleAmmoForGun( pAmmo, pGun ) ) // can use the ammo with this gun { - pAmmo = &( gWorldItems[ uiLoop ].o ); + // same ammo type in gun and magazine + if ( Magazine[Item[pGun->usGunAmmoItem].ubClassIndex].ubAmmoType == Magazine[Item[pAmmo->usItem].ubClassIndex].ubAmmoType ) + { + ReloadGun( pTeamSoldier, pGun, pAmmo ); + } + + if (pAmmo->ubShotsLeft[0] == 0) + { + RemoveItemFromPool( gWorldItems[ uiLoop ].sGridNo, uiLoop, gWorldItems[ uiLoop ].ubLevel ); + } + } + } + } + } + } + } + } + } + } + } + else + { + SOLDIERTYPE *pTeamSoldier; + INT8 bLoop; + OBJECTTYPE *pGun, *pAmmo; + + for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++) + { + if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) ) + { + if ( (Item[pTeamSoldier->inv[HANDPOS].usItem].usItemClass & IC_GUN) || (Item[pTeamSoldier->inv[HANDPOS].usItem].usItemClass == IC_LAUNCHER) ) + { + if ( ( gTacticalStatus.uiFlags & INCOMBAT ) ) + { + pGun = &(pTeamSoldier->inv[HANDPOS]); + + //magazine is not full + if ( pGun->ubGunShotsLeft < GetMagSize( pGun ) ) + { + AutoReload( pTeamSoldier ); + } + } + else + { + // Search for gun in soldier inventory + for (UINT32 bLoop2 = 0; bLoop2 < NUM_INV_SLOTS; bLoop2++) + { + if ( (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass & IC_GUN) || (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass == IC_LAUNCHER) ) + { + pGun = &(pTeamSoldier->inv[bLoop2]); + //if magazine is not full + if ( pGun->ubGunShotsLeft < GetMagSize( pGun ) ) + { + + // Search for ammo in soldier inventory + for ( UINT32 uiLoop = 0; uiLoop < NUM_INV_SLOTS; uiLoop++ ) + { + if ( (Item[pTeamSoldier->inv[uiLoop].usItem].usItemClass & IC_AMMO ) ) // the item is ammo + { + pAmmo = &(pTeamSoldier->inv[uiLoop]); if ( CompatibleAmmoForGun( pAmmo, pGun ) ) // can use the ammo with this gun { @@ -3260,11 +3334,9 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) if ( Magazine[Item[pGun->usGunAmmoItem].ubClassIndex].ubAmmoType == Magazine[Item[pAmmo->usItem].ubClassIndex].ubAmmoType ) { ReloadGun( pTeamSoldier, pGun, pAmmo ); - } - if (pAmmo->ubShotsLeft[0] == 0) - { - RemoveItemFromPool( gWorldItems[ uiLoop ].sGridNo, uiLoop, gWorldItems[ uiLoop ].ubLevel ); + fCharacterInfoPanelDirty = TRUE; + fInterfacePanelDirty = DIRTYLEVEL2; } } } @@ -3272,185 +3344,124 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) } } } + + } + } } } + } + break; + + + case 'r': + if( gusSelectedSoldier != NO_SOLDIER ) + { + if( fAlt ) //reload selected merc's weapon + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + ReloadWeapon( MercPtrs[ gusSelectedSoldier ], MercPtrs[ gusSelectedSoldier ]->ubAttackingHand ); + } + } + else if( fCtrl ) + { + if ( INFORMATION_CHEAT_LEVEL( ) ) + { + DoChrisTest( MercPtrs[ gusSelectedSoldier ] ); + } + } else - { - SOLDIERTYPE *pTeamSoldier; - INT8 bLoop; - OBJECTTYPE *pGun, *pAmmo; - - for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++) + { + if ( !MercInWater( MercPtrs[ gusSelectedSoldier ] ) && !(MercPtrs[ gusSelectedSoldier ]->uiStatusFlags & SOLDIER_ROBOT ) ) { - if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) ) - { - if ( (Item[pTeamSoldier->inv[HANDPOS].usItem].usItemClass & IC_GUN) || (Item[pTeamSoldier->inv[HANDPOS].usItem].usItemClass == IC_LAUNCHER) ) - { - if ( ( gTacticalStatus.uiFlags & INCOMBAT ) ) - { - pGun = &(pTeamSoldier->inv[HANDPOS]); - - //magazine is not full - if ( pGun->ubGunShotsLeft < GetMagSize( pGun ) ) - { - AutoReload( pTeamSoldier ); - } - } - else - { - // Search for gun in soldier inventory - for (UINT32 bLoop2 = 0; bLoop2 < NUM_INV_SLOTS; bLoop2++) - { - if ( (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass & IC_GUN) || (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass == IC_LAUNCHER) ) - { - pGun = &(pTeamSoldier->inv[bLoop2]); - //if magazine is not full - if ( pGun->ubGunShotsLeft < GetMagSize( pGun ) ) - { - - // Search for ammo in soldier inventory - for ( UINT32 uiLoop = 0; uiLoop < NUM_INV_SLOTS; uiLoop++ ) - { - if ( (Item[pTeamSoldier->inv[uiLoop].usItem].usItemClass & IC_AMMO ) ) // the item is ammo - { - pAmmo = &(pTeamSoldier->inv[uiLoop]); - - if ( CompatibleAmmoForGun( pAmmo, pGun ) ) // can use the ammo with this gun - { - // same ammo type in gun and magazine - if ( Magazine[Item[pGun->usGunAmmoItem].ubClassIndex].ubAmmoType == Magazine[Item[pAmmo->usItem].ubClassIndex].ubAmmoType ) - { - ReloadGun( pTeamSoldier, pGun, pAmmo ); - - fCharacterInfoPanelDirty = TRUE; - fInterfacePanelDirty = DIRTYLEVEL2; - } - } - } - } - } - } - } - - - } - - } - } - } - } - break; - - - case 'r': - if( gusSelectedSoldier != NO_SOLDIER ) - { - if( fAlt ) //reload selected merc's weapon - { - if ( CHEATER_CHEAT_LEVEL( ) ) + //change selected merc to run + if ( MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != WALKING && MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != RUNNING ) { - ReloadWeapon( MercPtrs[ gusSelectedSoldier ], MercPtrs[ gusSelectedSoldier ]->ubAttackingHand ); - } - } - else if( fCtrl ) - { - if ( INFORMATION_CHEAT_LEVEL( ) ) - { - DoChrisTest( MercPtrs[ gusSelectedSoldier ] ); - } - } - else - { - if ( !MercInWater( MercPtrs[ gusSelectedSoldier ] ) && !(MercPtrs[ gusSelectedSoldier ]->uiStatusFlags & SOLDIER_ROBOT ) ) - { - //change selected merc to run - if ( MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != WALKING && MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != RUNNING ) - { - UIHandleSoldierStanceChange( (UINT8)gusSelectedSoldier, ANIM_STAND ); - MercPtrs[ gusSelectedSoldier ]->fUIMovementFast = 1; - } - else - { - MercPtrs[ gusSelectedSoldier ]->fUIMovementFast = 1; - MercPtrs[ gusSelectedSoldier ]->usUIMovementMode = RUNNING; - gfPlotNewMovement = TRUE; - } - } - } - } - break; - - - - - - case 'S': - if (! ( gTacticalStatus.fEnemyInSector ) ) - { - HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); - - for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; uiLoop++ ) - { - if ( ( gWorldItems[ uiLoop ].fExists) && (gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_REACHABLE) )//item exists and is reachable - { - //find out how many items can be put in a big slot - INT8 ubSlotLimit = ItemSlotLimit( gWorldItems[ uiLoop ].o.usItem, BIGPOCK1POS ); - - //if we still have some space - INT32 i = 0; - while ( gWorldItems[ uiLoop ].o.ubNumberOfObjects < ubSlotLimit ) - { - i++; - //if the next item is the same - if ( gWorldItems[ uiLoop ].o.usItem == gWorldItems[ uiLoop + i ].o.usItem ) - { - INT8 ubObjCount = ubSlotLimit - gWorldItems[ uiLoop ].o.ubNumberOfObjects; - INT8 bPointsToMove = __min( ubObjCount, gWorldItems[ uiLoop + i ].o.ubNumberOfObjects ); - - StackObjs( &(gWorldItems[ uiLoop + i ].o), &(gWorldItems[ uiLoop ].o), bPointsToMove); - - } - else - { - break; - } - } - } - } - - //HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); - } - break; - - - case 's': - - if( fCtrl ) - { - if ( fAlt ) - RemoveCharacterFromSquads(MercPtrs[gusSelectedSoldier]); - - else if( !fDisableMapInterfaceDueToBattle && !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) ) - { - //if the game CAN be saved - if( CanGameBeSaved() ) - { - gfSaveGame = TRUE; - gfCameDirectlyFromGame = TRUE; - - guiPreviousOptionScreen = GAME_SCREEN; - LeaveTacticalScreen( SAVE_LOAD_SCREEN ); + UIHandleSoldierStanceChange( (UINT8)gusSelectedSoldier, ANIM_STAND ); + MercPtrs[ gusSelectedSoldier ]->fUIMovementFast = 1; } else { - //Display a message saying the player cant save now - DoMessageBox( MSG_BOX_BASIC_STYLE, zNewTacticalMessages[ TCTL_MSG__IRON_MAN_CANT_SAVE_NOW ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_OK, NULL, NULL); + MercPtrs[ gusSelectedSoldier ]->fUIMovementFast = 1; + MercPtrs[ gusSelectedSoldier ]->usUIMovementMode = RUNNING; + gfPlotNewMovement = TRUE; } } } - else + } + break; + + + + + + case 'S': + if (! ( gTacticalStatus.fEnemyInSector ) ) + { + HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + + for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; uiLoop++ ) + { + if ( ( gWorldItems[ uiLoop ].fExists) && (gWorldItems[ uiLoop ].usFlags & WORLD_ITEM_REACHABLE) )//item exists and is reachable + { + //find out how many items can be put in a big slot + INT8 ubSlotLimit = ItemSlotLimit( gWorldItems[ uiLoop ].o.usItem, BIGPOCK1POS ); + + //if we still have some space + INT32 i = 0; + while ( gWorldItems[ uiLoop ].o.ubNumberOfObjects < ubSlotLimit ) + { + i++; + //if the next item is the same + if ( gWorldItems[ uiLoop ].o.usItem == gWorldItems[ uiLoop + i ].o.usItem ) + { + INT8 ubObjCount = ubSlotLimit - gWorldItems[ uiLoop ].o.ubNumberOfObjects; + INT8 bPointsToMove = __min( ubObjCount, gWorldItems[ uiLoop + i ].o.ubNumberOfObjects ); + + StackObjs( &(gWorldItems[ uiLoop + i ].o), &(gWorldItems[ uiLoop ].o), bPointsToMove); + + } + else + { + break; + } + } + } + } + + //HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + } + break; + + + case 's': + + if( fCtrl ) + { + if ( fAlt ) + RemoveCharacterFromSquads(MercPtrs[gusSelectedSoldier]); + + else if( !fDisableMapInterfaceDueToBattle && !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) ) + { + //if the game CAN be saved + if( CanGameBeSaved() ) + { + gfSaveGame = TRUE; + gfCameDirectlyFromGame = TRUE; + + guiPreviousOptionScreen = GAME_SCREEN; + LeaveTacticalScreen( SAVE_LOAD_SCREEN ); + } + else + { + //Display a message saying the player cant save now + DoMessageBox( MSG_BOX_BASIC_STYLE, zNewTacticalMessages[ TCTL_MSG__IRON_MAN_CANT_SAVE_NOW ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_OK, NULL, NULL); + } + } + } + else if( fAlt ) { if( !fDisableMapInterfaceDueToBattle && !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) ) @@ -3476,345 +3487,345 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) } break; - case 't': + case 't': + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + TeleportSelectedSoldier(); + } + } + else if( fCtrl ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + TestCapture( ); + + //EnterCombatMode( gbPlayerNum ); + } + } + else + ToggleTreeTops(); + break; + + + case '=': + //if the display cover or line of sight is being displayed + if( _KeyDown( END ) || _KeyDown( DEL ) ) + { + if( _KeyDown( DEL ) ) + ChangeSizeOfDisplayCover( gGameSettings.ubSizeOfDisplayCover + 1 ); + + if( _KeyDown( END ) ) + ChangeSizeOfLOS( gGameSettings.ubSizeOfLOS + 1 ); + } + else + { + +#ifdef JA2TESTVERSION if( fAlt ) { - if ( CHEATER_CHEAT_LEVEL( ) ) + WarpGameTime( 60, TRUE ); + break; + } +#endif + + // ATE: This key will select everybody in the sector + if (! (gTacticalStatus.uiFlags & INCOMBAT) ) + { + SOLDIERTYPE * pSoldier; + INT32 cnt; + + cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; + for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++, pSoldier++ ) { - TeleportSelectedSoldier(); - } - } - else if( fCtrl ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - TestCapture( ); - //EnterCombatMode( gbPlayerNum ); - } - } - else - ToggleTreeTops(); - break; - - - case '=': - //if the display cover or line of sight is being displayed - if( _KeyDown( END ) || _KeyDown( DEL ) ) - { - if( _KeyDown( DEL ) ) - ChangeSizeOfDisplayCover( gGameSettings.ubSizeOfDisplayCover + 1 ); - - if( _KeyDown( END ) ) - ChangeSizeOfLOS( gGameSettings.ubSizeOfLOS + 1 ); - } - else - { - - #ifdef JA2TESTVERSION - if( fAlt ) + // Check if this guy is OK to control.... + if ( OK_CONTROLLABLE_MERC( pSoldier ) && !( pSoldier->uiStatusFlags & ( SOLDIER_VEHICLE | SOLDIER_PASSENGER | SOLDIER_DRIVER ) ) ) { - WarpGameTime( 60, TRUE ); - break; + pSoldier->uiStatusFlags |= SOLDIER_MULTI_SELECTED; } - #endif - - // ATE: This key will select everybody in the sector - if (! (gTacticalStatus.uiFlags & INCOMBAT) ) - { - SOLDIERTYPE * pSoldier; - INT32 cnt; - - cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; - for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++, pSoldier++ ) - { - - // Check if this guy is OK to control.... - if ( OK_CONTROLLABLE_MERC( pSoldier ) && !( pSoldier->uiStatusFlags & ( SOLDIER_VEHICLE | SOLDIER_PASSENGER | SOLDIER_DRIVER ) ) ) - { - pSoldier->uiStatusFlags |= SOLDIER_MULTI_SELECTED; - } - } - EndMultiSoldierSelection( TRUE ); - } - } - break; - - case 'u': - - if( fAlt ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - RefreshSoldier(); } + EndMultiSoldierSelection( TRUE ); } - else if( fCtrl ) + } + break; + + case 'u': + + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) { - INT32 cnt; - SOLDIERTYPE *pSoldier; + RefreshSoldier(); + } + } + else if( fCtrl ) + { + INT32 cnt; + SOLDIERTYPE *pSoldier; #ifdef GERMAN - if ( gubCheatLevel == 2 ) + if ( gubCheatLevel == 2 ) + { + fGoodCheatLevelKey = TRUE; + gubCheatLevel++; + } + else + { + RESET_CHEAT_LEVEL(); + } +#endif + + if ( CHEATER_CHEAT_LEVEL( ) && gusSelectedSoldier != NOBODY ) + { + for ( pSoldier = MercPtrs[ gbPlayerNum ], cnt = 0; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++) + { + if ( pSoldier->bActive && pSoldier->bLife > 0 ) + { + // Get breath back + pSoldier->bBreath = pSoldier->bBreathMax; + + // Get life back + pSoldier->bLife = pSoldier->bLifeMax; + pSoldier->bBleeding = 0; + + fInterfacePanelDirty = DIRTYLEVEL2; + } + } + } + } + + else if ( gusSelectedSoldier != NO_SOLDIER ) + *puiNewEvent = M_CHANGE_TO_ACTION; + break; + + case 'v': + if( fAlt ) + { +#ifdef JA2TESTVERSION + if( gfDoVideoScroll ^= TRUE ) + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Video Scroll ON" ); + else + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Video Scroll OFF" ); +#endif + } + else if( fCtrl ) + { +#ifdef SGP_VIDEO_DEBUGGING + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"VObjects: %d", guiVObjectSize ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"VSurfaces: %d", guiVSurfaceSize ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"SGPVideoDump.txt updated..." ); + PerformVideoInfoDumpIntoFile( "SGPVideoDump.txt", TRUE ); +#endif + } + else + DisplayGameSettings( ); + + break; + case 'w': + case 'W': + + if( fAlt ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + if ( InItemDescriptionBox( ) ) { - fGoodCheatLevelKey = TRUE; - gubCheatLevel++; + // Swap item in description panel... + CycleItemDescriptionItem( ); + } else { - RESET_CHEAT_LEVEL(); + CycleSelectedMercsItem(); } -#endif - - if ( CHEATER_CHEAT_LEVEL( ) && gusSelectedSoldier != NOBODY ) + } + } + else if( fCtrl ) + { + if ( CHEATER_CHEAT_LEVEL( ) ) + { + if ( gusSelectedSoldier != NOBODY ) { - for ( pSoldier = MercPtrs[ gbPlayerNum ], cnt = 0; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++) + CreateItem( FLAMETHROWER, 100, &( MercPtrs[ gusSelectedSoldier ]->inv[ HANDPOS ]) ); + } + } + } + else + ToggleWireFrame(); + break; + + case 'y': + if( fAlt ) + { + OBJECTTYPE Object; + SOLDIERTYPE *pSoldier; + + if ( CHEATER_CHEAT_LEVEL( ) ) + { + QuickCreateProfileMerc( CIV_TEAM, MARIA ); //Ira + + // Recruit! + RecruitEPC( MARIA ); + } + + // Create object and set + CreateItem( (UINT16) G41, 100, &Object ); + + pSoldier = FindSoldierByProfileID( ROBOT, FALSE ); + + AutoPlaceObject( pSoldier, &Object, FALSE ); + + } + else + { + if ( INFORMATION_CHEAT_LEVEL( ) ) + { + *puiNewEvent = I_LOSDEBUG; + } + } + //else if( gusSelectedSoldier != NO_SOLDIER ) + break; + case 'z': + if( fCtrl ) + { + if ( INFORMATION_CHEAT_LEVEL( ) ) + { + ToggleZBuffer(); + } + } + else if ( fAlt ) + { + // Toggle squad's stealth mode..... + // For each guy on squad... + { + SOLDIERTYPE *pTeamSoldier; + INT8 bLoop; + BOOLEAN fStealthOn = FALSE; + + // Check if at least one guy is on stealth.... + for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++) + { + if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) ) { - if ( pSoldier->bActive && pSoldier->bLife > 0 ) + if ( pTeamSoldier->bStealthMode ) { - // Get breath back - pSoldier->bBreath = pSoldier->bBreathMax; - - // Get life back - pSoldier->bLife = pSoldier->bLifeMax; - pSoldier->bBleeding = 0; - - fInterfacePanelDirty = DIRTYLEVEL2; + fStealthOn = TRUE; } } } + + fStealthOn = !fStealthOn; + + for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++) + { + if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) ) + { + if ( gpSMCurrentMerc != NULL && bLoop == gpSMCurrentMerc->ubID ) + { + gfUIStanceDifferent = TRUE; + } + + pTeamSoldier->bStealthMode = fStealthOn; + } + } + + fInterfacePanelDirty = DIRTYLEVEL2; + + // OK, display message + if ( fStealthOn ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ON_STEALTHMODE ] ); + } + else + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_OFF_STEALTHMODE ] ); + } } + } + else + { + // nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel + if ( ( gpItemPointer == NULL ) ) + { + HandleStealthChangeFromUIKeys( ); + } + } + break; - else if ( gusSelectedSoldier != NO_SOLDIER ) - *puiNewEvent = M_CHANGE_TO_ACTION; - break; + case '-': + case '_': + //if the display cover or line of sight is being displayed + if( _KeyDown( END ) || _KeyDown( DEL ) ) + { + if( _KeyDown( DEL ) ) + ChangeSizeOfDisplayCover( gGameSettings.ubSizeOfDisplayCover - 1 ); - case 'v': + if( _KeyDown( END ) ) + ChangeSizeOfLOS( gGameSettings.ubSizeOfLOS - 1 ); + } + else + { if( fAlt ) { + if(MusicGetVolume() >= 20) + MusicSetVolume(MusicGetVolume()-20); + else + MusicSetVolume(0); + } + else if( fCtrl ) + { #ifdef JA2TESTVERSION - if( gfDoVideoScroll ^= TRUE ) - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Video Scroll ON" ); - else - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Video Scroll OFF" ); + gTacticalStatus.bRealtimeSpeed = max( 1, gTacticalStatus.bRealtimeSpeed - 1 ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Decreasing Realtime speed to %d", gTacticalStatus.bRealtimeSpeed ); #endif - } - else if( fCtrl ) - { - #ifdef SGP_VIDEO_DEBUGGING - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"VObjects: %d", guiVObjectSize ); - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"VSurfaces: %d", guiVSurfaceSize ); - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"SGPVideoDump.txt updated..." ); - PerformVideoInfoDumpIntoFile( "SGPVideoDump.txt", TRUE ); - #endif - } - else - DisplayGameSettings( ); - - break; - case 'w': - case 'W': - - if( fAlt ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - if ( InItemDescriptionBox( ) ) - { - // Swap item in description panel... - CycleItemDescriptionItem( ); - - } - else - { - CycleSelectedMercsItem(); - } - } - } - else if( fCtrl ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - if ( gusSelectedSoldier != NOBODY ) - { - CreateItem( FLAMETHROWER, 100, &( MercPtrs[ gusSelectedSoldier ]->inv[ HANDPOS ]) ); - } - } - } - else - ToggleWireFrame(); - break; - - case 'y': - if( fAlt ) - { - OBJECTTYPE Object; - SOLDIERTYPE *pSoldier; - - if ( CHEATER_CHEAT_LEVEL( ) ) - { - QuickCreateProfileMerc( CIV_TEAM, MARIA ); //Ira - - // Recruit! - RecruitEPC( MARIA ); - } - - // Create object and set - CreateItem( (UINT16) G41, 100, &Object ); - - pSoldier = FindSoldierByProfileID( ROBOT, FALSE ); - - AutoPlaceObject( pSoldier, &Object, FALSE ); - } else { - if ( INFORMATION_CHEAT_LEVEL( ) ) - { - *puiNewEvent = I_LOSDEBUG; - } +#ifdef JA2TESTVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Using Normal Scroll Speed" ); + gubCurScrollSpeedID = 1; +#endif } - //else if( gusSelectedSoldier != NO_SOLDIER ) - break; - case 'z': - if( fCtrl ) - { - if ( INFORMATION_CHEAT_LEVEL( ) ) - { - ToggleZBuffer(); - } - } - else if ( fAlt ) - { - // Toggle squad's stealth mode..... - // For each guy on squad... - { - SOLDIERTYPE *pTeamSoldier; - INT8 bLoop; - BOOLEAN fStealthOn = FALSE; - - // Check if at least one guy is on stealth.... - for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++) - { - if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) ) - { - if ( pTeamSoldier->bStealthMode ) - { - fStealthOn = TRUE; - } - } - } - - fStealthOn = !fStealthOn; - - for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++) - { - if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) ) - { - if ( gpSMCurrentMerc != NULL && bLoop == gpSMCurrentMerc->ubID ) - { - gfUIStanceDifferent = TRUE; - } - - pTeamSoldier->bStealthMode = fStealthOn; - } - } - - fInterfacePanelDirty = DIRTYLEVEL2; - - // OK, display message - if ( fStealthOn ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ON_STEALTHMODE ] ); - } - else - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_OFF_STEALTHMODE ] ); - } - } - } - else - { - // nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel - if ( ( gpItemPointer == NULL ) ) - { - HandleStealthChangeFromUIKeys( ); - } - } - break; - - case '-': - case '_': - //if the display cover or line of sight is being displayed - if( _KeyDown( END ) || _KeyDown( DEL ) ) - { - if( _KeyDown( DEL ) ) - ChangeSizeOfDisplayCover( gGameSettings.ubSizeOfDisplayCover - 1 ); - - if( _KeyDown( END ) ) - ChangeSizeOfLOS( gGameSettings.ubSizeOfLOS - 1 ); - } - else - { - if( fAlt ) - { - if(MusicGetVolume() >= 20) - MusicSetVolume(MusicGetVolume()-20); - else - MusicSetVolume(0); - } - else if( fCtrl ) - { - #ifdef JA2TESTVERSION - gTacticalStatus.bRealtimeSpeed = max( 1, gTacticalStatus.bRealtimeSpeed - 1 ); - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Decreasing Realtime speed to %d", gTacticalStatus.bRealtimeSpeed ); - #endif - } - else - { - #ifdef JA2TESTVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Using Normal Scroll Speed" ); - gubCurScrollSpeedID = 1; - #endif - } - } - break; - case '+': + } + break; + case '+': #ifdef JA2TESTVERSION - if( fAlt ) - { - if(MusicGetVolume() <= 107) - MusicSetVolume(MusicGetVolume()+20); - else - MusicSetVolume(127); - } - else if( fCtrl ) - { - gTacticalStatus.bRealtimeSpeed = min( MAX_REALTIME_SPEED_VAL, gTacticalStatus.bRealtimeSpeed+1 ); - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Increasing Realtime speed to %d", gTacticalStatus.bRealtimeSpeed ); - } - else - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Using Higher Scroll Speed" ); - gubCurScrollSpeedID = 2; - } + if( fAlt ) + { + if(MusicGetVolume() <= 107) + MusicSetVolume(MusicGetVolume()+20); + else + MusicSetVolume(127); + } + else if( fCtrl ) + { + gTacticalStatus.bRealtimeSpeed = min( MAX_REALTIME_SPEED_VAL, gTacticalStatus.bRealtimeSpeed+1 ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Increasing Realtime speed to %d", gTacticalStatus.bRealtimeSpeed ); + } + else + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Using Higher Scroll Speed" ); + gubCurScrollSpeedID = 2; + } #endif - break; - case '`': - - // Switch panels... + break; + case '`': + + // Switch panels... + { + ToggleTacticalPanels(); + + if ( CHEATER_CHEAT_LEVEL( ) ) { - ToggleTacticalPanels(); - - if ( CHEATER_CHEAT_LEVEL( ) ) - { - //EnvBeginRainStorm( 1 ); - } - + //EnvBeginRainStorm( 1 ); } - break; + + } + break; } @@ -3859,8 +3870,8 @@ void HandleTalkingMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent ) void HandleSectorExitMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent ) { // CHECK ESC KEYS HERE.... - if ( ( pInputEvent->usEvent == KEY_UP )&& ( pInputEvent->usParam == ESC )) - { + if ( ( pInputEvent->usEvent == KEY_UP )&& ( pInputEvent->usParam == ESC )) + { //Handle esc in talking menu RemoveSectorExitMenu( FALSE ); @@ -3872,8 +3883,8 @@ void HandleSectorExitMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent ) void HandleOpenDoorMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent ) { // CHECK ESC KEYS HERE.... - if ( ( pInputEvent->usEvent == KEY_UP )&& ( pInputEvent->usParam == ESC )) - { + if ( ( pInputEvent->usEvent == KEY_UP )&& ( pInputEvent->usParam == ESC )) + { //Handle esc in talking menu CancelOpenDoorMenu( ); HandleOpenDoorMenu( ); @@ -3885,11 +3896,11 @@ void HandleOpenDoorMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent ) void HandleMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent ) { // CHECK ESC KEYS HERE.... - if ( ( pInputEvent->usEvent == KEY_UP )&& ( pInputEvent->usParam == ESC )) - { + if ( ( pInputEvent->usEvent == KEY_UP )&& ( pInputEvent->usParam == ESC )) + { //Handle esc in talking menu CancelMovementMenu( ); - + *puiNewEvent = A_CHANGE_TO_MOVE; } } @@ -3897,8 +3908,8 @@ void HandleMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent ) void HandleItemMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent ) { // CHECK ESC KEYS HERE.... - if ( ( pInputEvent->usEvent == KEY_UP )&& ( pInputEvent->usParam == ESC )) - { + if ( ( pInputEvent->usEvent == KEY_UP )&& ( pInputEvent->usParam == ESC )) + { //Handle esc in talking menu RemoveItemPickupMenu( ); *puiNewEvent = A_CHANGE_TO_MOVE; @@ -3907,7 +3918,7 @@ void HandleItemMenuKeys( InputAtom *pInputEvent, UINT32 *puiNewEvent ) BOOLEAN HandleCheckForExitArrowsInput( BOOLEAN fAdjustConfirm ) { - INT16 sMapPos; + UINT16 usMapPos; // If not in move mode, return! if ( gCurrentUIMode != MOVE_MODE ) @@ -3927,8 +3938,8 @@ BOOLEAN HandleCheckForExitArrowsInput( BOOLEAN fAdjustConfirm ) //Return right away, saying that we are in this mode, don't do any normal stuff! if ( guiCurrentUICursor == NOEXIT_EAST_UICURSOR || guiCurrentUICursor == NOEXIT_WEST_UICURSOR - || guiCurrentUICursor == NOEXIT_NORTH_UICURSOR || guiCurrentUICursor == NOEXIT_SOUTH_UICURSOR || - guiCurrentUICursor == NOEXIT_GRID_UICURSOR ) + || guiCurrentUICursor == NOEXIT_NORTH_UICURSOR || guiCurrentUICursor == NOEXIT_SOUTH_UICURSOR || + guiCurrentUICursor == NOEXIT_GRID_UICURSOR ) { // Yeah, but add a message.... if( gfInvalidTraversal ) @@ -3954,12 +3965,12 @@ BOOLEAN HandleCheckForExitArrowsInput( BOOLEAN fAdjustConfirm ) if( gMercProfiles[ MercPtrs[ gusSelectedSoldier ]->ubProfile ].bSex == MALE ) { //male singular swprintf( str, pExitingSectorHelpText[ EXIT_GUI_MERC_CANT_ISOLATE_EPC_HELPTEXT_MALE_SINGULAR ], MercPtrs[ gusSelectedSoldier ]->name, - MercPtrs[ gbPotentiallyAbandonedEPCSlotID ]->name ); + MercPtrs[ gbPotentiallyAbandonedEPCSlotID ]->name ); } else { //female singular swprintf( str, pExitingSectorHelpText[ EXIT_GUI_MERC_CANT_ISOLATE_EPC_HELPTEXT_FEMALE_SINGULAR ], MercPtrs[ gusSelectedSoldier ]->name, - MercPtrs[ gbPotentiallyAbandonedEPCSlotID ]->name ); + MercPtrs[ gbPotentiallyAbandonedEPCSlotID ]->name ); } } else @@ -3980,7 +3991,7 @@ BOOLEAN HandleCheckForExitArrowsInput( BOOLEAN fAdjustConfirm ) { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ MERC_IS_TOO_FAR_AWAY_STR ], MercPtrs[ gusSelectedSoldier ]->name ); } - + return( TRUE ); } @@ -3995,14 +4006,14 @@ BOOLEAN HandleCheckForExitArrowsInput( BOOLEAN fAdjustConfirm ) } else { - if ( !GetMouseMapPos( &sMapPos ) ) + if ( !GetMouseMapPos( &usMapPos ) ) { return( FALSE ); } // Goto next sector //SimulateMouseMovement( gusMouseXPos - 5, gusMouseYPos ); - InitSectorExitMenu( DIRECTION_EXITGRID, sMapPos ); + InitSectorExitMenu( DIRECTION_EXITGRID, usMapPos ); } } return( TRUE ); @@ -4087,7 +4098,7 @@ void CreateRandomItem() { OBJECTTYPE Object; UINT16 usMapPos; - if ( GetMouseMapPos( (INT16 *)&usMapPos ) ) + if ( GetMouseMapPos( &usMapPos ) ) { CreateItem( (UINT16) (Random( 35 ) + 1), 100, &Object ); AddItemToPool( usMapPos, &Object, -1 , 0, 0, 0 ); @@ -4100,7 +4111,7 @@ void MakeSelectedSoldierTired() SOLDIERTYPE *pSoldier; OBJECTTYPE Object; UINT16 usMapPos; - if ( GetMouseMapPos( (INT16 *)&usMapPos ) ) + if ( GetMouseMapPos( &usMapPos ) ) { CreateItem( (UINT16)TNT, 100, &Object ); AddItemToPool( usMapPos, &Object, -1, 0, 0, 0 ); @@ -4138,7 +4149,7 @@ void ToggleRealTime( UINT32 *puiNewEvent ) ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Switching to Turnbased." ); } - + // Plot new path! gfPlotNewMovement = TRUE; } @@ -4187,7 +4198,7 @@ void ToggleViewAllItems() void TestExplosion() { UINT16 usMapPos; - if ( GetMouseMapPos( (INT16 *)&usMapPos ) ) + if ( GetMouseMapPos( &usMapPos ) ) { EXPLOSION_PARAMS ExpParams ; ExpParams.uiFlags = 0; @@ -4211,7 +4222,7 @@ void CycleSelectedMercsItem() { // Get soldier... pSoldier = MercPtrs[ gusUIFullTargetID ]; - + usOldItem = pSoldier->inv[ HANDPOS ].usItem; usOldItem++; @@ -4222,7 +4233,7 @@ void CycleSelectedMercsItem() } CreateItem( (UINT16)usOldItem, 100, &( pSoldier->inv[ HANDPOS ]) ); - + DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); } @@ -4260,15 +4271,15 @@ void RefreshSoldier() } - if ( GetMouseMapPos( (INT16 *)&usMapPos ) ) + if ( GetMouseMapPos( &usMapPos ) ) sprintf( gDebugStr, "%d %d %d %d %d %d %d %d", gubWorldMovementCosts[ usMapPos ][ 0 ][ 0 ], - gubWorldMovementCosts[ usMapPos ][ 1 ][gsInterfaceLevel], - gubWorldMovementCosts[ usMapPos ][ 2 ][gsInterfaceLevel], - gubWorldMovementCosts[ usMapPos ][ 3 ][gsInterfaceLevel], - gubWorldMovementCosts[ usMapPos ][ 4 ][gsInterfaceLevel], - gubWorldMovementCosts[ usMapPos ][ 5 ][gsInterfaceLevel], - gubWorldMovementCosts[ usMapPos ][ 6 ][gsInterfaceLevel], - gubWorldMovementCosts[ usMapPos ][ 7 ][gsInterfaceLevel] ); + gubWorldMovementCosts[ usMapPos ][ 1 ][gsInterfaceLevel], + gubWorldMovementCosts[ usMapPos ][ 2 ][gsInterfaceLevel], + gubWorldMovementCosts[ usMapPos ][ 3 ][gsInterfaceLevel], + gubWorldMovementCosts[ usMapPos ][ 4 ][gsInterfaceLevel], + gubWorldMovementCosts[ usMapPos ][ 5 ][gsInterfaceLevel], + gubWorldMovementCosts[ usMapPos ][ 6 ][gsInterfaceLevel], + gubWorldMovementCosts[ usMapPos ][ 7 ][gsInterfaceLevel] ); } void ChangeSoldiersBodyType( UINT8 ubBodyType, BOOLEAN fCreateNewPalette ) @@ -4287,31 +4298,31 @@ void ChangeSoldiersBodyType( UINT8 ubBodyType, BOOLEAN fCreateNewPalette ) switch( ubBodyType ) { - case ADULTFEMALEMONSTER: - case AM_MONSTER: - case YAF_MONSTER: - case YAM_MONSTER: - case LARVAE_MONSTER: - case INFANT_MONSTER: - case QUEENMONSTER: + case ADULTFEMALEMONSTER: + case AM_MONSTER: + case YAF_MONSTER: + case YAM_MONSTER: + case LARVAE_MONSTER: + case INFANT_MONSTER: + case QUEENMONSTER: - pSoldier->uiStatusFlags |= SOLDIER_MONSTER; - memset( &(pSoldier->inv), 0, sizeof( OBJECTTYPE ) * NUM_INV_SLOTS ); - AssignCreatureInventory( pSoldier ); - CreateItem( CREATURE_YOUNG_MALE_SPIT, 100, &(pSoldier->inv[HANDPOS]) ); + pSoldier->uiStatusFlags |= SOLDIER_MONSTER; + memset( &(pSoldier->inv), 0, sizeof( OBJECTTYPE ) * NUM_INV_SLOTS ); + AssignCreatureInventory( pSoldier ); + CreateItem( CREATURE_YOUNG_MALE_SPIT, 100, &(pSoldier->inv[HANDPOS]) ); - break; + break; - case TANK_NW: - case TANK_NE: + case TANK_NW: + case TANK_NE: - pSoldier->uiStatusFlags |= SOLDIER_VEHICLE; - //pSoldier->inv[ HANDPOS ].usItem = TANK_CANNON; - - pSoldier->inv[ HANDPOS ].usItem = MINIMI; - pSoldier->bVehicleID = (INT8)AddVehicleToList( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ, HUMMER ); + pSoldier->uiStatusFlags |= SOLDIER_VEHICLE; + //pSoldier->inv[ HANDPOS ].usItem = TANK_CANNON; - break; + pSoldier->inv[ HANDPOS ].usItem = MINIMI; + pSoldier->bVehicleID = (INT8)AddVehicleToList( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ, HUMMER ); + + break; } } @@ -4326,7 +4337,7 @@ void TeleportSelectedSoldier() // CHECK IF WE'RE ON A GUY ( EITHER SELECTED, OURS, OR THEIRS if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) { - if ( GetMouseMapPos( (INT16 *)&usMapPos ) ) + if ( GetMouseMapPos( &usMapPos ) ) { // Check level first.... if ( gsInterfaceLevel == 0 ) @@ -4341,7 +4352,7 @@ void TeleportSelectedSoldier() if ( FindStructure( usMapPos, STRUCTURE_ROOF ) != NULL ) { SetSoldierHeight( pSoldier, 50.0 ); - + TeleportSoldier( pSoldier, usMapPos, TRUE ); EVENT_StopMerc( pSoldier, pSoldier->sGridNo, pSoldier->bDirection ); } @@ -4398,26 +4409,26 @@ void TogglePlanningMode() { EndUIPlan( ); } - else if ( GetMouseMapPos( (INT16 *)&usMapPos ) ) + else if ( GetMouseMapPos( &usMapPos ) ) { switch( gCurrentUIMode ) { - case MOVE_MODE: - if ( gusSelectedSoldier != NO_SOLDIER ) - { - GetSoldier( &pSoldier, gusSelectedSoldier ); - BeginUIPlan( pSoldier ); - AddUIPlan( usMapPos, UIPLAN_ACTION_MOVETO ); - } - break; - case ACTION_MODE: - if ( gusSelectedSoldier != NO_SOLDIER ) - { - GetSoldier( &pSoldier, gusSelectedSoldier ); - BeginUIPlan( pSoldier ); - AddUIPlan( usMapPos, UIPLAN_ACTION_FIRE ); - } - break; + case MOVE_MODE: + if ( gusSelectedSoldier != NO_SOLDIER ) + { + GetSoldier( &pSoldier, gusSelectedSoldier ); + BeginUIPlan( pSoldier ); + AddUIPlan( usMapPos, UIPLAN_ACTION_MOVETO ); + } + break; + case ACTION_MODE: + if ( gusSelectedSoldier != NO_SOLDIER ) + { + GetSoldier( &pSoldier, gusSelectedSoldier ); + BeginUIPlan( pSoldier ); + AddUIPlan( usMapPos, UIPLAN_ACTION_FIRE ); + } + break; } } } @@ -4439,28 +4450,28 @@ void ObliterateSector() // Kill everybody! cnt = gTacticalStatus.Team[ gbPlayerNum ].bLastID + 1; - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Obliterating Sector!" ); - #endif +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Obliterating Sector!" ); +#endif for ( pTSoldier = MercPtrs[ cnt ]; cnt < MAX_NUM_SOLDIERS; pTSoldier++, cnt++ ) { if ( pTSoldier->bActive && !pTSoldier->bNeutral && (pTSoldier->bSide != gbPlayerNum ) ) { - // ANITILE_PARAMS AniParams; + // ANITILE_PARAMS AniParams; // memset( &AniParams, 0, sizeof( ANITILE_PARAMS ) ); // AniParams.sGridNo = pTSoldier->sGridNo; // AniParams.ubLevelID = ANI_STRUCT_LEVEL; // AniParams.usTileType = FIRSTEXPLOSION; - // AniParams.usTileIndex = FIRSTEXPLOSION1; - // AniParams.sDelay = 80; - // AniParams.sStartFrame = 0; - // AniParams.uiFlags = ANITILE_FORWARD; + // AniParams.usTileIndex = FIRSTEXPLOSION1; + // AniParams.sDelay = 80; + // AniParams.sStartFrame = 0; + // AniParams.uiFlags = ANITILE_FORWARD; - // CreateAnimationTile( &AniParams ); - //PlayJA2Sample( EXPLOSION_1, RATE_11025, MIDVOLUME, 1, MIDDLEPAN ); + // CreateAnimationTile( &AniParams ); + //PlayJA2Sample( EXPLOSION_1, RATE_11025, MIDVOLUME, 1, MIDDLEPAN ); - EVENT_SoldierGotHit( pTSoldier, 0, 400, 0, pTSoldier->bDirection, 320, NOBODY , FIRE_WEAPON_NO_SPECIAL, pTSoldier->bAimShotLocation, 0, NOWHERE ); + EVENT_SoldierGotHit( pTSoldier, 0, 400, 0, pTSoldier->bDirection, 320, NOBODY , FIRE_WEAPON_NO_SPECIAL, pTSoldier->bAimShotLocation, 0, NOWHERE ); } } } @@ -4499,7 +4510,7 @@ void CreateNextCivType() UINT16 usMapPos; static INT8 bBodyType = FATCIV; // Get Grid Corrdinates of mouse - if ( GetMouseWorldCoordsInCenter( &sWorldX, &sWorldY ) && GetMouseMapPos( (INT16 *)&usMapPos ) ) + if ( GetMouseWorldCoordsInCenter( &sWorldX, &sWorldY ) && GetMouseMapPos( &usMapPos ) ) { INT8 iNewIndex; @@ -4557,7 +4568,7 @@ void CreateCow() SOLDIERCREATE_STRUCT MercCreateStruct; UINT16 usMapPos; // Get Grid Corrdinates of mouse - if ( GetMouseWorldCoordsInCenter( &sWorldX, &sWorldY ) && GetMouseMapPos( (INT16 *)&usMapPos ) ) + if ( GetMouseWorldCoordsInCenter( &sWorldX, &sWorldY ) && GetMouseMapPos( &usMapPos ) ) { INT8 iNewIndex; @@ -4589,7 +4600,7 @@ void CreatePlayerControlledCow() SOLDIERCREATE_STRUCT MercCreateStruct; UINT16 usMapPos; // Get Grid Corrdinates of mouse - if ( GetMouseWorldCoordsInCenter( &sWorldX, &sWorldY ) && GetMouseMapPos( (INT16 *)&usMapPos ) ) + if ( GetMouseWorldCoordsInCenter( &sWorldX, &sWorldY ) && GetMouseMapPos( &usMapPos ) ) { INT8 iNewIndex; @@ -4631,7 +4642,7 @@ void GrenadeTest1() Object.usItem = MUSTARD_GRENADE; Object.bStatus[ 0 ] = 100; Object.ubNumberOfObjects = 1; - CreatePhysicalObject( &Object, 60, (FLOAT)(sX * CELL_X_SIZE), (FLOAT)(sY * CELL_Y_SIZE ), 256, -20, 20, 158, NOBODY, THROW_ARM_ITEM, 0 ); + CreatePhysicalObject( &Object, 60, (FLOAT)(sX * CELL_X_SIZE), (FLOAT)(sY * CELL_Y_SIZE ), 256, -20, 20, 158, NOBODY, THROW_ARM_ITEM, 0, FALSE ); } } @@ -4645,7 +4656,7 @@ void GrenadeTest2() Object.usItem = HAND_GRENADE; Object.bStatus[ 0 ] = 100; Object.ubNumberOfObjects = 1; - CreatePhysicalObject( &Object, 60, (FLOAT)(sX * CELL_X_SIZE), (FLOAT)(sY * CELL_Y_SIZE ), 256, 0, -30, 158, NOBODY, THROW_ARM_ITEM, 0 ); + CreatePhysicalObject( &Object, 60, (FLOAT)(sX * CELL_X_SIZE), (FLOAT)(sY * CELL_Y_SIZE ), 256, 0, -30, 158, NOBODY, THROW_ARM_ITEM, 0, FALSE ); } } @@ -4659,7 +4670,7 @@ void GrenadeTest3() Object.usItem = HAND_GRENADE; Object.bStatus[ 0 ] = 100; Object.ubNumberOfObjects = 1; - CreatePhysicalObject( &Object, 60, (FLOAT)(sX * CELL_X_SIZE), (FLOAT)(sY * CELL_Y_SIZE ), 256, -10, 10, 158, NOBODY, THROW_ARM_ITEM, 0 ); + CreatePhysicalObject( &Object, 60, (FLOAT)(sX * CELL_X_SIZE), (FLOAT)(sY * CELL_Y_SIZE ), 256, -10, 10, 158, NOBODY, THROW_ARM_ITEM, 0, FALSE ); } } @@ -4667,7 +4678,7 @@ void CreatePlayerControlledMonster() { INT16 sWorldX, sWorldY; UINT16 usMapPos; - if ( GetMouseWorldCoordsInCenter( &sWorldX, &sWorldY ) && GetMouseMapPos( (INT16 *)&usMapPos ) ) + if ( GetMouseWorldCoordsInCenter( &sWorldX, &sWorldY ) && GetMouseMapPos( &usMapPos ) ) { SOLDIERCREATE_STRUCT MercCreateStruct; INT8 iNewIndex; @@ -4681,7 +4692,7 @@ void CreatePlayerControlledMonster() //Note: only gets called if Alt and/or Ctrl isn't pressed! if ( _KeyDown( INSERT ) ) MercCreateStruct.bBodyType = QUEENMONSTER; - //MercCreateStruct.bBodyType = LARVAE_MONSTER; + //MercCreateStruct.bBodyType = LARVAE_MONSTER; else MercCreateStruct.bBodyType = ADULTFEMALEMONSTER; MercCreateStruct.bTeam = SOLDIER_CREATE_AUTO_TEAM; @@ -4706,51 +4717,51 @@ INT8 CheckForAndHandleHandleVehicleInteractiveClick( SOLDIERTYPE *pSoldier, UINT if ( gfUIFullTargetFound ) { - pTSoldier = MercPtrs[ gusUIFullTargetID ]; + pTSoldier = MercPtrs[ gusUIFullTargetID ]; - if ( OK_ENTERABLE_VEHICLE( pTSoldier ) && pTSoldier->bVisible != -1 && OKUseVehicle( pTSoldier->ubProfile ) ) - { - if ( ( GetNumberInVehicle( pTSoldier->bVehicleID ) == 0 ) || !fMovementMode ) - { - // Find a gridno closest to sweetspot... - sActionGridNo = FindGridNoFromSweetSpotWithStructDataFromSoldier( pSoldier, pSoldier->usUIMovementMode, 5, &ubDirection, 0, pTSoldier ); + if ( OK_ENTERABLE_VEHICLE( pTSoldier ) && pTSoldier->bVisible != -1 && OKUseVehicle( pTSoldier->ubProfile ) ) + { + if ( ( GetNumberInVehicle( pTSoldier->bVehicleID ) == 0 ) || !fMovementMode ) + { + // Find a gridno closest to sweetspot... + sActionGridNo = FindGridNoFromSweetSpotWithStructDataFromSoldier( pSoldier, pSoldier->usUIMovementMode, 5, &ubDirection, 0, pTSoldier ); - if ( sActionGridNo != NOWHERE ) - { - // Calculate AP costs... - //sAPCost = GetAPsToBeginFirstAid( pSoldier ); - sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints); + if ( sActionGridNo != NOWHERE ) + { + // Calculate AP costs... + //sAPCost = GetAPsToBeginFirstAid( pSoldier ); + sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints); - if ( EnoughPoints( pSoldier, sAPCost, 0, TRUE ) ) + if ( EnoughPoints( pSoldier, sAPCost, 0, TRUE ) ) + { + DoMercBattleSound( pSoldier, BATTLE_SOUND_OK1 ); + + // CHECK IF WE ARE AT THIS GRIDNO NOW + if ( pSoldier->sGridNo != sActionGridNo ) { - DoMercBattleSound( pSoldier, BATTLE_SOUND_OK1 ); + // SEND PENDING ACTION + pSoldier->ubPendingAction = MERC_ENTER_VEHICLE; + pSoldier->sPendingActionData2 = pTSoldier->sGridNo; + pSoldier->bPendingActionData3 = ubDirection; + pSoldier->ubPendingActionAnimCount = 0; - // CHECK IF WE ARE AT THIS GRIDNO NOW - if ( pSoldier->sGridNo != sActionGridNo ) - { - // SEND PENDING ACTION - pSoldier->ubPendingAction = MERC_ENTER_VEHICLE; - pSoldier->sPendingActionData2 = pTSoldier->sGridNo; - pSoldier->bPendingActionData3 = ubDirection; - pSoldier->ubPendingActionAnimCount = 0; - - // WALK UP TO DEST FIRST - EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, 3 , pSoldier->fNoAPToFinishMove ); - } - else - { - EVENT_SoldierEnterVehicle( pSoldier, pTSoldier->sGridNo, ubDirection ); - } - - // OK, set UI - SetUIBusy( pSoldier->ubID ); - //guiPendingOverrideEvent = A_CHANGE_TO_MOVE; - - return( -1 ); + // WALK UP TO DEST FIRST + EVENT_InternalGetNewSoldierPath( pSoldier, sActionGridNo, pSoldier->usUIMovementMode, 3 , pSoldier->fNoAPToFinishMove ); } - } - } - } + else + { + EVENT_SoldierEnterVehicle( pSoldier, pTSoldier->sGridNo, ubDirection ); + } + + // OK, set UI + SetUIBusy( pSoldier->ubID ); + //guiPendingOverrideEvent = A_CHANGE_TO_MOVE; + + return( -1 ); + } + } + } + } } return( 0 ); @@ -4760,7 +4771,7 @@ void HandleHandCursorClick( UINT16 usMapPos, UINT32 *puiNewEvent ) { SOLDIERTYPE *pSoldier; LEVELNODE *pIntTile; - INT16 sIntTileGridNo; + INT16 sIntTileGridNo; INT16 sActionGridNo; UINT8 ubDirection; INT16 sAPCost; @@ -4772,11 +4783,11 @@ void HandleHandCursorClick( UINT16 usMapPos, UINT32 *puiNewEvent ) if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) { - // If we are out of breath, no cursor... - if ( pSoldier->bBreath < OKBREATH && pSoldier->bCollapsed ) - { - return; - } + // If we are out of breath, no cursor... + if ( pSoldier->bBreath < OKBREATH && pSoldier->bCollapsed ) + { + return; + } if ( CheckForAndHandleHandleVehicleInteractiveClick( pSoldier, usMapPos, FALSE ) == -1 ) { @@ -4787,8 +4798,8 @@ void HandleHandCursorClick( UINT16 usMapPos, UINT32 *puiNewEvent ) // Check if we are on a merc... if so.. steal! if ( gfUIFullTargetFound ) { - if ( ( guiUIFullTargetFlags & ENEMY_MERC ) && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) - { + if ( ( guiUIFullTargetFlags & ENEMY_MERC ) && !( guiUIFullTargetFlags & UNCONSCIOUS_MERC ) ) + { sActionGridNo = FindAdjacentGridEx( pSoldier, MercPtrs[ gusUIFullTargetID ]->sGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); if ( sActionGridNo == -1 ) { @@ -4800,17 +4811,17 @@ void HandleHandCursorClick( UINT16 usMapPos, UINT32 *puiNewEvent ) if ( EnoughPoints( pSoldier, sAPCost, 0, TRUE ) ) { - MercStealFromMerc( pSoldier, MercPtrs[ gusUIFullTargetID ] ); + MercStealFromMerc( pSoldier, MercPtrs[ gusUIFullTargetID ] ); - *puiNewEvent = A_CHANGE_TO_MOVE; + *puiNewEvent = A_CHANGE_TO_MOVE; - return; + return; } - else - { - return; - } - } + else + { + return; + } + } } // Default action gridno to mouse.... @@ -4883,32 +4894,32 @@ void HandleHandCursorClick( UINT16 usMapPos, UINT32 *puiNewEvent ) { // ATE: Here, the poor player wants to search something that does not exist... // Why should we not let them make fools of themselves....? - if ( AM_AN_EPC( pSoldier ) ) - { - // Display message - // ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ EPC_CANNOT_DO_THAT ] ); - } - else - { - // Check morale, if < threashold, refuse... - if ( pSoldier->bMorale < 30 ) - { - TacticalCharacterDialogue( pSoldier, QUOTE_REFUSING_ORDER ); - } - else - { - if ( gsCurrentActionPoints == 0 ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); - } - else - { - SoldierPickupItem( pSoldier, NOTHING, sActionGridNo, 0 ); - *puiNewEvent = A_CHANGE_TO_MOVE; - } - } - } + if ( AM_AN_EPC( pSoldier ) ) + { + // Display message + // ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ EPC_CANNOT_DO_THAT ] ); + } + else + { + // Check morale, if < threashold, refuse... + if ( pSoldier->bMorale < 30 ) + { + TacticalCharacterDialogue( pSoldier, QUOTE_REFUSING_ORDER ); + } + else + { + if ( gsCurrentActionPoints == 0 ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); + } + else + { + SoldierPickupItem( pSoldier, NOTHING, sActionGridNo, 0 ); + *puiNewEvent = A_CHANGE_TO_MOVE; + } + } + } } } } @@ -4934,7 +4945,7 @@ INT8 HandleMoveModeInteractiveClick( UINT16 usMapPos, UINT32 *puiNewEvent ) BOOLEAN fContinue = TRUE; SOLDIERTYPE *pSoldier; LEVELNODE *pIntTile; - INT16 sIntTileGridNo; + INT16 sIntTileGridNo; INT16 sActionGridNo; UINT8 ubDirection; INT8 bReturnCode = 0; @@ -4943,11 +4954,11 @@ INT8 HandleMoveModeInteractiveClick( UINT16 usMapPos, UINT32 *puiNewEvent ) if( GetSoldier( &pSoldier, gusSelectedSoldier ) ) { - // If we are out of breath, no cursor... - // if ( pSoldier->bBreath < OKBREATH ) - //{ - // return( -1 ); - //} + // If we are out of breath, no cursor... + // if ( pSoldier->bBreath < OKBREATH ) + //{ + // return( -1 ); + //} // ATE: If we are a vehicle, no moving! if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) @@ -4957,18 +4968,18 @@ INT8 HandleMoveModeInteractiveClick( UINT16 usMapPos, UINT32 *puiNewEvent ) } // OK, check for height differences..... - if ( gpWorldLevelData[ usMapPos ].sHeight != gpWorldLevelData[ pSoldier->sGridNo ].sHeight ) + if ( gpWorldLevelData[ usMapPos ].sHeight != gpWorldLevelData[ pSoldier->sGridNo ].sHeight ) { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANT_GET_THERE ] ); return( -1 ); } - + // See if we are over a vehicle, and walk up to it and enter.... if ( CheckForAndHandleHandleVehicleInteractiveClick( pSoldier, usMapPos, TRUE ) == -1 ) { return( -1 ); } - + // Check if we are over a civillian.... if ( gfUIFullTargetFound ) { @@ -4977,15 +4988,15 @@ INT8 HandleMoveModeInteractiveClick( UINT16 usMapPos, UINT32 *puiNewEvent ) // Check if we can... if ( CanExchangePlaces( pSoldier, MercPtrs[ gusUIFullTargetID ], TRUE ) ) { - gpExchangeSoldier1 = pSoldier; - gpExchangeSoldier2 = MercPtrs[ gusUIFullTargetID ]; + gpExchangeSoldier1 = pSoldier; + gpExchangeSoldier2 = MercPtrs[ gusUIFullTargetID ]; - // Do message box... - //DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ EXCHANGE_PLACES_REQUESTER ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, ExchangeMessageBoxCallBack, NULL ); - SwapMercPositions( gpExchangeSoldier1, gpExchangeSoldier2 ); + // Do message box... + //DoMessageBox( MSG_BOX_BASIC_STYLE, TacticalStr[ EXCHANGE_PLACES_REQUESTER ], GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, ExchangeMessageBoxCallBack, NULL ); + SwapMercPositions( gpExchangeSoldier1, gpExchangeSoldier2 ); } } - return( -3 ); + return( -3 ); } pIntTile = GetCurInteractiveTileGridNoAndStructure( &sIntTileGridNo, &pStructure ); @@ -5076,8 +5087,8 @@ BOOLEAN HandleUIReloading( SOLDIERTYPE *pSoldier ) // Do we say we could not reload gun...? } - // ATE: Re-examine cursor info! - gfUIForceReExamineCursorData = TRUE; + // ATE: Re-examine cursor info! + gfUIForceReExamineCursorData = TRUE; } return( TRUE ); } @@ -5104,9 +5115,9 @@ BOOLEAN ConfirmActionCancel( UINT16 usMapPos, UINT16 usOldMapPos ) // confirm UI, we want a bigger radius... //if ( InAimCubeUI( ) ) //{ - // Calculate distence between both gridnos..... + // Calculate distence between both gridnos..... // if ( GetRangeFromGridNoDiff( GetInAimCubeUIGridNo( ), usOldMapPos ) > 1 ) - //if ( usMapPos != usOldMapPos ) + //if ( usMapPos != usOldMapPos ) // { // return( TRUE ); // } @@ -5126,7 +5137,7 @@ void ChangeCurrentSquad( INT32 iSquad ) { // only allow if nothing in hand and the Change Squad button for whichever panel we're in must be enabled if ( ( gpItemPointer == NULL ) && !gfDisableTacticalPanelButtons && - ( ( gsCurInterfacePanel != TEAM_PANEL ) || ( ButtonList[ iTEAMPanelButtons[ CHANGE_SQUAD_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) + ( ( gsCurInterfacePanel != TEAM_PANEL ) || ( ButtonList[ iTEAMPanelButtons[ CHANGE_SQUAD_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) ) { if ( IsSquadOnCurrentTacticalMap( iSquad ) ) { @@ -5174,7 +5185,7 @@ void TestMeanWhile( INT32 iID ) // Are we a POW in this sector? if ( pSoldier->bActive && pSoldier->bInSector ) { - + ChangeSoldiersAssignment( pSoldier, ASSIGNMENT_POW ); pSoldier->sSectorX = 7; @@ -5204,18 +5215,18 @@ void EscapeUILock( ) #include "Map Edgepoints.h" void ToggleMapEdgepoints() { - #ifdef JA2EDITOR - static BOOLEAN fToggleEdgepointDisplay = FALSE; - if( fToggleEdgepointDisplay ^= TRUE ) - { //Show edgepoints - ShowMapEdgepoints(); - } - else - { //Hide edgepoints - HideMapEdgepoints(); - } - SetRenderFlags( RENDER_FLAG_FULL ); - #endif +#ifdef JA2EDITOR + static BOOLEAN fToggleEdgepointDisplay = FALSE; + if( fToggleEdgepointDisplay ^= TRUE ) + { //Show edgepoints + ShowMapEdgepoints(); + } + else + { //Hide edgepoints + HideMapEdgepoints(); + } + SetRenderFlags( RENDER_FLAG_FULL ); +#endif } #endif @@ -5243,7 +5254,7 @@ void HandleStanceChangeFromUIKeys( UINT8 ubAnimHeight ) SOLDIERTYPE * pSoldier; INT32 cnt; SOLDIERTYPE *pFirstSoldier = NULL; - + if ( gTacticalStatus.fAtLeastOneGuyOnMultiSelect ) { // OK, loop through all guys who are 'multi-selected' and @@ -5272,26 +5283,26 @@ void ToggleStealthMode( SOLDIERTYPE *pSoldier ) { // nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel if ( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ giSMStealthButton ]->uiFlags & BUTTON_ENABLED ) ) - { - // ATE: Toggle stealth - if ( gpSMCurrentMerc != NULL && pSoldier->ubID == gpSMCurrentMerc->ubID ) - { - gfUIStanceDifferent = TRUE; - } + { + // ATE: Toggle stealth + if ( gpSMCurrentMerc != NULL && pSoldier->ubID == gpSMCurrentMerc->ubID ) + { + gfUIStanceDifferent = TRUE; + } - pSoldier->bStealthMode = ! pSoldier->bStealthMode; - gfPlotNewMovement = TRUE; - fInterfacePanelDirty = DIRTYLEVEL2; + pSoldier->bStealthMode = ! pSoldier->bStealthMode; + gfPlotNewMovement = TRUE; + fInterfacePanelDirty = DIRTYLEVEL2; - if ( pSoldier->bStealthMode ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_MERC_ON_STEALTHMODE ], pSoldier->name ); - } - else - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_MERC_OFF_STEALTHMODE ], pSoldier->name ); - } - } + if ( pSoldier->bStealthMode ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_MERC_ON_STEALTHMODE ], pSoldier->name ); + } + else + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_MERC_OFF_STEALTHMODE ], pSoldier->name ); + } + } } @@ -5301,7 +5312,7 @@ void HandleStealthChangeFromUIKeys( ) SOLDIERTYPE * pSoldier; INT32 cnt; SOLDIERTYPE *pFirstSoldier = NULL; - + if ( gTacticalStatus.fAtLeastOneGuyOnMultiSelect ) { // OK, loop through all guys who are 'multi-selected' and @@ -5322,12 +5333,12 @@ void HandleStealthChangeFromUIKeys( ) else { if( gusSelectedSoldier != NO_SOLDIER ) - { - if ( !AM_A_ROBOT( MercPtrs[ gusSelectedSoldier ] ) ) - { - ToggleStealthMode( MercPtrs[ gusSelectedSoldier ] ); - } - } + { + if ( !AM_A_ROBOT( MercPtrs[ gusSelectedSoldier ] ) ) + { + ToggleStealthMode( MercPtrs[ gusSelectedSoldier ] ); + } + } } } @@ -5354,7 +5365,7 @@ void TestCapture( ) if ( uiNumChosen < 3 ) { EnemyCapturesPlayerSoldier( pSoldier ); - + // Remove them from tectical.... RemoveSoldierFromGridNo( pSoldier ); diff --git a/Tactical/UI Cursors.cpp b/Tactical/UI Cursors.cpp index 538feb04..a44716ce 100644 --- a/Tactical/UI Cursors.cpp +++ b/Tactical/UI Cursors.cpp @@ -26,6 +26,9 @@ #include "soldier macros.h" #include "text.h" #include "spread burst.h" + #include "GameSettings.h" + #include "Interactive Tiles.h" + #include "PATHAI.H" #endif // FUNCTIONS FOR ITEM CURSOR HANDLING @@ -1129,7 +1132,7 @@ void DetermineCursorBodyLocation( UINT8 ubSoldierID, BOOLEAN fDisplay, BOOLEAN f // ALWAYS SET AIM LOCATION TO NOTHING pSoldier->bAimShotLocation = AIM_SHOT_RANDOM; - if( !GetMouseMapPos( (INT16 *)&usMapPos) ) + if( !GetMouseMapPos( &usMapPos) ) { return; } @@ -1919,7 +1922,7 @@ void HandleLeftClickCursor( SOLDIERTYPE *pSoldier ) { UINT16 usInHand; UINT8 ubItemCursor; - INT16 sGridNo; + UINT16 usGridNo; // LOOK IN GUY'S HAND TO CHECK LOCATION usInHand = pSoldier->inv[HANDPOS].usItem; @@ -1938,7 +1941,7 @@ void HandleLeftClickCursor( SOLDIERTYPE *pSoldier ) return; } - if (!GetMouseMapPos( &sGridNo ) ) + if (!GetMouseMapPos( &usGridNo ) ) { return; } @@ -2002,7 +2005,7 @@ void HandleLeftClickCursor( SOLDIERTYPE *pSoldier ) case TOSSCURS: - //BeginAimCubeUI( pSoldier, sGridNo, (INT8)gsInterfaceLevel, 0, 0 ); + //BeginAimCubeUI( pSoldier, usGridNo, (INT8)gsInterfaceLevel, 0, 0 ); //break; default: diff --git a/Tactical/Vehicles.cpp b/Tactical/Vehicles.cpp index bdde236b..4e94f685 100644 --- a/Tactical/Vehicles.cpp +++ b/Tactical/Vehicles.cpp @@ -29,6 +29,15 @@ #include "animation control.h" #include "strategicmap.h" #include "Interface Control.h" + #include "Campaign Types.h" + #include "Map Screen Interface.h" + #include "jascreens.h" + #include "screenids.h" + #include "Quests.h" + #include "Tactical Save.h" + #include "Soldier macros.h" + #include "opplist.h" + #include "Soldier ani.h" #endif INT8 gubVehicleMovementGroups[ MAX_VEHICLES ]; diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index 4eb7ec50..5480ec2a 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -42,6 +42,10 @@ #include "Debug Control.h" #include "expat.h" #include "XML.h" + #include "Soldier macros.h" + #include "SmokeEffects.h" + #include "lighting.h" + #include "Auto Resolve.h" #endif //rain @@ -1289,7 +1293,7 @@ BOOLEAN FireWeapon( SOLDIERTYPE *pSoldier , INT16 sTargetGridNo ) { // FREE UP NPC! DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - attack on own gridno!") ); - FreeUpAttacker( (UINT8) pSoldier->ubID ); + FreeUpAttacker( ); return( FALSE ); } @@ -1531,6 +1535,10 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT16 sTargetGridNo ) // ONly deduct points once if ( pSoldier->bDoBurst == 1 ) { + INT8 bShotsToFire = pSoldier->bDoAutofire ? + pSoldier->bDoAutofire : + GetShotsPerBurst(&pSoldier->inv[HANDPOS]); + if ( Weapon[ usItemNum ].sBurstSound != NO_WEAPON_SOUND ) { // IF we are silenced? @@ -1538,7 +1546,7 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT16 sTargetGridNo ) if( noisefactor < MAX_PERCENT_NOISE_VOLUME_FOR_SILENCED_SOUND || Weapon[ usItemNum ].ubAttackVolume <= 10 ) { // Pick sound file baed on how many bullets we are going to fire... - sprintf( zBurstString, gzBurstSndStrings[ Weapon[ usItemNum ].sSilencedBurstSound ], pSoldier->bBulletsLeft ); + sprintf( zBurstString, gzBurstSndStrings[ Weapon[ usItemNum ].sSilencedBurstSound ], bShotsToFire ); // Try playing sound... pSoldier->iBurstSoundID = PlayJA2SampleFromFile( zBurstString, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); @@ -1547,7 +1555,7 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT16 sTargetGridNo ) { // Pick sound file baed on how many bullets we are going to fire... // Lesh: changed next line - sprintf( zBurstString, gzBurstSndStrings[ Weapon[ usItemNum ].sBurstSound ], pSoldier->bBulletsLeft ); + sprintf( zBurstString, gzBurstSndStrings[ Weapon[ usItemNum ].sBurstSound ], bShotsToFire ); INT8 volume = HIGHVOLUME; if ( noisefactor < 100 ) volume = (volume * noisefactor) / 100; @@ -1880,8 +1888,10 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT16 sTargetGridNo ) } // Reduce again for attack end 'cause it has been incremented for a normal attack // + // Not anymore. Only the attack animation was increased, and it will decrease itself. DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - ATTACK ANIMATION %s ENDED BY BAD EXPLOSIVE CHECK, Now %d", gAnimControl[ pSoldier->usAnimState ].zAnimStr, gTacticalStatus.ubAttackBusyCount ) ); - ReduceAttackBusyCount( pSoldier->ubID, FALSE ); + DebugAttackBusy( String("@@@@@@@ Freeing up attacker - ATTACK ANIMATION %s ENDED BY BAD EXPLOSIVE CHECK\n", gAnimControl[ pSoldier->usAnimState ].zAnimStr ) ); +// ReduceAttackBusyCount( pSoldier->ubID, FALSE ); return( FALSE ); } @@ -1918,8 +1928,9 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT16 sTargetGridNo ) if ( gAnimControl[ MercPtrs[ ubMerc ]->usAnimState ].ubHeight != ANIM_PRONE ) { // Increment attack counter... - gTacticalStatus.ubAttackBusyCount++; +// gTacticalStatus.ubAttackBusyCount++; DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Incrementing Attack: Exaust from LAW", gTacticalStatus.ubAttackBusyCount ) ); + DebugAttackBusy( "Incrementing Attack: Exaust from LAW\n" ); EVENT_SoldierGotHit( MercPtrs[ ubMerc ], MINI_GRENADE, 10, 200, pSoldier->bDirection, 0, pSoldier->ubID, 0, ANIM_CROUCH, 0, sNewGridNo ); } @@ -2095,8 +2106,9 @@ BOOLEAN UseBlade( SOLDIERTYPE *pSoldier , INT16 sTargetGridNo ) StatChange( MercPtrs[ pTargetSoldier->ubID ], STRAMT, 5, FALSE); } } - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - missed in knife attack") ); - FreeUpAttacker( (UINT8) pSoldier->ubID ); + // 0verhaul: Another case that is handled by the animation transition system. + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - missed in knife attack") ); + // FreeUpAttacker( (UINT8) pSoldier->ubID ); } if ( PTR_OURTEAM && pSoldier->ubTargetID != NOBODY) @@ -2136,11 +2148,12 @@ BOOLEAN UseBlade( SOLDIERTYPE *pSoldier , INT16 sTargetGridNo ) StatChange( pSoldier, STRAMT, usExpGain/3, ( UINT8 )( fGonnaHit ? FALSE : FROM_FAILURE ) ); } } - else - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - missed in knife attack") ); - FreeUpAttacker( (UINT8) pSoldier->ubID ); - } + // 0verhaul: This case is also handled by the animation translations + // else + // { + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - missed in knife attack") ); + // FreeUpAttacker( (UINT8) pSoldier->ubID ); + // } // possibly reduce monster smell if ( pSoldier->bMonsterSmell > 0 && Random( 5 ) == 0 ) @@ -2382,10 +2395,11 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo, BOOLEAN fStea } } - #ifdef JA2BETAVERSION - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - steal") ); - #endif - FreeUpAttacker( (UINT8) pSoldier->ubID ); + // 0verhaul: Also handled in the animation transition + // #ifdef JA2BETAVERSION + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - steal") ); + // #endif + // FreeUpAttacker( (UINT8) pSoldier->ubID ); } // ----------------------------------- @@ -2471,11 +2485,12 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo, BOOLEAN fStea SWeaponHit.ubSpecial = FIRE_WEAPON_NO_SPECIAL; AddGameEvent( S_WEAPONHIT, (UINT16) 20, &SWeaponHit ); } - else - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - missed in HTH attack") ); - FreeUpAttacker( (UINT8) pSoldier->ubID ); - } + // 0verhaul: And this too + // else + // { + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - missed in HTH attack") ); + // FreeUpAttacker( (UINT8) pSoldier->ubID ); + // } } } @@ -2674,9 +2689,10 @@ BOOLEAN UseLauncher( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ) IgniteExplosion( pSoldier->ubID, (INT16)CenterX( pSoldier->sGridNo ), (INT16)CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, Launchable.usItem, pSoldier->bLevel ); // Reduce again for attack end 'cause it has been incremented for a normal attack - // + // Nope, not anymore. DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - ATTACK ANIMATION %s ENDED BY BAD EXPLOSIVE CHECK, Now %d", gAnimControl[ pSoldier->usAnimState ].zAnimStr, gTacticalStatus.ubAttackBusyCount ) ); - ReduceAttackBusyCount( pSoldier->ubID, FALSE ); + DebugAttackBusy( String("@@@@@@@ Freeing up attacker - ATTACK ANIMATION %s ENDED BY BAD EXPLOSIVE CHECK\n", gAnimControl[ pSoldier->usAnimState ].zAnimStr ) ); + // ReduceAttackBusyCount( pSoldier->ubID, FALSE ); // So all's well, should be good from here.... return( FALSE ); @@ -2733,7 +2749,7 @@ BOOLEAN UseLauncher( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo ) CalculateLaunchItemParamsForThrow( pSoldier, sTargetGridNo, pSoldier->bTargetLevel, 0, &Launchable, (INT8)(uiDiceRoll - uiHitChance), THROW_ARM_ITEM, 0 ); - iID = 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 ); + iID = 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 ); pObject = &( ObjectSlots[ iID ] ); //pObject->fPotentialForDebug = TRUE; @@ -2785,8 +2801,9 @@ BOOLEAN DoSpecialEffectAmmoMiss( UINT8 ubAttackerID, INT16 sGridNo, INT16 sXPos, if ( fFreeupAttacker ) { RemoveBullet( iBullet ); - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - bullet hit structure - explosive ammo") ); - FreeUpAttacker( (UINT8) ubAttackerID ); + // 0verhaul: No longer necessary + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - bullet hit structure - explosive ammo") ); + // FreeUpAttacker( (UINT8) ubAttackerID ); } } @@ -2821,8 +2838,9 @@ BOOLEAN DoSpecialEffectAmmoMiss( UINT8 ubAttackerID, INT16 sGridNo, INT16 sXPos, if ( fFreeupAttacker ) { RemoveBullet( iBullet ); - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - bullet hit structure - explosive ammo") ); - FreeUpAttacker( (UINT8) ubAttackerID ); + // 0verhaul: No longer necessary. + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - bullet hit structure - explosive ammo") ); + // FreeUpAttacker( (UINT8) ubAttackerID ); } } @@ -2857,8 +2875,9 @@ BOOLEAN DoSpecialEffectAmmoMiss( UINT8 ubAttackerID, INT16 sGridNo, INT16 sXPos, if ( fFreeupAttacker ) { RemoveBullet( iBullet ); - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - bullet hit structure - explosive ammo") ); - FreeUpAttacker( (UINT8) ubAttackerID ); + // 0verhaul: No longer necessary. + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - bullet hit structure - explosive ammo") ); + // FreeUpAttacker( (UINT8) ubAttackerID ); } } @@ -2948,26 +2967,28 @@ void WeaponHit( UINT16 usSoldierID, UINT16 usWeaponIndex, INT16 sDamage, INT16 s IgniteExplosion( ubAttackerID, sXPos, sYPos, 0, (INT16) (GETWORLDINDEXFROMWORLDCOORDS( sYPos, sXPos )), TANK_SHELL, pTargetSoldier->bLevel ); } - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - end of LAW fire") ); - FreeUpAttacker( ubAttackerID ); + // 0verhaul: No longer necessary + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - end of LAW fire") ); + // FreeUpAttacker( ubAttackerID ); return; } DoSpecialEffectAmmoMiss( ubAttackerID, pTargetSoldier->sGridNo, sXPos, sYPos, sZPos, FALSE, FALSE, 0 ); // OK, SHOT HAS HIT, DO THINGS APPROPRIATELY - // ATE: This is 'cause of that darn smoke effect that could potnetially kill - // the poor bastard .. so check - if ( !pTargetSoldier->fDoingExternalDeath ) - { - EVENT_SoldierGotHit( pTargetSoldier, usWeaponIndex, sDamage, sBreathLoss, usDirection, sRange, ubAttackerID, ubSpecial, ubHitLocation, 0, NOWHERE ); - } - else - { - // Buddy had died from additional dammage - free up attacker here... - ReduceAttackBusyCount( pTargetSoldier->ubAttackerID, FALSE ); - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Special effect killed before bullet impact, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); - } + // ATE: This is 'cause of that darn smoke effect that could potnetially kill + // the poor bastard .. so check + if ( !pTargetSoldier->fDoingExternalDeath ) + { + EVENT_SoldierGotHit( pTargetSoldier, usWeaponIndex, sDamage, sBreathLoss, usDirection, sRange, ubAttackerID, ubSpecial, ubHitLocation, 0, NOWHERE ); + } + // else + // { + // Buddy had died from additional dammage - free up attacker here... + // ReduceAttackBusyCount( pTargetSoldier->ubAttackerID, FALSE ); + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Special effect killed before bullet impact, attack count now %d", gTacticalStatus.ubAttackBusyCount) ); + // OutputDebugString( "Special effect killed before bullet impact\n" ); + // } } @@ -3041,11 +3062,9 @@ void StructureHit( INT32 iBullet, UINT16 usWeaponIndex, INT8 bWeaponStatus, UINT // marke added one 'or' to get this working with HE ammo if ( Item[usWeaponIndex].rocketlauncher || AmmoTypes[pSoldier->inv[pSoldier->ubAttackingHand ].ubGunAmmoType].explosionSize > 1) { - RemoveBullet( iBullet ); - // Reduce attacker count! DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - end of LAW fire") ); - FreeUpAttacker( ubAttackerID ); + // FreeUpAttacker( ubAttackerID ); if ( Item[usWeaponIndex].singleshotrocketlauncher ) { IgniteExplosion( ubAttackerID, (INT16)CenterX( sGridNo ), (INT16)CenterY( sGridNo ), 0, sGridNo, C1, (INT8)( sZPos >= WALL_HEIGHT ) ); @@ -3063,21 +3082,25 @@ void StructureHit( INT32 iBullet, UINT16 usWeaponIndex, INT8 bWeaponStatus, UINT IgniteExplosion( ubAttackerID, (INT16)CenterX( sGridNo ), (INT16)CenterY( sGridNo ), 0, sGridNo, AmmoTypes[pSoldier->inv[pSoldier->ubAttackingHand ].ubGunAmmoType].highExplosive , (INT8)( sZPos >= WALL_HEIGHT ) ); // pSoldier->inv[pSoldier->ubAttackingHand ].usGunAmmoItem = NONE; } + + // Moved here to make sure ABC stays >0 until everything done + RemoveBullet( iBullet ); return; } if ( Item[usWeaponIndex].cannon ) { - RemoveBullet( iBullet ); - // Reduce attacker count! - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - end of TANK fire") ); - FreeUpAttacker( ubAttackerID ); + //DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - end of TANK fire") ); + //FreeUpAttacker( ubAttackerID ); IgniteExplosion( ubAttackerID, (INT16)CenterX( sGridNo ), (INT16)CenterY( sGridNo ), 0, sGridNo, TANK_SHELL, (INT8)( sZPos >= WALL_HEIGHT ) ); //FreeUpAttacker( (UINT8) ubAttackerID ); + // Moved here to keep ABC >0 as long as possible + RemoveBullet( iBullet ); + return; } } @@ -3116,11 +3139,11 @@ void StructureHit( INT32 iBullet, UINT16 usWeaponIndex, INT8 bWeaponStatus, UINT case MONSTERCLASS: - DoSpecialEffectAmmoMiss( ubAttackerID, sGridNo, sXPos, sYPos, sZPos, FALSE, TRUE, iBullet ); + DoSpecialEffectAmmoMiss( ubAttackerID, sGridNo, sXPos, sYPos, sZPos, FALSE, TRUE, iBullet ); RemoveBullet( iBullet ); - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - monster attack hit structure") ); - FreeUpAttacker( (UINT8) ubAttackerID ); + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - monster attack hit structure") ); + // FreeUpAttacker( (UINT8) ubAttackerID ); //PlayJA2Sample( SPIT_RICOCHET , RATE_11025, uiMissVolume, 1, SoundDir( sGridNo ) ); break; @@ -3150,8 +3173,8 @@ void StructureHit( INT32 iBullet, UINT16 usWeaponIndex, INT8 bWeaponStatus, UINT } RemoveBullet( iBullet ); - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - knife attack hit structure") ); - FreeUpAttacker( (UINT8) ubAttackerID ); + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - knife attack hit structure") ); + // FreeUpAttacker( (UINT8) ubAttackerID ); } } @@ -3178,8 +3201,8 @@ void StructureHit( INT32 iBullet, UINT16 usWeaponIndex, INT8 bWeaponStatus, UINT if ( fStopped ) { RemoveBullet( iBullet ); - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - bullet hit same structure twice") ); - FreeUpAttacker( (UINT8) ubAttackerID ); + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - bullet hit same structure twice") ); + // FreeUpAttacker( (UINT8) ubAttackerID ); } } else @@ -4815,8 +4838,8 @@ void ShotMiss( UINT8 ubAttackerID, INT32 iBullet ) } - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - bullet missed") ); - FreeUpAttacker( ubAttackerID ); + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - bullet missed") ); + // FreeUpAttacker( ubAttackerID ); } UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, UINT8 ubAimTime, UINT8 ubMode ) @@ -5719,6 +5742,10 @@ UINT8 GetMagSize( OBJECTTYPE *pObj ) } BOOLEAN WeaponReady(SOLDIERTYPE * pSoldier) { +#ifdef ROBOT_ALWAYS_READY + if ( AM_A_ROBOT( pSoldier) ) + return TRUE; +#endif if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FIREREADY ) return TRUE; else diff --git a/Tactical/World Items.cpp b/Tactical/World Items.cpp index 07097093..a9207c7e 100644 --- a/Tactical/World Items.cpp +++ b/Tactical/World Items.cpp @@ -25,6 +25,9 @@ #include "Action Items.h" #include "pits.h" #include "GameSettings.h" + #include "Quests.h" + #include "Soldier Profile.h" + #include "message.h" #endif //Global dynamic array of all of the items in a loaded map. diff --git a/Tactical/XML.h b/Tactical/XML.h index 66ad65d4..00174b38 100644 --- a/Tactical/XML.h +++ b/Tactical/XML.h @@ -188,4 +188,4 @@ extern BOOLEAN WriteInArmyCompositionInfo(STR fileName); //Kaiden: Roaming Militia Restricted Sectors List extern BOOLEAN ReadInRoamingInfo(STR filename); -#endif \ No newline at end of file +#endif diff --git a/Tactical/XML_ComboMergeInfo.cpp b/Tactical/XML_ComboMergeInfo.cpp index 31445319..c22e7ee6 100644 --- a/Tactical/XML_ComboMergeInfo.cpp +++ b/Tactical/XML_ComboMergeInfo.cpp @@ -266,4 +266,4 @@ BOOLEAN WriteAttachmentComboMergeStats() FileClose( hFile ); return( TRUE ); -} \ No newline at end of file +} diff --git a/Tactical/XML_EnemyItemChoice.cpp b/Tactical/XML_EnemyItemChoice.cpp index 8f910ba8..2910ee9b 100644 --- a/Tactical/XML_EnemyItemChoice.cpp +++ b/Tactical/XML_EnemyItemChoice.cpp @@ -43,6 +43,7 @@ #include "Debug Control.h" #include "expat.h" #include "XML.h" + #include "Inventory Choosing.h" #endif struct diff --git a/Tactical/XML_EnemyWeaponChoice.cpp b/Tactical/XML_EnemyWeaponChoice.cpp index 5e35aeeb..b2bad67d 100644 --- a/Tactical/XML_EnemyWeaponChoice.cpp +++ b/Tactical/XML_EnemyWeaponChoice.cpp @@ -43,6 +43,7 @@ #include "Debug Control.h" #include "expat.h" #include "XML.h" + #include "Inventory Choosing.h" #endif struct diff --git a/Tactical/XML_SectorLoadscreens.cpp b/Tactical/XML_SectorLoadscreens.cpp index 33303b5b..9d191f38 100644 --- a/Tactical/XML_SectorLoadscreens.cpp +++ b/Tactical/XML_SectorLoadscreens.cpp @@ -42,7 +42,7 @@ #include "Debug Control.h" #include "expat.h" #include "XML.h" - #include "SectorLoadscreens.h" +// #include "SectorLoadscreens.h" #endif struct diff --git a/Tactical/bullets.cpp b/Tactical/bullets.cpp index 34fd48cc..face9039 100644 --- a/Tactical/bullets.cpp +++ b/Tactical/bullets.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Tactical All.h" #else + #include "builddefines.h" #include "math.h" #include #include @@ -25,6 +26,8 @@ #include "random.h" #include "GameSettings.h" #include "FileMan.h" + #include "lighting.h" + #include "Buildings.h" #endif @@ -98,6 +101,9 @@ INT32 CreateBullet( UINT8 ubFirerID, BOOLEAN fFake, UINT16 usFlags,UINT16 fromIt else { pBullet->fReal = TRUE; +// gBullets[ iBullet ].pFirer->bBulletsLeft++; + gTacticalStatus.ubAttackBusyCount++; + DebugAttackBusy( String( "Creating a new bullet for %d. ABC now %d\n", ubFirerID, gTacticalStatus.ubAttackBusyCount) ); } return( iBulletIndex ); @@ -174,28 +180,32 @@ void RemoveBullet( INT32 iBullet ) gBullets[ iBullet ].fToDelete = TRUE; // decrement reference to bullet in the firer - gBullets[ iBullet ].pFirer->bBulletsLeft--; - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Ending bullet, bullets left %d", gBullets[ iBullet ].pFirer->bBulletsLeft ) ); +// gBullets[ iBullet ].pFirer->bBulletsLeft--; +// DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Ending bullet, bullets left %d", gBullets[ iBullet ].pFirer->bBulletsLeft ) ); +// DebugAttackBusy( String( "Deleting a bullet for %d. Total count now %d\n", gBullets[ iBullet].ubFirerID, gBullets[ iBullet ].pFirer->bBulletsLeft) ); + // Nah, just decrement the attack busy count and be done with it + DebugAttackBusy( String( "Deleting a bullet for %d.\n", gBullets[ iBullet].ubFirerID ) ); + ReduceAttackBusyCount( ); - if ( gBullets[ iBullet ].usFlags & ( BULLET_FLAG_KNIFE ) ) + // if ( gBullets[ iBullet ].usFlags & ( BULLET_FLAG_KNIFE ) ) + // { + // Delete ani tile + if ( gBullets[ iBullet ].pAniTile != NULL ) { - // Delete ani tile - if ( gBullets[ iBullet ].pAniTile != NULL ) - { - DeleteAniTile( gBullets[ iBullet ].pAniTile ); - gBullets[ iBullet ].pAniTile = NULL; - } - - // Delete shadow - if ( gBullets[ iBullet ].usFlags & ( BULLET_FLAG_KNIFE ) ) - { - if ( gBullets[ iBullet ].pShadowAniTile != NULL ) - { - DeleteAniTile( gBullets[ iBullet ].pShadowAniTile ); - gBullets[ iBullet ].pShadowAniTile = NULL; - } - } + DeleteAniTile( gBullets[ iBullet ].pAniTile ); + gBullets[ iBullet ].pAniTile = NULL; } + + // Delete shadow + // if ( gBullets[ iBullet ].usFlags & ( BULLET_FLAG_KNIFE ) ) + // { + if ( gBullets[ iBullet ].pShadowAniTile != NULL ) + { + DeleteAniTile( gBullets[ iBullet ].pShadowAniTile ); + gBullets[ iBullet ].pShadowAniTile = NULL; + } +// } +// } } else { @@ -429,15 +439,29 @@ void AddMissileTrail( BULLET *pBullet, FIXEDPT qCurrX, FIXEDPT qCurrY, FIXEDPT q //else if ( pBullet->usFlags & ( BULLET_FLAG_TRACER ) ) else if (fTracer == TRUE) { + INT16 sXPos, sYPos; + strcpy( AniParams.zCachedFile, "TILECACHE\\BULLET_TRACER.STI" ); AniParams.uiFlags |= ANITILE_LIGHT; - /*if ( pBullet->pFirer->bLevel > 0 ) // if firer on roof then + AniParams.sDelay = 10000; // Test this out + + if (!pBullet->pAniTile) + { + pBullet->pAniTile = CreateAnimationTile( &AniParams ); + } + + ConvertGridNoToCenterCellXY( pBullet->sGridNo, &sXPos, &sYPos ); + LightSpritePosition( pBullet->pAniTile->lightSprite, (INT16)(sXPos/CELL_X_SIZE), (INT16)(sYPos/CELL_Y_SIZE)); + + if ( pBullet->pFirer->bLevel > 0 ) // if firer on roof then { if ( FindBuilding(AniParams.sGridNo) != NULL ) // if this spot is still within the building's grid area { - AniParams.uiFlags &= ~ANITILE_LIGHT; + LightSpritePower( pBullet->pAniTile->lightSprite, FALSE); } - }*/ + } + + return; } CreateAnimationTile( &AniParams ); @@ -555,4 +579,4 @@ void DeleteAllBullets( ) RecountBullets( ); -} \ No newline at end of file +} diff --git a/Tactical/fov.cpp b/Tactical/fov.cpp index cdb7b6da..8b36ce18 100644 --- a/Tactical/fov.cpp +++ b/Tactical/fov.cpp @@ -24,6 +24,9 @@ #include "Fog Of War.h" #include "Strategicmap.h" #include "boxing.h" + #include "opplist.h" + #include "lighting.h" + #include "Soldier macros.h" #endif /* view directions */ diff --git a/Tactical/opplist.cpp b/Tactical/opplist.cpp index 60d887b5..d6d15aed 100644 --- a/Tactical/opplist.cpp +++ b/Tactical/opplist.cpp @@ -42,6 +42,13 @@ #include "meanwhile.h" #include "WorldMan.h" #include "SkillCheck.h" + #include "GameSettings.h" + #include "Smell.h" + #include "Game Clock.h" + #include "civ quotes.h" + #include "Sound Control.h" + #include "drugs and alcohol.h" + #include "Interface.h" #endif //rain @@ -460,6 +467,12 @@ void HandleBestSightingPositionInRealtime( void ) return; } + // Also delay until attack busy returns +// if (gTacticalStatus.ubAttackBusyCount > 0) +// { +// return; +// } + if (gubBestToMakeSighting[ 0 ] != NOBODY) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "HBSPIR called and there is someone in the list" ); @@ -598,6 +611,20 @@ void InitSightArrays( void ) gubBestToMakeSighting[ uiLoop ] = NOBODY; } //gfHumanSawSomeoneInRealtime = FALSE; + + // It is assumed that once the sight arrays are (re)initialized, the enemies should all have no + // interrupt points. At least a paranoia check in the HandleSightingInRealtime and HandleSightingInTurnBased + // both make sure no interrupt points remain after they drain the sighting list. + // I do not fully grok the interrupt system, but it IS possible for this function to be called when there are + // still soldiers on the sighting list, which gives them lingering interrupt points. So the best course of + // action is to reset their points. However, I think I'll just do a clean sweep here to make sure I get them all. + for ( uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++ ) + { + if (MercSlots[ uiLoop ] ) + { + MercSlots[ uiLoop ]->bInterruptDuelPts = NO_INTERRUPT; + } + } } void AddToShouldBecomeHostileOrSayQuoteList( UINT8 ubID ) @@ -3717,7 +3744,7 @@ void DebugSoldierPage1( ) gprintf( 400, LINE_HEIGHT * ubLine, L"%d", pSoldier->bHasKeys ); ubLine++; } - else if ( GetMouseMapPos( (INT16 *)&usMapPos ) ) + else if ( GetMouseMapPos( &usMapPos ) ) { SetFont( LARGEFONT1 ); gprintf( 0,0,L"DEBUG LAND PAGE ONE" ); @@ -3876,7 +3903,7 @@ void DebugSoldierPage2( ) gprintf( 150, LINE_HEIGHT * ubLine, L"%s", ShortItemNames[pSoldier->inv[SECONDHANDPOS].usItem] ); ubLine++; - if ( GetMouseMapPos( (INT16 *)&usMapPos ) ) + if ( GetMouseMapPos( &usMapPos ) ) { SetFontShade(LARGEFONT1, FONT_SHADE_GREEN); gprintf( 0, LINE_HEIGHT * ubLine, L"CurrGridNo:"); @@ -3886,7 +3913,7 @@ void DebugSoldierPage2( ) } } - else if ( GetMouseMapPos( (INT16 *)&usMapPos ) ) + else if ( GetMouseMapPos( &usMapPos ) ) { SetFont( LARGEFONT1 ); gprintf( 0,0,L"DEBUG LAND PAGE TWO" ); @@ -4217,7 +4244,7 @@ void DebugSoldierPage3( ) } } - else if ( GetMouseMapPos( (INT16 *)&usMapPos ) ) + else if ( GetMouseMapPos( &usMapPos ) ) { DOOR_STATUS *pDoorStatus; STRUCTURE *pStructure; diff --git a/Tactical/opplist.h b/Tactical/opplist.h index c7b620fb..f12ff4d4 100644 --- a/Tactical/opplist.h +++ b/Tactical/opplist.h @@ -103,6 +103,7 @@ INT16 MaxDistanceVisible( void ); INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir, INT16 sSubjectGridNo, INT8 bLevel, SOLDIERTYPE *pOther ); void ResetLastKnownLocs(SOLDIERTYPE *ptr); void RecalculateOppCntsDueToNoLongerNeutral( SOLDIERTYPE * pSoldier ); +void ReevaluateBestSightingPosition( SOLDIERTYPE * pSoldier, INT8 bInterruptDuelPts ); void InitOpponentKnowledgeSystem(void); diff --git a/Tactical/qarray.h b/Tactical/qarray.h index e1b57e4d..625315d1 100644 --- a/Tactical/qarray.h +++ b/Tactical/qarray.h @@ -1,6 +1,7 @@ #ifndef __Q_ARRAY_H #define __Q_ARRAY_H +#include "soldier profile type.h" extern BOOLEAN QuoteExp_HeadShotOnly[NUM_PROFILES]; extern BOOLEAN QuoteExp_TeamSpecific[NUM_PROFILES]; diff --git a/Tactical/soldier profile type.h b/Tactical/soldier profile type.h index 0fbfe7ef..c28a3fe6 100644 --- a/Tactical/soldier profile type.h +++ b/Tactical/soldier profile type.h @@ -1,6 +1,7 @@ #ifndef __SOLDER_PROFILE_TYPE_H #define __SOLDER_PROFILE_TYPE_H +#include "overhead types.h" #define NUM_PROFILES 170 #define FIRST_RPC 57 diff --git a/TacticalAI/AIList.cpp b/TacticalAI/AIList.cpp index cd230f60..2e60aed0 100644 --- a/TacticalAI/AIList.cpp +++ b/TacticalAI/AIList.cpp @@ -17,6 +17,10 @@ #include "Overhead.h" #include "debug.h" #include "AIInternals.h" + #include "ai.h" + #include "opplist.h" + #include "Interface.h" + #include "Tactical Save.h" #endif #define AI_LIST_SIZE TOTAL_SOLDIERS diff --git a/TacticalAI/AIMain.cpp b/TacticalAI/AIMain.cpp index c85a79b8..0dd2d76f 100644 --- a/TacticalAI/AIMain.cpp +++ b/TacticalAI/AIMain.cpp @@ -1,45 +1,56 @@ #ifdef PRECOMPILEDHEADERS - #include "AI All.h" - #include "sound control.h" - #include "Debug Control.h" +#include "AI All.h" +#include "sound control.h" +#include "Debug Control.h" #else - #include "wcheck.h" - #include "sgp.h" - #include "ai.h" - #include "Isometric Utils.h" - #include "overhead.h" - #include "math.h" - #include "Event Pump.h" - #include "Overhead Types.h" - #include "sys globals.h" - #include "opplist.h" - #include "animation control.h" - #include "font control.h" - #include "interface.h" - #include "screenids.h" - #include "worldman.h" - #include "pathai.h" - #include "points.h" - #include "weapons.h" - #include "items.h" - #include "Handle Items.h" - #include "AIInternals.h" - #include "animation data.h" - #include "los.h" - #include "message.h" - #include "TeamTurns.h" - #include "NPC.h" - #include "Dialogue Control.h" - #include "Soldier Profile.h" - #include "strategicmap.h" - #include "Tactical Save.h" - #include "Soldier Create.h" - #include "Explosion Control.h" - #include "Interactive Tiles.h" - #include "interface dialogue.h" - #include "Vehicles.h" - #include "renderworld.h" - #include "AIList.h" +#include "wcheck.h" +#include "sgp.h" +#include "ai.h" +#include "Isometric Utils.h" +#include "overhead.h" +#include "math.h" +#include "Event Pump.h" +#include "Overhead Types.h" +#include "sys globals.h" +#include "opplist.h" +#include "animation control.h" +#include "font control.h" +#include "interface.h" +#include "screenids.h" +#include "worldman.h" +#include "pathai.h" +#include "points.h" +#include "weapons.h" +#include "items.h" +#include "Handle Items.h" +#include "AIInternals.h" +#include "animation data.h" +#include "los.h" +#include "message.h" +#include "TeamTurns.h" +#include "NPC.h" +#include "Dialogue Control.h" +#include "Soldier Profile.h" +#include "strategicmap.h" +#include "Tactical Save.h" +#include "Soldier Create.h" +#include "Explosion Control.h" +#include "Interactive Tiles.h" +#include "interface dialogue.h" +#include "Vehicles.h" +#include "renderworld.h" +#include "AIList.h" +#include "Soldier macros.h" +#include "Bullets.h" +#include "physics.h" +#include "GameSettings.h" +#include "Debug Control.h" +#include "interface panels.h" +#include "Sound Control.h" +#include "civ quotes.h" +#include "Quests.h" +#include "Campaign Types.h" +#include "Queen Command.h" #endif extern void PauseAITemporarily( void ); @@ -78,15 +89,15 @@ INT8 GameOption[MAXGAMEOPTIONS] = {0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0}; BOOLEAN gfTurnBasedAI; INT8 gbDiff[MAX_DIFF_PARMS][5] = - { - // AI DIFFICULTY SETTING - // WIMPY EASY NORMAL TOUGH ELITE - { -20, -10, 0, 10, 20 }, // DIFF_ENEMY_EQUIP_MOD - { -10, -5, 0, 5, 10 }, // DIFF_ENEMY_TO_HIT_MOD - { -2, -1, 0, 1, 2 }, // DIFF_ENEMY_INTERRUPT_MOD - { 50, 65, 80, 90, 95 }, // DIFF_RADIO_RED_ALERT - { 4, 6, 8, 10, 13 } // DIFF_MAX_COVER_RANGE - }; +{ + // AI DIFFICULTY SETTING + // WIMPY EASY NORMAL TOUGH ELITE + { -20, -10, 0, 10, 20 }, // DIFF_ENEMY_EQUIP_MOD + { -10, -5, 0, 5, 10 }, // DIFF_ENEMY_TO_HIT_MOD + { -2, -1, 0, 1, 2 }, // DIFF_ENEMY_INTERRUPT_MOD + { 50, 65, 80, 90, 95 }, // DIFF_RADIO_RED_ALERT + { 4, 6, 8, 10, 13 } // DIFF_MAX_COVER_RANGE +}; @@ -161,10 +172,10 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) return; } - if ( gfExplosionQueueActive ) - { - return; - } + if ( gfExplosionQueueActive ) + { + return; + } if (pSoldier->uiStatusFlags & SOLDIER_PC) { @@ -184,15 +195,15 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) /* else { - // AI is run on all PCs except the one who is selected - if (pSoldier->uiStatusFlags & SOLDIER_PC ) - { - // if this soldier is "selected" then only let user give orders! - if ((pSoldier->ubID == gusSelectedSoldier) && !(gTacticalStatus.uiFlags & DEMOMODE)) - { - return; - } - } + // AI is run on all PCs except the one who is selected + if (pSoldier->uiStatusFlags & SOLDIER_PC ) + { + // if this soldier is "selected" then only let user give orders! + if ((pSoldier->ubID == gusSelectedSoldier) && !(gTacticalStatus.uiFlags & DEMOMODE)) + { + return; + } + } } */ @@ -216,27 +227,27 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) // why do we let the quote record thing be in here? we're in turnbased the quote record doesn't matter, // we can't act out of turn! if ( !(pSoldier->uiStatusFlags & SOLDIER_UNDERAICONTROL) ) - //if ( !(pSoldier->uiStatusFlags & SOLDIER_UNDERAICONTROL) && (pSoldier->ubQuoteRecord == 0)) + //if ( !(pSoldier->uiStatusFlags & SOLDIER_UNDERAICONTROL) && (pSoldier->ubQuoteRecord == 0)) { return; } if ( pSoldier->bTeam != gTacticalStatus.ubCurrentTeam ) { - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_ERROR, L"Turning off AI flag for %d because trying to act out of turn", pSoldier->ubID ); - #endif +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_ERROR, L"Turning off AI flag for %d because trying to act out of turn", pSoldier->ubID ); +#endif pSoldier->uiStatusFlags &= ~SOLDIER_UNDERAICONTROL; return; } if ( pSoldier->bMoved ) { - #ifdef TESTAICONTROL - if (gfTurnBasedAI) - { - DebugAI( String("Ending turn for %d because set to moved", pSoldier->ubID ) ); - } - #endif +#ifdef TESTAICONTROL + if (gfTurnBasedAI) + { + DebugAI( String("Ending turn for %d because set to moved", pSoldier->ubID ) ); + } +#endif // this guy doesn't get to act! EndAIGuysTurn( pSoldier ); return; @@ -245,7 +256,7 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) } else if ( !(pSoldier->fAIFlags & AI_HANDLE_EVERY_FRAME) ) // if set to handle every frame, ignore delay! { - //#ifndef AI_PROFILING + //#ifndef AI_PROFILING //Time to handle guys in realtime (either combat or not ) if ( !TIMECOUNTERDONE( pSoldier->AICounter, pSoldier->uiAIDelay ) ) { @@ -256,7 +267,7 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) { //Reset counter! RESETTIMECOUNTER( pSoldier->AICounter, pSoldier->uiAIDelay ); - //DebugMsg( TOPIC_JA2, DBG_LEVEL_0, String( "%s waiting %d from %d", pSoldier->name, pSoldier->AICounter, uiCurrTime ) ); + //DebugMsg( TOPIC_JA2, DBG_LEVEL_0, String( "%s waiting %d from %d", pSoldier->name, pSoldier->AICounter, uiCurrTime ) ); } //#endif } @@ -281,12 +292,12 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) if ( ! ( pSoldier->uiStatusFlags & SOLDIER_BOXER ) ) { // do nothing! - #ifdef TESTAICONTROL - if (gfTurnBasedAI) - { - DebugAI( String("Ending turn for %d because not a boxer", pSoldier->ubID ) ); - } - #endif +#ifdef TESTAICONTROL + if (gfTurnBasedAI) + { + DebugAI( String("Ending turn for %d because not a boxer", pSoldier->ubID ) ); + } +#endif EndAIGuysTurn( pSoldier ); return; } @@ -299,13 +310,13 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) { EndMuzzleFlash( pSoldier ); } - #ifdef TESTAICONTROL - if (gfTurnBasedAI) - { - DebugAI( String("Ending turn for %d because bad life/inactive", pSoldier->ubID ) ); - } - #endif - +#ifdef TESTAICONTROL + if (gfTurnBasedAI) + { + DebugAI( String("Ending turn for %d because bad life/inactive", pSoldier->ubID ) ); + } +#endif + EndAIGuysTurn( pSoldier ); return; } @@ -321,12 +332,12 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) else if ( !(pSoldier->fAIFlags & AI_CHECK_SCHEDULE) ) { // don't do anything! - #ifdef TESTAICONTROL - if (gfTurnBasedAI) - { - DebugAI( String("Ending turn for %d because asleep and no scheduled action", pSoldier->ubID ) ); - } - #endif +#ifdef TESTAICONTROL + if (gfTurnBasedAI) + { + DebugAI( String("Ending turn for %d because asleep and no scheduled action", pSoldier->ubID ) ); + } +#endif EndAIGuysTurn( pSoldier ); return; @@ -336,12 +347,12 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) if ( pSoldier->bInSector == FALSE && !(pSoldier->fAIFlags & AI_CHECK_SCHEDULE) ) { // don't do anything! - #ifdef TESTAICONTROL - if (gfTurnBasedAI) - { - DebugAI( String("Ending turn for %d because out of sector and no scheduled action", pSoldier->ubID ) ); - } - #endif +#ifdef TESTAICONTROL + if (gfTurnBasedAI) + { + DebugAI( String("Ending turn for %d because out of sector and no scheduled action", pSoldier->ubID ) ); + } +#endif EndAIGuysTurn( pSoldier ); return; @@ -350,12 +361,12 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) if ( ( (pSoldier->uiStatusFlags & SOLDIER_VEHICLE) && !TANK( pSoldier ) ) || AM_A_ROBOT( pSoldier ) ) { // bail out! - #ifdef TESTAICONTROL - if (gfTurnBasedAI) - { - DebugAI( String("Ending turn for %d because is vehicle or robot", pSoldier->ubID ) ); - } - #endif +#ifdef TESTAICONTROL + if (gfTurnBasedAI) + { + DebugAI( String("Ending turn for %d because is vehicle or robot", pSoldier->ubID ) ); + } +#endif EndAIGuysTurn( pSoldier ); return; @@ -369,12 +380,12 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) EndMuzzleFlash( pSoldier ); } - #ifdef TESTAICONTROL - if (gfTurnBasedAI) - { - DebugAI( String("Ending turn for %d because unconscious", pSoldier->ubID ) ); - } - #endif +#ifdef TESTAICONTROL + if (gfTurnBasedAI) + { + DebugAI( String("Ending turn for %d because unconscious", pSoldier->ubID ) ); + } +#endif // stunned/collapsed! CancelAIAction( pSoldier, FORCE ); @@ -417,7 +428,7 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) { // abort attack! DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String(">>>>>> Attack busy count lobotomized due to new situation for %d", pSoldier->ubID ) ); - gTacticalStatus.ubAttackBusyCount = 0; + //gTacticalStatus.ubAttackBusyCount = 0; fProcessNewSituation = TRUE; } } @@ -463,10 +474,10 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) } #ifdef TESTAI - DebugMsg( TOPIC_JA2AI, DBG_LEVEL_3,String( ".... HANDLING AI FOR %d",pSoldier->ubID)); + DebugMsg( TOPIC_JA2AI, DBG_LEVEL_3,String( ".... HANDLING AI FOR %d",pSoldier->ubID)); #endif -/********* + /********* Start of new overall AI system ********/ @@ -476,8 +487,8 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) { if ( ( GetJA2Clock() - gTacticalStatus.uiTimeSinceMercAIStart ) > ( (UINT32)gGameExternalOptions.gubDeadLockDelay * 1000 ) && !gfUIInDeadlock ) { - // ATE: Display message that deadlock occured... - LiveMessage( "Breaking Deadlock" ); + // ATE: Display message that deadlock occured... + LiveMessage( "Breaking Deadlock" ); #ifdef JA2TESTVERSION // display deadlock message @@ -500,6 +511,13 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) } } + // We STILL do not want to issue new orders while an attack busy situation is going on. This can happen, for example, + // when a gun is fired in real-time and an enemy sees it. Delay the AI until that action is done. + if ( gTacticalStatus.ubAttackBusyCount > 0 ) + { + return; + } + if (pSoldier->bAction == AI_ACTION_NONE) { // being handled so turn off muzzle flash @@ -580,10 +598,10 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) } // reached destination - #ifdef TESTAI - DebugMsg( TOPIC_JA2AI, DBG_LEVEL_0, String("OPPONENT %d REACHES DEST - ACTION DONE",pSoldier->ubID ) ); - #endif - +#ifdef TESTAI + DebugMsg( TOPIC_JA2AI, DBG_LEVEL_0, String("OPPONENT %d REACHES DEST - ACTION DONE",pSoldier->ubID ) ); +#endif + if ( pSoldier->sGridNo == pSoldier->sFinalDestination ) { if ( pSoldier->bAction == AI_ACTION_MOVE_TO_CLIMB ) @@ -598,7 +616,7 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) pSoldier->bAction = AI_ACTION_NONE; pSoldier->bNextAction = AI_ACTION_CLIMB_ROOF; } - + } } @@ -626,9 +644,9 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) else { // OK, we have a move to finish... - #ifdef TESTAI - DebugMsg( TOPIC_JA2AI, DBG_LEVEL_0, String("GONNA TRY TO CONTINUE PATH FOR %d", pSoldier->ubID ) ); - #endif +#ifdef TESTAI + DebugMsg( TOPIC_JA2AI, DBG_LEVEL_0, String("GONNA TRY TO CONTINUE PATH FOR %d", pSoldier->ubID ) ); +#endif SoldierTriesToContinueAlongPath(pSoldier); } @@ -638,7 +656,7 @@ void HandleSoldierAI( SOLDIERTYPE *pSoldier ) } -/********* + /********* End of new overall AI system ********/ @@ -707,10 +725,10 @@ void EndAIGuysTurn( SOLDIERTYPE *pSoldier ) pSoldier->bMoved = TRUE; pSoldier->bBypassToGreen = FALSE; - #ifdef TESTAICONTROL +#ifdef TESTAICONTROL if (!(gTacticalStatus.uiFlags & DEMOMODE)) DebugAI( String("Ending control for %d", pSoldier->ubID ) ); - #endif +#endif // find the next AI guy ubID = RemoveFirstAIListEntry(); @@ -738,9 +756,9 @@ void EndAIDeadlock(void) INT32 cnt; SOLDIERTYPE *pSoldier; INT8 bFound=FALSE; - + // ESCAPE ENEMY'S TURN - + // find enemy with problem and free him up... for (cnt=0,pSoldier=Menptr; cnt < MAXMERCS; cnt++,pSoldier++) { @@ -749,18 +767,18 @@ void EndAIDeadlock(void) if (pSoldier->uiStatusFlags & SOLDIER_UNDERAICONTROL) { CancelAIAction(pSoldier,FORCE); - #ifdef TESTAICONTROL - if (gfTurnBasedAI) - { - DebugAI( String("Ending turn for %d because breaking deadlock", pSoldier->ubID ) ); - } - #endif +#ifdef TESTAICONTROL + if (gfTurnBasedAI) + { + DebugAI( String("Ending turn for %d because breaking deadlock", pSoldier->ubID ) ); + } +#endif DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Number of bullets in the air is %ld", guiNumBullets ) ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Setting attack busy count to 0 from deadlock break" ) ); gTacticalStatus.ubAttackBusyCount = 0; - + EndAIGuysTurn(pSoldier); bFound = TRUE; break; @@ -781,84 +799,84 @@ void StartNPCAI(SOLDIERTYPE *pSoldier) BOOLEAN fInValidSoldier = FALSE; - // Only the host should do this + // Only the host should do this #ifdef NETWORKED - if(!gfAmIHost) - return; + if(!gfAmIHost) + return; #endif - //pSoldier->uiStatusFlags |= SOLDIER_UNDERAICONTROL; - SetSoldierAsUnderAiControl( pSoldier ); + //pSoldier->uiStatusFlags |= SOLDIER_UNDERAICONTROL; + SetSoldierAsUnderAiControl( pSoldier ); - pSoldier->fTurnInProgress = TRUE; + pSoldier->fTurnInProgress = TRUE; - pSoldier->sLastTwoLocations[0] = NOWHERE; - pSoldier->sLastTwoLocations[1] = NOWHERE; + pSoldier->sLastTwoLocations[0] = NOWHERE; + pSoldier->sLastTwoLocations[1] = NOWHERE; - RefreshAI(pSoldier); + RefreshAI(pSoldier); #ifdef TESTAICONTROL - if (!(gTacticalStatus.uiFlags & DEMOMODE)) - DebugAI( String("Giving control to %d", pSoldier->ubID ) ); + if (!(gTacticalStatus.uiFlags & DEMOMODE)) + DebugAI( String("Giving control to %d", pSoldier->ubID ) ); #endif - gTacticalStatus.uiTimeSinceMercAIStart = GetJA2Clock(); + gTacticalStatus.uiTimeSinceMercAIStart = GetJA2Clock(); - DebugMsg( TOPIC_JA2AI, DBG_LEVEL_3 , "Clock set" ); + DebugMsg( TOPIC_JA2AI, DBG_LEVEL_3 , "Clock set" ); - // important: if "fPausedAnimation" is TRUE, then we have to turn it off else - // HandleSoldierAI() will not be called! + // important: if "fPausedAnimation" is TRUE, then we have to turn it off else + // HandleSoldierAI() will not be called! - if( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) + if( pSoldier->uiStatusFlags & SOLDIER_VEHICLE ) + { + if ( GetNumberInVehicle( pSoldier->bVehicleID ) == 0 ) { - if ( GetNumberInVehicle( pSoldier->bVehicleID ) == 0 ) + fInValidSoldier = TRUE; + } + } + + // Locate to soldier + // If we are not in an interrupt situation! + if ( (( gTacticalStatus.uiFlags & TURNBASED ) && ( gTacticalStatus.uiFlags & INCOMBAT )) && gubOutOfTurnPersons == 0 ) + { + if( ( ( pSoldier->bVisible != -1 && pSoldier->bLife) || ( gTacticalStatus.uiFlags & SHOW_ALL_MERCS ) ) && ( fInValidSoldier == FALSE ) ) + { + // If we are on a roof, set flag for rendering... + if ( pSoldier->bLevel != 0 && ( gTacticalStatus.uiFlags & INCOMBAT ) ) { - fInValidSoldier = TRUE; + gTacticalStatus.uiFlags |= SHOW_ALL_ROOFS; + SetRenderFlags( RENDER_FLAG_FULL ); + InvalidateWorldRedundency( ); } + + + //ATE: Changed to show locator + + // Skip locator for green friendly militia + if ( !(pSoldier->bTeam == MILITIA_TEAM && pSoldier->bSide == 0 && pSoldier->bAlertStatus == STATUS_GREEN) ) + { + LocateSoldier( pSoldier->ubID, SETLOCATORFAST ); + } + + // try commenting this out altogether + /* + // so long as he's not a neutral civ or a militia friendly to the player + if ( !(pSoldier->bNeutral || (pSoldier->bTeam == MILITIA_TEAM && pSoldier->bSide == 0) ) ) + { + PauseAITemporarily(); + } + */ } - // Locate to soldier - // If we are not in an interrupt situation! - if ( (( gTacticalStatus.uiFlags & TURNBASED ) && ( gTacticalStatus.uiFlags & INCOMBAT )) && gubOutOfTurnPersons == 0 ) - { - if( ( ( pSoldier->bVisible != -1 && pSoldier->bLife) || ( gTacticalStatus.uiFlags & SHOW_ALL_MERCS ) ) && ( fInValidSoldier == FALSE ) ) - { - // If we are on a roof, set flag for rendering... - if ( pSoldier->bLevel != 0 && ( gTacticalStatus.uiFlags & INCOMBAT ) ) - { - gTacticalStatus.uiFlags |= SHOW_ALL_ROOFS; - SetRenderFlags( RENDER_FLAG_FULL ); - InvalidateWorldRedundency( ); - } - + UpdateEnemyUIBar( ); - //ATE: Changed to show locator + } - // Skip locator for green friendly militia - if ( !(pSoldier->bTeam == MILITIA_TEAM && pSoldier->bSide == 0 && pSoldier->bAlertStatus == STATUS_GREEN) ) - { - LocateSoldier( pSoldier->ubID, SETLOCATORFAST ); - } - - // try commenting this out altogether - /* - // so long as he's not a neutral civ or a militia friendly to the player - if ( !(pSoldier->bNeutral || (pSoldier->bTeam == MILITIA_TEAM && pSoldier->bSide == 0) ) ) - { - PauseAITemporarily(); - } - */ - } - - UpdateEnemyUIBar( ); - - } - - // Remove deadlock message - DebugMsg( TOPIC_JA2AI, DBG_LEVEL_3 , "About to remove deadlock message" ); - EndDeadlockMsg( ); - DebugMsg( TOPIC_JA2AI, DBG_LEVEL_3 , "About to decide alert status" ); - DecideAlertStatus( pSoldier ); - DebugMsg( TOPIC_JA2AI, DBG_LEVEL_3 , "Alert status decided - startnpcai done" ); + // Remove deadlock message + DebugMsg( TOPIC_JA2AI, DBG_LEVEL_3 , "About to remove deadlock message" ); + EndDeadlockMsg( ); + DebugMsg( TOPIC_JA2AI, DBG_LEVEL_3 , "About to decide alert status" ); + DecideAlertStatus( pSoldier ); + DebugMsg( TOPIC_JA2AI, DBG_LEVEL_3 , "Alert status decided - startnpcai done" ); } @@ -907,7 +925,7 @@ INT16 FindAdjacentSpotBeside(SOLDIERTYPE *pSoldier, INT16 sGridno) } } - + } return(sCheapestDest); @@ -944,7 +962,7 @@ UINT8 GetMostThreateningOpponent( SOLDIERTYPE *pSoldier ) } if (pSoldier->bOppList[pTargetSoldier->ubID] != SEEN_CURRENTLY) - continue; + continue; // Special stuff for Carmen the bounty hunter if (pSoldier->bAttitude == ATTACKSLAYONLY && pTargetSoldier->ubProfile != 64) @@ -958,7 +976,7 @@ UINT8 GetMostThreateningOpponent( SOLDIERTYPE *pSoldier ) iMinThreat = iThreatVal; ubTargetSoldier = pTargetSoldier->ubID; } - + } return( ubTargetSoldier ); @@ -1010,47 +1028,47 @@ void FreeUpNPCFromAttacking(UINT8 ubID) ActionDone(pSoldier); pSoldier->bNeedToLook = TRUE; -/* + /* if (pSoldier->bActionInProgress) { -#ifdef TESTAI - DebugMsg( TOPIC_JA2AI, DBG_LEVEL_0, String( "FreeUpNPCFromAttacking for %d", pSoldier->ubID ) ); -#endif - if (pSoldier->bAction == AI_ACTION_FIRE_GUN) - { - if (pSoldier->bDoBurst) - { - if (pSoldier->bBulletsLeft == 0) - { - // now find the target and have them say "close call" quote if - // applicable - pTarget = SimpleFindSoldier( pSoldier->sTargetGridNo, pSoldier->bTargetLevel ); - if (pTarget && pTarget->bTeam == OUR_TEAM && pTarget->fCloseCall && pTarget->bShock == 0) - { - // say close call quote! - TacticalCharacterDialogue( pTarget, QUOTE_CLOSE_CALL ); - pTarget->fCloseCall = FALSE; - } - ActionDone(pSoldier); - pSoldier->bDoBurst = FALSE; - } - } - else - { - pTarget = SimpleFindSoldier( pSoldier->sTargetGridNo, pSoldier->bTargetLevel ); - if (pTarget && pTarget->bTeam == OUR_TEAM && pTarget->fCloseCall && pTarget->bShock == 0) - { - // say close call quote! - TacticalCharacterDialogue( pTarget, QUOTE_CLOSE_CALL ); - pTarget->fCloseCall = FALSE; - } - ActionDone(pSoldier); - } - } - else if ((pSoldier->bAction == AI_ACTION_TOSS_PROJECTILE) || (pSoldier->bAction == AI_ACTION_KNIFE_STAB)) - { - ActionDone(pSoldier); - } + #ifdef TESTAI + DebugMsg( TOPIC_JA2AI, DBG_LEVEL_0, String( "FreeUpNPCFromAttacking for %d", pSoldier->ubID ) ); + #endif + if (pSoldier->bAction == AI_ACTION_FIRE_GUN) + { + if (pSoldier->bDoBurst) + { + if (pSoldier->bBulletsLeft == 0) + { + // now find the target and have them say "close call" quote if + // applicable + pTarget = SimpleFindSoldier( pSoldier->sTargetGridNo, pSoldier->bTargetLevel ); + if (pTarget && pTarget->bTeam == OUR_TEAM && pTarget->fCloseCall && pTarget->bShock == 0) + { + // say close call quote! + TacticalCharacterDialogue( pTarget, QUOTE_CLOSE_CALL ); + pTarget->fCloseCall = FALSE; + } + ActionDone(pSoldier); + pSoldier->bDoBurst = FALSE; + } + } + else + { + pTarget = SimpleFindSoldier( pSoldier->sTargetGridNo, pSoldier->bTargetLevel ); + if (pTarget && pTarget->bTeam == OUR_TEAM && pTarget->fCloseCall && pTarget->bShock == 0) + { + // say close call quote! + TacticalCharacterDialogue( pTarget, QUOTE_CLOSE_CALL ); + pTarget->fCloseCall = FALSE; + } + ActionDone(pSoldier); + } + } + else if ((pSoldier->bAction == AI_ACTION_TOSS_PROJECTILE) || (pSoldier->bAction == AI_ACTION_KNIFE_STAB)) + { + ActionDone(pSoldier); + } } // DO WE NEED THIS??? @@ -1077,24 +1095,24 @@ void FreeUpNPCFromLoweringGun( SOLDIERTYPE *pSoldier ) void FreeUpNPCFromTurning(SOLDIERTYPE *pSoldier, INT8 bLook) { - + // if NPC is in the process of changing facing, mark him as being done! - if ((pSoldier->bAction == AI_ACTION_CHANGE_FACING) && pSoldier->bActionInProgress) - { + if ((pSoldier->bAction == AI_ACTION_CHANGE_FACING) && pSoldier->bActionInProgress) + { #ifdef TESTAI DebugMsg( TOPIC_JA2AI, DBG_LEVEL_3, - String("FREEUPNPCFROMTURNING: our action %d, desdir %d dir %d",pSoldier->bAction,pSoldier->bDesiredDirection,pSoldier->bDirection) ); + String("FREEUPNPCFROMTURNING: our action %d, desdir %d dir %d",pSoldier->bAction,pSoldier->bDesiredDirection,pSoldier->bDirection) ); #endif - ActionDone(pSoldier); + ActionDone(pSoldier); - if ( bLook ) - { - //HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO); // no interrupt possible - } + if ( bLook ) + { + //HandleSight(pSoldier,SIGHT_LOOK | SIGHT_RADIO); // no interrupt possible + } - } + } } @@ -1102,7 +1120,7 @@ void FreeUpNPCFromStanceChange(SOLDIERTYPE *pSoldier ) { // are we/were we doing something? if (pSoldier->bActionInProgress) - { + { // check and see if we were changing stance if (pSoldier->bAction == AI_ACTION_CHANGE_STANCE || pSoldier->bAction == AI_ACTION_COWER || pSoldier->bAction == AI_ACTION_STOP_COWERING) { @@ -1120,7 +1138,7 @@ void FreeUpNPCFromRoofClimb(SOLDIERTYPE *pSoldier ) { // are we/were we doing something? if (pSoldier->bActionInProgress) - { + { // check and see if we were climbing if (pSoldier->bAction == AI_ACTION_CLIMB_ROOF) { @@ -1242,20 +1260,20 @@ void NPCDoesAct(SOLDIERTYPE *pSoldier) { DisplayHiddenTurnbased( pSoldier ); } - + if (gfHiddenInterrupt) { DisplayHiddenInterrupt( pSoldier ); } - //StartInterruptVisually(pSoldier->ubID); - // *** IAN deleted lots of interrupt related code here to simplify JA2 development + //StartInterruptVisually(pSoldier->ubID); + // *** IAN deleted lots of interrupt related code here to simplify JA2 development - // CJC Feb 18 99: make sure that soldier is not in the middle of a turn due to visual crap to make enemies - // face and point their guns at us - if ( pSoldier->bDesiredDirection != pSoldier->bDirection ) - { - pSoldier->bDesiredDirection = pSoldier->bDirection; - } + // CJC Feb 18 99: make sure that soldier is not in the middle of a turn due to visual crap to make enemies + // face and point their guns at us + if ( pSoldier->bDesiredDirection != pSoldier->bDirection ) + { + pSoldier->bDesiredDirection = pSoldier->bDirection; + } DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"NPCDoesAct done"); } @@ -1267,12 +1285,12 @@ void NPCDoesNothing(SOLDIERTYPE *pSoldier) // NPC, for whatever reason, did/could not start an action, so end his turn //pSoldier->moved = TRUE; - #ifdef TESTAICONTROL - if (gfTurnBasedAI) - { - DebugAI( String("Ending turn for %d because doing no-action", pSoldier->ubID ) ); - } - #endif +#ifdef TESTAICONTROL + if (gfTurnBasedAI) + { + DebugAI( String("Ending turn for %d because doing no-action", pSoldier->ubID ) ); + } +#endif EndAIGuysTurn(pSoldier); @@ -1318,126 +1336,126 @@ void CancelAIAction(SOLDIERTYPE *pSoldier, UINT8 ubForce) /* void ActionTimeoutExceeded(SOLDIERTYPE *pSoldier, UCHAR alreadyFreedUp) { - int cnt; - UCHAR attackAction = FALSE; +int cnt; +UCHAR attackAction = FALSE; #ifdef BETAVERSION - if (ConvertedMultiSave) - { - // re-start real-time NPC action timer - EnemyTimedOut = FALSE; - EnemyTimerCnt = ENEMYWAITTOLERANCE; - return; - } +if (ConvertedMultiSave) +{ +// re-start real-time NPC action timer +EnemyTimedOut = FALSE; +EnemyTimerCnt = ENEMYWAITTOLERANCE; +return; +} #endif - // check if it's a problem with a offensive combat action - if ((pSoldier->bAction == AI_ACTION_FIRE_GUN) || - (pSoldier->bAction == AI_ACTION_TOSS_PROJECTILE) || - (pSoldier->bAction == AI_ACTION_KNIFE_STAB)) - { - // THESE ARE LESS SERIOUS, SINCE THEY LIKELY WON'T REPEAT THEMSELVES - attackAction = TRUE; - } - // OTHERS ARE VERY SERIOUS, SINCE THEY ARE LIKELY TO REPEAT THEMSELVES +// check if it's a problem with a offensive combat action +if ((pSoldier->bAction == AI_ACTION_FIRE_GUN) || +(pSoldier->bAction == AI_ACTION_TOSS_PROJECTILE) || +(pSoldier->bAction == AI_ACTION_KNIFE_STAB)) +{ +// THESE ARE LESS SERIOUS, SINCE THEY LIKELY WON'T REPEAT THEMSELVES +attackAction = TRUE; +} +// OTHERS ARE VERY SERIOUS, SINCE THEY ARE LIKELY TO REPEAT THEMSELVES #ifdef BETAVERSION - sprintf(tempstr,"ActionInProgress - ERROR: %s's timeout limit exceeded. Action #%d (%d)", - pSoldier->name,pSoldier->bAction,pSoldier->usActionData); +sprintf(tempstr,"ActionInProgress - ERROR: %s's timeout limit exceeded. Action #%d (%d)", +pSoldier->name,pSoldier->bAction,pSoldier->usActionData); #ifdef RECORDNET - fprintf(NetDebugFile,"\n%s\n\n",tempstr); +fprintf(NetDebugFile,"\n%s\n\n",tempstr); #endif - PopMessage(tempstr); - SaveGame(ERROR_SAVE); +PopMessage(tempstr); +SaveGame(ERROR_SAVE); #endif #ifdef TESTVERSION - PopMessage("FULL SOLDIER INFORMATION DUMP COMING UP, BRACE THYSELF!"); - DumpSoldierInfo(pSoldier); +PopMessage("FULL SOLDIER INFORMATION DUMP COMING UP, BRACE THYSELF!"); +DumpSoldierInfo(pSoldier); #endif - // re-start real-time NPC action timer - EnemyTimedOut = FALSE; - EnemyTimerCnt = ENEMYWAITTOLERANCE; +// re-start real-time NPC action timer +EnemyTimedOut = FALSE; +EnemyTimerCnt = ENEMYWAITTOLERANCE; - if (attackAction) - { +if (attackAction) +{ #ifdef BETAVERSION - NameMessage(pSoldier,"will now be freed up from attacking...",2000); +NameMessage(pSoldier,"will now be freed up from attacking...",2000); #endif - // free up ONLY players from whom we haven't received an AI_ACTION_DONE yet - // we can all agree the action is DONE and we can continue... - // (otherwise they'll be calling FreeUp... twice and get REAL screwed up) - NetSend.msgType = NET_FREE_UP_ATTACK; - NetSend.ubID = pSoldier->ubID; +// free up ONLY players from whom we haven't received an AI_ACTION_DONE yet +// we can all agree the action is DONE and we can continue... +// (otherwise they'll be calling FreeUp... twice and get REAL screwed up) +NetSend.msgType = NET_FREE_UP_ATTACK; +NetSend.ubID = pSoldier->ubID; - for (cnt = 0; cnt < MAXPLAYERS; cnt++) - { - if ((cnt != Net.pnum) && Net.player[cnt].playerActive && - (Net.player[cnt].actionDone != pSoldier->ubID)) - SendNetData(cnt); - } +for (cnt = 0; cnt < MAXPLAYERS; cnt++) +{ +if ((cnt != Net.pnum) && Net.player[cnt].playerActive && +(Net.player[cnt].actionDone != pSoldier->ubID)) +SendNetData(cnt); +} - if (!alreadyFreedUp) - FreeUpManFromAttacking(pSoldier->ubID,COMMUNICATE); - } - else if (pSoldier->bAction == AI_ACTION_CHANGE_FACING) - { +if (!alreadyFreedUp) +FreeUpManFromAttacking(pSoldier->ubID,COMMUNICATE); +} +else if (pSoldier->bAction == AI_ACTION_CHANGE_FACING) +{ #ifdef BETAVERSION - NameMessage(pSoldier,"will now be freed up from turning...",2000); +NameMessage(pSoldier,"will now be freed up from turning...",2000); #endif - // force him to face in the right direction (as long as it's legal) - if ((pSoldier->bDesiredDirection >= 1) && (pSoldier->bDesiredDirection <= 8)) - pSoldier->bDirection = pSoldier->bDesiredDirection; - else - pSoldier->bDesiredDirection = pSoldier->bDirection; +// force him to face in the right direction (as long as it's legal) +if ((pSoldier->bDesiredDirection >= 1) && (pSoldier->bDesiredDirection <= 8)) +pSoldier->bDirection = pSoldier->bDesiredDirection; +else +pSoldier->bDesiredDirection = pSoldier->bDirection; - // free up ONLY players from whom we haven't received an AI_ACTION_DONE yet - // we can all agree the action is DONE and we can continue... - // (otherwise they'll be calling FreeUp... twice and get REAL screwed up) - NetSend.msgType = NET_FREE_UP_TURN; - NetSend.ubID = pSoldier->ubID; - NetSend.misc_UCHAR = pSoldier->bDirection; - NetSend.answer = pSoldier->bDesiredDirection; +// free up ONLY players from whom we haven't received an AI_ACTION_DONE yet +// we can all agree the action is DONE and we can continue... +// (otherwise they'll be calling FreeUp... twice and get REAL screwed up) +NetSend.msgType = NET_FREE_UP_TURN; +NetSend.ubID = pSoldier->ubID; +NetSend.misc_UCHAR = pSoldier->bDirection; +NetSend.answer = pSoldier->bDesiredDirection; - for (cnt = 0; cnt < MAXPLAYERS; cnt++) - { - if ((cnt != Net.pnum) && Net.player[cnt].playerActive && - (Net.player[cnt].actionDone != pSoldier->ubID)) - SendNetData(cnt); - } +for (cnt = 0; cnt < MAXPLAYERS; cnt++) +{ +if ((cnt != Net.pnum) && Net.player[cnt].playerActive && +(Net.player[cnt].actionDone != pSoldier->ubID)) +SendNetData(cnt); +} - if (!alreadyFreedUp) - // this calls FreeUpManFromTurning() - NowFacingRightWay(pSoldier,COMMUNICATE); - } - else - { +if (!alreadyFreedUp) +// this calls FreeUpManFromTurning() +NowFacingRightWay(pSoldier,COMMUNICATE); +} +else +{ #ifdef BETAVERSION - NameMessage(pSoldier,"is having the remainder of his turn canceled...",1000); +NameMessage(pSoldier,"is having the remainder of his turn canceled...",1000); #endif - // cancel the remainder of the offender's turn as a penalty! - pSoldier->bActionPoints = 0; - NPCDoesNothing(pSoldier); - } +// cancel the remainder of the offender's turn as a penalty! +pSoldier->bActionPoints = 0; +NPCDoesNothing(pSoldier); +} - // cancel whatever the current action is, force this even for escorted NPCs - CancelAIAction(pSoldier,FORCE); +// cancel whatever the current action is, force this even for escorted NPCs +CancelAIAction(pSoldier,FORCE); - // reset the timeout counter for next time - pSoldier->bActionTimeout = 0; +// reset the timeout counter for next time +pSoldier->bActionTimeout = 0; } */ @@ -1446,29 +1464,29 @@ void ActionTimeoutExceeded(SOLDIERTYPE *pSoldier, UCHAR alreadyFreedUp) INT16 ActionInProgress(SOLDIERTYPE *pSoldier) { - // if NPC has a desired destination, but isn't currently going there - if ((pSoldier->sFinalDestination != NOWHERE) && (pSoldier->sDestination != pSoldier->sFinalDestination)) - { - // return success (TRUE) if we successfully resume the movement - return(TryToResumeMovement(pSoldier,pSoldier->sFinalDestination)); - } + // if NPC has a desired destination, but isn't currently going there + if ((pSoldier->sFinalDestination != NOWHERE) && (pSoldier->sDestination != pSoldier->sFinalDestination)) + { + // return success (TRUE) if we successfully resume the movement + return(TryToResumeMovement(pSoldier,pSoldier->sFinalDestination)); + } - // this here should never happen, but it seems to (turns sometimes hang!) - if ((pSoldier->bAction == AI_ACTION_CHANGE_FACING) && (pSoldier->bDesiredDirection != pSoldier->usActionData)) - { + // this here should never happen, but it seems to (turns sometimes hang!) + if ((pSoldier->bAction == AI_ACTION_CHANGE_FACING) && (pSoldier->bDesiredDirection != pSoldier->usActionData)) + { #ifdef TESTVERSION - PopMessage("ActionInProgress: WARNING - CONTINUING FACING CHANGE..."); + PopMessage("ActionInProgress: WARNING - CONTINUING FACING CHANGE..."); #endif - // don't try to pay any more APs for this, it was paid for once already! - pSoldier->bDesiredDirection = (INT8) pSoldier->usActionData; // turn to face direction in actionData - return(TRUE); - } + // don't try to pay any more APs for this, it was paid for once already! + pSoldier->bDesiredDirection = (INT8) pSoldier->usActionData; // turn to face direction in actionData + return(TRUE); + } - // needs more time to complete action - return(TRUE); + // needs more time to complete action + return(TRUE); } @@ -1478,77 +1496,77 @@ INT16 ActionInProgress(SOLDIERTYPE *pSoldier) /* void RestoreMarkedMines() { - int gridno; +int gridno; - // all tiles marked with the special NPC mine cost value must be restored - for (gridno = 0; gridno < GRIDSIZE; gridno++) - { - if (GridCost[gridno] == NPCMINECOST) - { - GridCost[gridno] = BackupGridCost[gridno]; +// all tiles marked with the special NPC mine cost value must be restored +for (gridno = 0; gridno < GRIDSIZE; gridno++) +{ +if (GridCost[gridno] == NPCMINECOST) +{ +GridCost[gridno] = BackupGridCost[gridno]; #ifdef TESTMINEMARKING - fprintf(NetDebugFile,"\tRestoring marked mine at gridno %d back to gridCost %d\n",gridno,BackupGridCost[gridno]); +fprintf(NetDebugFile,"\tRestoring marked mine at gridno %d back to gridCost %d\n",gridno,BackupGridCost[gridno]); #endif - } - } +} +} - MarkedNPCMines = FALSE; +MarkedNPCMines = FALSE; } void MarkDetectableMines(SOLDIERTYPE *pSoldier) { - int gridno,detectLevel; - GRIDINFO *gpSoldier; +int gridno,detectLevel; +GRIDINFO *gpSoldier; - // this should happen, means we missed a clean-up cycle last time! - if (MarkedNPCMines) - { +// this should happen, means we missed a clean-up cycle last time! +if (MarkedNPCMines) +{ #ifdef BETAVERSION - sprintf(tempstr,"MarkDetectableMines: ERROR - mines still marked! Guynum %d",pSoldier->ubID); +sprintf(tempstr,"MarkDetectableMines: ERROR - mines still marked! Guynum %d",pSoldier->ubID); #ifdef RECORDNET - fprintf(NetDebugFile,"\n\t%s\n\n",tempstr); +fprintf(NetDebugFile,"\n\t%s\n\n",tempstr); #endif - PopMessage(tempstr); +PopMessage(tempstr); #endif - RestoreMarkedMines(); - } +RestoreMarkedMines(); +} - // make a backup of the current gridcosts - memcpy(BackupGridCost,GridCost,sizeof(GridCost)); +// make a backup of the current gridcosts +memcpy(BackupGridCost,GridCost,sizeof(GridCost)); - // calculate what "level" of mines we are able to detect - detectLevel = CalcMineDetectLevel(pSoldier); +// calculate what "level" of mines we are able to detect +detectLevel = CalcMineDetectLevel(pSoldier); - // check every tile, looking for BURIED mines only - for (gridno = 0,gpSoldier = &Grid[0]; gridno < GRIDSIZE; gridno++,gpSoldier++) - { - // if there's a valid object there, and it is still "buried" - if ((gpSoldier->object < 255) && - (ObjList[gpSoldier->object].visible == BURIED) && - (ObjList[gpSoldier->object].item == MINE)) - { - // are we bright enough to detect it (should we get there) ? - if (detectLevel >= ObjList[gpSoldier->object].trap) - { - // bingo! Mark it as "unpassable" for the purposes of the path AI - GridCost[gridno] = NPCMINECOST; - MarkedNPCMines = TRUE; +// check every tile, looking for BURIED mines only +for (gridno = 0,gpSoldier = &Grid[0]; gridno < GRIDSIZE; gridno++,gpSoldier++) +{ +// if there's a valid object there, and it is still "buried" +if ((gpSoldier->object < 255) && +(ObjList[gpSoldier->object].visible == BURIED) && +(ObjList[gpSoldier->object].item == MINE)) +{ +// are we bright enough to detect it (should we get there) ? +if (detectLevel >= ObjList[gpSoldier->object].trap) +{ +// bingo! Mark it as "unpassable" for the purposes of the path AI +GridCost[gridno] = NPCMINECOST; +MarkedNPCMines = TRUE; #ifdef TESTMINEMARKING - fprintf(NetDebugFile,"\tNPC %d, dtctLvl %d, marking mine at gridno %d, gridCost was %d\n",pSoldier->ubID,detectLevel,gridno,BackupGridCost[gridno]); +fprintf(NetDebugFile,"\tNPC %d, dtctLvl %d, marking mine at gridno %d, gridCost was %d\n",pSoldier->ubID,detectLevel,gridno,BackupGridCost[gridno]); #endif - } - } - } +} +} +} } */ @@ -1560,108 +1578,108 @@ void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier) { -/* - if (Status.gamePaused) - { -#ifdef DEBUGBUSY - DebugAI("HandleManAI - Skipping %d, the game is paused\n",pSoldier->ubID); -#endif + /* + if (Status.gamePaused) + { + #ifdef DEBUGBUSY + DebugAI("HandleManAI - Skipping %d, the game is paused\n",pSoldier->ubID); + #endif - return; - } -// + return; + } + // - // If man is inactive/at base/dead/unconscious - if (!pSoldier->bActive || !pSoldier->bInSector || (pSoldier->bLife < OKLIFE)) - { -#ifdef DEBUGDECISIONS - AINumMessage("HandleManAI - Unavailable man, skipping guy#",pSoldier->ubID); -#endif + // If man is inactive/at base/dead/unconscious + if (!pSoldier->bActive || !pSoldier->bInSector || (pSoldier->bLife < OKLIFE)) + { + #ifdef DEBUGDECISIONS + AINumMessage("HandleManAI - Unavailable man, skipping guy#",pSoldier->ubID); + #endif - NPCDoesNothing(pSoldier); - return; - } + NPCDoesNothing(pSoldier); + return; + } - if (PTR_CIVILIAN && pSoldier->service && - (pSoldier->bNeutral || MedicsMissionIsEscort(pSoldier))) - { -#ifdef DEBUGDECISIONS - AINumMessage("HandleManAI - Civilian is being serviced, skipping guy#",pSoldier->ubID); -#endif + if (PTR_CIVILIAN && pSoldier->service && + (pSoldier->bNeutral || MedicsMissionIsEscort(pSoldier))) + { + #ifdef DEBUGDECISIONS + AINumMessage("HandleManAI - Civilian is being serviced, skipping guy#",pSoldier->ubID); + #endif - NPCDoesNothing(pSoldier); - return; - } -*/ + NPCDoesNothing(pSoldier); + return; + } + */ - /* - anim = pSoldier->anitype[pSoldier->anim]; + /* + anim = pSoldier->anitype[pSoldier->anim]; - // If man is down on the ground - if (anim < BREATHING) - { - // if he lacks the breath, or APs to get up this turn (life checked above) - // OR... (new June 13/96 Ian) he's getting first aid... - if ((pSoldier->bBreath < OKBREATH) || (pSoldier->bActionPoints < (AP_GET_UP + AP_ROLL_OVER)) - || pSoldier->service) - { -#ifdef RECORDNET - fprintf(NetDebugFile,"\tAI: %d can't get up (breath %d, AP %d), ending his turn\n", - pSoldier->ubID,pSoldier->bBreath,pSoldier->bActionPoints); -#endif -#ifdef DEBUGDECISIONS - AINumMessage("HandleManAI - CAN'T GET UP, skipping guy #",pSoldier->ubID); -#endif + // If man is down on the ground + if (anim < BREATHING) + { + // if he lacks the breath, or APs to get up this turn (life checked above) + // OR... (new June 13/96 Ian) he's getting first aid... + if ((pSoldier->bBreath < OKBREATH) || (pSoldier->bActionPoints < (AP_GET_UP + AP_ROLL_OVER)) + || pSoldier->service) + { + #ifdef RECORDNET + fprintf(NetDebugFile,"\tAI: %d can't get up (breath %d, AP %d), ending his turn\n", + pSoldier->ubID,pSoldier->bBreath,pSoldier->bActionPoints); + #endif + #ifdef DEBUGDECISIONS + AINumMessage("HandleManAI - CAN'T GET UP, skipping guy #",pSoldier->ubID); + #endif - NPCDoesNothing(pSoldier); - return; - } - else - { - // wait until he gets up first, only then worry about deciding his AI + NPCDoesNothing(pSoldier); + return; + } + else + { + // wait until he gets up first, only then worry about deciding his AI -#ifdef RECORDNET - fprintf(NetDebugFile,"\tAI: waiting for %d to GET UP (breath %d, AP %d)\n", - pSoldier->ubID,pSoldier->bBreath,pSoldier->bActionPoints); -#endif + #ifdef RECORDNET + fprintf(NetDebugFile,"\tAI: waiting for %d to GET UP (breath %d, AP %d)\n", + pSoldier->ubID,pSoldier->bBreath,pSoldier->bActionPoints); + #endif -#ifdef DEBUGBUSY - AINumMessage("HandleManAI - About to get up, skipping guy#",pSoldier->ubID); -#endif + #ifdef DEBUGBUSY + AINumMessage("HandleManAI - About to get up, skipping guy#",pSoldier->ubID); + #endif - return; - } - } + return; + } + } - // if NPC's has been forced to stop by an opponent's interrupt or similar - if (pSoldier->forcedToStop) - { -#ifdef DEBUGBUSY - AINumMessage("HandleManAI - Forced to stop, skipping guy #",pSoldier->ubID); -#endif + // if NPC's has been forced to stop by an opponent's interrupt or similar + if (pSoldier->forcedToStop) + { + #ifdef DEBUGBUSY + AINumMessage("HandleManAI - Forced to stop, skipping guy #",pSoldier->ubID); + #endif - return; - } + return; + } - // if we are still in the midst in an uninterruptable animation - if (!AnimControl[anim].interruptable) - { -#ifdef DEBUGBUSY - AINumMessage("HandleManAI - uninterruptable animation, skipping guy #",pSoldier->ubID); -#endif + // if we are still in the midst in an uninterruptable animation + if (!AnimControl[anim].interruptable) + { + #ifdef DEBUGBUSY + AINumMessage("HandleManAI - uninterruptable animation, skipping guy #",pSoldier->ubID); + #endif - return; // wait a while, let the animation finish first - } + return; // wait a while, let the animation finish first + } -*/ + */ // yikes, this shouldn't occur! we should be trying to finish our move! // pSoldier->fNoAPToFinishMove = FALSE; - // unless in mid-move, get an up-to-date alert status for this guy + // unless in mid-move, get an up-to-date alert status for this guy if (pSoldier->bStopped) { // if active team is waiting for oppChanceToDecide, that means we have NOT @@ -1670,81 +1688,81 @@ void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier) ??? if (gTacticalStatus.team[Net.turnActive].allowOppChanceToDecide) { - // if mines are still marked (this could happen if we also control the - // active team that's potentially BEING interrupted), unmark them - //RestoreMarkedMines(); + // if mines are still marked (this could happen if we also control the + // active team that's potentially BEING interrupted), unmark them + //RestoreMarkedMines(); - RefreshAI(pSoldier); + RefreshAI(pSoldier); } else { - DecideAlertStatus(pSoldier); + DecideAlertStatus(pSoldier); } */ - } + } -/* + /* // move this clause outside of the function... if (pSoldier->bNewSituation) - // don't force, don't want escorted mercs reacting to new opponents, etc. - CancelAIAction(pSoldier,DONTFORCE); + // don't force, don't want escorted mercs reacting to new opponents, etc. + CancelAIAction(pSoldier,DONTFORCE); -*/ + */ - /* - if (!pSoldier->stopped) - { -#ifdef DEBUGBUSY - AINumMessage("HandleManAI - Moving, skipping guy#",pSoldier->ubID); -#endif + /* + if (!pSoldier->stopped) + { + #ifdef DEBUGBUSY + AINumMessage("HandleManAI - Moving, skipping guy#",pSoldier->ubID); + #endif - return; - } -*/ + return; + } + */ if ((pSoldier->bAction != AI_ACTION_NONE) && pSoldier->bActionInProgress) { -/* - if (pSoldier->bAction == AI_ACTION_RANDOM_PATROL) - { - if (pSoldier->usPathIndex == pSoldier->usPathDataSize) - //if (pSoldier->usActionData == pSoldier->sGridNo ) - //(IC?) if (pSoldier->bAction == AI_ACTION_RANDOM_PATROL && ( pSoldier->usPathIndex == pSoldier->usPathDataSize ) ) - //(old?) if (pSoldier->bAction == AI_ACTION_RANDOM_PATROL && ( pSoldier->usActionData == pSoldier->sGridNo ) ) - { - #ifdef TESTAI - DebugMsg( TOPIC_JA2AI, DBG_LEVEL_0, String("OPPONENT %d REACHES DEST - ACTION DONE",pSoldier->ubID ) ); - #endif - ActionDone(pSoldier); - } + /* + if (pSoldier->bAction == AI_ACTION_RANDOM_PATROL) + { + if (pSoldier->usPathIndex == pSoldier->usPathDataSize) + //if (pSoldier->usActionData == pSoldier->sGridNo ) + //(IC?) if (pSoldier->bAction == AI_ACTION_RANDOM_PATROL && ( pSoldier->usPathIndex == pSoldier->usPathDataSize ) ) + //(old?) if (pSoldier->bAction == AI_ACTION_RANDOM_PATROL && ( pSoldier->usActionData == pSoldier->sGridNo ) ) + { + #ifdef TESTAI + DebugMsg( TOPIC_JA2AI, DBG_LEVEL_0, String("OPPONENT %d REACHES DEST - ACTION DONE",pSoldier->ubID ) ); + #endif + ActionDone(pSoldier); + } - //*** TRICK- TAKE INTO ACCOUNT PAUSED FOR NO TIME ( FOR NOW ) - if (pSoldier->fNoAPToFinishMove) - //if (pSoldier->bAction == AI_ACTION_RANDOM_PATROL && pSoldier->fNoAPToFinishMove) - { - // OK, we have a move to finish... + //*** TRICK- TAKE INTO ACCOUNT PAUSED FOR NO TIME ( FOR NOW ) + if (pSoldier->fNoAPToFinishMove) + //if (pSoldier->bAction == AI_ACTION_RANDOM_PATROL && pSoldier->fNoAPToFinishMove) + { + // OK, we have a move to finish... - #ifdef TESTAI - DebugMsg( TOPIC_JA2AI, DBG_LEVEL_0, String("GONNA TRY TO CONTINUE PATH FOR %d", pSoldier->ubID ) ); - #endif + #ifdef TESTAI + DebugMsg( TOPIC_JA2AI, DBG_LEVEL_0, String("GONNA TRY TO CONTINUE PATH FOR %d", pSoldier->ubID ) ); + #endif - SoldierTriesToContinueAlongPath(pSoldier); + SoldierTriesToContinueAlongPath(pSoldier); - // since we just gave up on our action due to running out of points, better end our turn - //EndAIGuysTurn(pSoldier); - } - } -*/ + // since we just gave up on our action due to running out of points, better end our turn + //EndAIGuysTurn(pSoldier); + } + } + */ - // if action should remain in progress + // if action should remain in progress if (ActionInProgress(pSoldier)) { - #ifdef DEBUGBUSY - AINumMessage("Busy with action, skipping guy#",pSoldier->ubID); - #endif +#ifdef DEBUGBUSY + AINumMessage("Busy with action, skipping guy#",pSoldier->ubID); +#endif // let it continue return; @@ -1870,9 +1888,9 @@ void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier) // if he chose to continue doing nothing if (pSoldier->bAction == AI_ACTION_NONE) { - #ifdef RECORDNET - fprintf(NetDebugFile,"\tMOVED BECOMING TRUE: Chose to do nothing, guynum %d\n",pSoldier->ubID); - #endif +#ifdef RECORDNET + fprintf(NetDebugFile,"\tMOVED BECOMING TRUE: Chose to do nothing, guynum %d\n",pSoldier->ubID); +#endif DebugMsg (TOPIC_JA2AI,DBG_LEVEL_3,"NPC has no action assigned"); NPCDoesNothing(pSoldier); // sets pSoldier->moved to TRUE @@ -1881,18 +1899,18 @@ void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier) - /* - // if we somehow just caused an uninterruptable animation to occur - // This is mainly to finish a weapon_AWAY anim that preceeds a TOSS attack - if (!AnimControl[ pSoldier->anitype[pSoldier->anim] ].interruptable) - { -#ifdef DEBUGBUSY - DebugAI( String( "Uninterruptable animation %d, skipping guy %d",pSoldier->anitype[pSoldier->anim],pSoldier->ubID ) ); -#endif + /* + // if we somehow just caused an uninterruptable animation to occur + // This is mainly to finish a weapon_AWAY anim that preceeds a TOSS attack + if (!AnimControl[ pSoldier->anitype[pSoldier->anim] ].interruptable) + { + #ifdef DEBUGBUSY + DebugAI( String( "Uninterruptable animation %d, skipping guy %d",pSoldier->anitype[pSoldier->anim],pSoldier->ubID ) ); + #endif - return; // wait a while, let the animation finish first - } - */ + return; // wait a while, let the animation finish first + } + */ // to get here, we MUST have an action selected, but not in progress... @@ -1912,9 +1930,9 @@ void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier) } else { - #ifdef DEBUGDECISIONS - AINumMessage("HandleManAI - Not enough APs, skipping guy#",pSoldier->ubID); - #endif +#ifdef DEBUGDECISIONS + AINumMessage("HandleManAI - Not enough APs, skipping guy#",pSoldier->ubID); +#endif HaltMoveForSoldierOutOfPoints( pSoldier); return; } @@ -1924,40 +1942,40 @@ void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier) void RefreshAI(SOLDIERTYPE *pSoldier) { - // produce our own private "mine map" so we can avoid the ones we can detect -// MarkDetectableMines(pSoldier); + // produce our own private "mine map" so we can avoid the ones we can detect + // MarkDetectableMines(pSoldier); - // whether last attack hit or not doesn't matter once control has been lost - pSoldier->bLastAttackHit = FALSE; + // whether last attack hit or not doesn't matter once control has been lost + pSoldier->bLastAttackHit = FALSE; - // get an up-to-date alert status for this guy - DecideAlertStatus(pSoldier); + // get an up-to-date alert status for this guy + DecideAlertStatus(pSoldier); - if (pSoldier->bAlertStatus == STATUS_YELLOW) - SkipCoverCheck = FALSE; + if (pSoldier->bAlertStatus == STATUS_YELLOW) + SkipCoverCheck = FALSE; - // if he's in battle or knows opponents are here - if (gfTurnBasedAI) - { - if ((pSoldier->bAlertStatus == STATUS_BLACK) || (pSoldier->bAlertStatus == STATUS_RED)) + // if he's in battle or knows opponents are here + if (gfTurnBasedAI) + { + if ((pSoldier->bAlertStatus == STATUS_BLACK) || (pSoldier->bAlertStatus == STATUS_RED)) { - // always freshly rethink things at start of his turn - pSoldier->bNewSituation = IS_NEW_SITUATION; + // always freshly rethink things at start of his turn + pSoldier->bNewSituation = IS_NEW_SITUATION; } - else + else { - // make sure any paths stored during out last AI decision but not reacted - // to (probably due to lack of APs) get re-tested by the ExecuteAction() - // function in AI, since the ->sDestination may no longer be legal now! - pSoldier->bPathStored = FALSE; + // make sure any paths stored during out last AI decision but not reacted + // to (probably due to lack of APs) get re-tested by the ExecuteAction() + // function in AI, since the ->sDestination may no longer be legal now! + pSoldier->bPathStored = FALSE; - // if not currently engaged, or even alerted - // take a quick look around to see if any friends seem to be in trouble - ManChecksOnFriends(pSoldier); + // if not currently engaged, or even alerted + // take a quick look around to see if any friends seem to be in trouble + ManChecksOnFriends(pSoldier); - // allow stationary GREEN Civilians to turn again at least 1/turn! + // allow stationary GREEN Civilians to turn again at least 1/turn! } - pSoldier->bLastAction = AI_ACTION_NONE; + pSoldier->bLastAction = AI_ACTION_NONE; } } @@ -1981,20 +1999,20 @@ void AIDecideRadioAnimation( SOLDIERTYPE *pSoldier ) switch( gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) { - case ANIM_STAND: + case ANIM_STAND: - EVENT_InitNewSoldierAnim( pSoldier, AI_RADIO, 0 , FALSE ); - break; + EVENT_InitNewSoldierAnim( pSoldier, AI_RADIO, 0 , FALSE ); + break; - case ANIM_CROUCH: + case ANIM_CROUCH: - EVENT_InitNewSoldierAnim( pSoldier, AI_CR_RADIO, 0 , FALSE ); - break; + EVENT_InitNewSoldierAnim( pSoldier, AI_CR_RADIO, 0 , FALSE ); + break; - case ANIM_PRONE: + case ANIM_PRONE: - ActionDone( pSoldier ); - break; + ActionDone( pSoldier ); + break; } } @@ -2013,87 +2031,88 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier) UINT16 usHandItem = pSoldier->inv[HANDPOS].usItem; - #ifdef TESTAICONTROL +#ifdef TESTAICONTROL if (gfTurnBasedAI || gTacticalStatus.fAutoBandageMode) { DebugAI( String( "%d does %s (a.d. %d) in %d with %d APs left", pSoldier->ubID, gzActionStr[pSoldier->bAction], pSoldier->usActionData, pSoldier->sGridNo, pSoldier->bActionPoints ) ); } - #endif +#endif DebugAI( String( "%d does %s (a.d. %d) at time %ld", pSoldier->ubID, gzActionStr[pSoldier->bAction], pSoldier->usActionData, GetJA2Clock() ) ); - + switch (pSoldier->bAction) { - case AI_ACTION_NONE: // maintain current position & facing + case AI_ACTION_NONE: // maintain current position & facing + // do nothing + break; + + case AI_ACTION_WAIT: // hold AI_ACTION_NONE for a specified time + if (gfTurnBasedAI) + { + // probably an action set as a next-action in the realtime prior to combat // do nothing - break; - - case AI_ACTION_WAIT: // hold AI_ACTION_NONE for a specified time - if (gfTurnBasedAI) + } + else + { + RESETTIMECOUNTER( pSoldier->AICounter, pSoldier->usActionData ); + if (pSoldier->ubProfile != NO_PROFILE) { - // probably an action set as a next-action in the realtime prior to combat - // do nothing + //DebugMsg( TOPIC_JA2, DBG_LEVEL_0, String( "%s waiting %d from %d", pSoldier->name, pSoldier->AICounter, GetJA2Clock() ) ); } - else - { - RESETTIMECOUNTER( pSoldier->AICounter, pSoldier->usActionData ); - if (pSoldier->ubProfile != NO_PROFILE) - { - //DebugMsg( TOPIC_JA2, DBG_LEVEL_0, String( "%s waiting %d from %d", pSoldier->name, pSoldier->AICounter, GetJA2Clock() ) ); - } - } - ActionDone( pSoldier ); - break; + } + ActionDone( pSoldier ); + break; - case AI_ACTION_CHANGE_FACING: // turn this way & that to look - // as long as we don't see anyone new, cover won't have changed - // if we see someone new, it will cause a new situation & remove this - SkipCoverCheck = TRUE; + case AI_ACTION_CHANGE_FACING: // turn this way & that to look + // as long as we don't see anyone new, cover won't have changed + // if we see someone new, it will cause a new situation & remove this + SkipCoverCheck = TRUE; #ifdef DEBUGDECISIONS - STR tempstr; - sprintf( tempstr, "ExecuteAction: SkipCoverCheck ON\n" ); - DebugAI (tempstr); + STR tempstr; + sprintf( tempstr, "ExecuteAction: SkipCoverCheck ON\n" ); + DebugAI (tempstr); #endif -// pSoldier->bDesiredDirection = (UINT8) ; // turn to face direction in actionData - SendSoldierSetDesiredDirectionEvent( pSoldier, pSoldier->usActionData ); - // now we'll have to wait for the turning to finish; no need to call TurnSoldier here - //TurnSoldier( pSoldier ); -/* - if (!StartTurn(pSoldier,pSoldier->usActionData,FASTTURN)) - { -#ifdef BETAVERSION - sprintf(tempstr,"ERROR: %s tried TURN to direction %d, StartTurn failed, action %d CANCELED", - pSoldier->name,pSoldier->usActionData,pSoldier->bAction); - PopMessage(tempstr); -#endif + // pSoldier->bDesiredDirection = (UINT8) ; // turn to face direction in actionData + SendSoldierSetDesiredDirectionEvent( pSoldier, pSoldier->usActionData ); + // now we'll have to wait for the turning to finish; no need to call TurnSoldier here + //TurnSoldier( pSoldier ); + /* + if (!StartTurn(pSoldier,pSoldier->usActionData,FASTTURN)) + { + #ifdef BETAVERSION + sprintf(tempstr,"ERROR: %s tried TURN to direction %d, StartTurn failed, action %d CANCELED", + pSoldier->name,pSoldier->usActionData,pSoldier->bAction); + PopMessage(tempstr); + #endif - // ZAP NPC's remaining action points so this isn't likely to repeat - pSoldier->bActionPoints = 0; + // ZAP NPC's remaining action points so this isn't likely to repeat + pSoldier->bActionPoints = 0; - CancelAIAction(pSoldier,FORCE); - return(FALSE); // nothing is in progress - } - else - { -#ifdef RECORDNET - fprintf(NetDebugFile,"\tAI decides to turn guynum %d to dir %d\n",pSoldier->ubID,pSoldier->usActionData); -#endif - NetLookTowardsDir(pSoldier,pSoldier->usActionData); - } - */ - break; + CancelAIAction(pSoldier,FORCE); + return(FALSE); // nothing is in progress + } + else + { + #ifdef RECORDNET + fprintf(NetDebugFile,"\tAI decides to turn guynum %d to dir %d\n",pSoldier->ubID,pSoldier->usActionData); + #endif + NetLookTowardsDir(pSoldier,pSoldier->usActionData); + } + */ + break; - case AI_ACTION_PICKUP_ITEM: // grab something! - SoldierPickupItem( pSoldier, pSoldier->uiPendingActionData1, pSoldier->usActionData, 0 ); - break; + case AI_ACTION_PICKUP_ITEM: // grab something! + SoldierPickupItem( pSoldier, pSoldier->uiPendingActionData1, pSoldier->usActionData, 0 ); + break; - case AI_ACTION_DROP_ITEM: // drop item in hand - SoldierDropItem( pSoldier, &(pSoldier->inv[HANDPOS]) ); - DeleteObj( &(pSoldier->inv[HANDPOS]) ); - pSoldier->bAction = AI_ACTION_PENDING_ACTION; - break; + case AI_ACTION_DROP_ITEM: // drop item in hand + SoldierDropItem( pSoldier, &(pSoldier->inv[HANDPOS]) ); + DeleteObj( &(pSoldier->inv[HANDPOS]) ); + // 0verhaul: Moved into PickDropAnimation because when something is dropped while crouched there's nothing to wait for + // pSoldier->bAction = AI_ACTION_PENDING_ACTION; + break; //case AI_ACTION_MOVE_TO_CLIMB: // if ( pSoldier->usActionData == pSoldier->sGridNo ) @@ -2111,519 +2130,519 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier) // } // } - // fall through - case AI_ACTION_RANDOM_PATROL: // move towards a particular location - case AI_ACTION_SEEK_FRIEND: // move towards friend in trouble - case AI_ACTION_SEEK_OPPONENT: // move towards a reported opponent - case AI_ACTION_TAKE_COVER: // run for nearest cover from threat - case AI_ACTION_GET_CLOSER: // move closer to a strategic location + // fall through + case AI_ACTION_RANDOM_PATROL: // move towards a particular location + case AI_ACTION_SEEK_FRIEND: // move towards friend in trouble + case AI_ACTION_SEEK_OPPONENT: // move towards a reported opponent + case AI_ACTION_TAKE_COVER: // run for nearest cover from threat + case AI_ACTION_GET_CLOSER: // move closer to a strategic location - case AI_ACTION_POINT_PATROL: // move towards next patrol point - case AI_ACTION_LEAVE_WATER_GAS: // seek nearest spot of ungassed land - case AI_ACTION_SEEK_NOISE: // seek most important noise heard - case AI_ACTION_RUN_AWAY: // run away from nearby opponent(s) + case AI_ACTION_POINT_PATROL: // move towards next patrol point + case AI_ACTION_LEAVE_WATER_GAS: // seek nearest spot of ungassed land + case AI_ACTION_SEEK_NOISE: // seek most important noise heard + case AI_ACTION_RUN_AWAY: // run away from nearby opponent(s) - case AI_ACTION_APPROACH_MERC: // walk up to someone to talk - case AI_ACTION_TRACK: // track by ground scent - case AI_ACTION_EAT: // monster approaching corpse - case AI_ACTION_SCHEDULE_MOVE: - case AI_ACTION_WALK: - case AI_ACTION_WITHDRAW: - case AI_ACTION_FLANK_LEFT: - case AI_ACTION_FLANK_RIGHT: - case AI_ACTION_RUN: - case AI_ACTION_MOVE_TO_CLIMB: - if ( pSoldier->bAction == AI_ACTION_MOVE_TO_CLIMB ) + case AI_ACTION_APPROACH_MERC: // walk up to someone to talk + case AI_ACTION_TRACK: // track by ground scent + case AI_ACTION_EAT: // monster approaching corpse + case AI_ACTION_SCHEDULE_MOVE: + case AI_ACTION_WALK: + case AI_ACTION_WITHDRAW: + case AI_ACTION_FLANK_LEFT: + case AI_ACTION_FLANK_RIGHT: + case AI_ACTION_RUN: + case AI_ACTION_MOVE_TO_CLIMB: + if ( pSoldier->bAction == AI_ACTION_MOVE_TO_CLIMB ) + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Executing: AI_ACTION_MOVE_TO_CLIMB"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("Soldier GridNo = %d, action data = %d ", pSoldier->sGridNo , pSoldier->usActionData)); + } + + if ( gfTurnBasedAI && pSoldier->bAlertStatus < STATUS_BLACK ) + { + if ( pSoldier->sLastTwoLocations[0] == NOWHERE ) { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Executing: AI_ACTION_MOVE_TO_CLIMB"); - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("Soldier GridNo = %d, action data = %d ", pSoldier->sGridNo , pSoldier->usActionData)); + pSoldier->sLastTwoLocations[0] = pSoldier->sGridNo; } - - if ( gfTurnBasedAI && pSoldier->bAlertStatus < STATUS_BLACK ) + else if ( pSoldier->sLastTwoLocations[1] == NOWHERE ) { - if ( pSoldier->sLastTwoLocations[0] == NOWHERE ) - { - pSoldier->sLastTwoLocations[0] = pSoldier->sGridNo; - } - else if ( pSoldier->sLastTwoLocations[1] == NOWHERE ) - { - pSoldier->sLastTwoLocations[1] = pSoldier->sGridNo; - } - // check for loop - else if ( pSoldier->usActionData == pSoldier->sLastTwoLocations[1] && pSoldier->sGridNo == pSoldier->sLastTwoLocations[0] ) - { - DebugAI( String( "%d in movement loop, aborting turn", pSoldier->ubID ) ); + pSoldier->sLastTwoLocations[1] = pSoldier->sGridNo; + } + // check for loop + else if ( pSoldier->usActionData == pSoldier->sLastTwoLocations[1] && pSoldier->sGridNo == pSoldier->sLastTwoLocations[0] ) + { + DebugAI( String( "%d in movement loop, aborting turn", pSoldier->ubID ) ); - // loop found! - ActionDone( pSoldier ); - EndAIGuysTurn( pSoldier ); - } - else + // loop found! + ActionDone( pSoldier ); + EndAIGuysTurn( pSoldier ); + } + else + { + pSoldier->sLastTwoLocations[0] = pSoldier->sLastTwoLocations[1]; + pSoldier->sLastTwoLocations[1] = pSoldier->sGridNo; + } + } + + // Randomly do growl... + if ( pSoldier->ubBodyType == BLOODCAT ) + { + if ( ( gTacticalStatus.uiFlags & INCOMBAT ) ) + { + if ( Random( 2 ) == 0 ) { - pSoldier->sLastTwoLocations[0] = pSoldier->sLastTwoLocations[1]; - pSoldier->sLastTwoLocations[1] = pSoldier->sGridNo; + PlaySoldierJA2Sample( pSoldier->ubID, ( BLOODCAT_GROWL_1 + Random( 4 ) ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); + } + } + } + + // on YELLOW/GREEN status, NPCs keep the actions from turn to turn + // (newSituation is intentionally NOT set in NewSelectedNPC()), so the + // possibility exists that NOW the actionData is no longer a valid + // NPC ->sDestination (path got blocked, someone is now standing at that + // gridno, etc.) So we gotta check again that the ->sDestination's legal! + + // optimization - Ian (if up-to-date path is known, do not check again) + if (!pSoldier->bPathStored) + { + if ( (pSoldier->sAbsoluteFinalDestination != NOWHERE || gTacticalStatus.fAutoBandageMode) && !(gTacticalStatus.uiFlags & INCOMBAT) ) + { + // NPC system move, allow path through + if (LegalNPCDestination(pSoldier,pSoldier->usActionData,ENSURE_PATH,WATEROK, PATH_THROUGH_PEOPLE )) + { + // optimization - Ian: prevent another path call in SetNewCourse() + pSoldier->bPathStored = TRUE; + } + } + else + { + if (LegalNPCDestination(pSoldier,pSoldier->usActionData,ENSURE_PATH,WATEROK, 0)) + { + // optimization - Ian: prevent another path call in SetNewCourse() + pSoldier->bPathStored = TRUE; } } - // Randomly do growl... - if ( pSoldier->ubBodyType == BLOODCAT ) - { - if ( ( gTacticalStatus.uiFlags & INCOMBAT ) ) - { - if ( Random( 2 ) == 0 ) - { - PlaySoldierJA2Sample( pSoldier->ubID, ( BLOODCAT_GROWL_1 + Random( 4 ) ), RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ), TRUE ); - } - } - } - - // on YELLOW/GREEN status, NPCs keep the actions from turn to turn - // (newSituation is intentionally NOT set in NewSelectedNPC()), so the - // possibility exists that NOW the actionData is no longer a valid - // NPC ->sDestination (path got blocked, someone is now standing at that - // gridno, etc.) So we gotta check again that the ->sDestination's legal! - - // optimization - Ian (if up-to-date path is known, do not check again) - if (!pSoldier->bPathStored) + // if we STILL don't have a path + if ( !pSoldier->bPathStored ) { - if ( (pSoldier->sAbsoluteFinalDestination != NOWHERE || gTacticalStatus.fAutoBandageMode) && !(gTacticalStatus.uiFlags & INCOMBAT) ) + // Check if we were told to move by NPC stuff + if ( pSoldier->sAbsoluteFinalDestination != NOWHERE && !(gTacticalStatus.uiFlags & INCOMBAT) ) { - // NPC system move, allow path through - if (LegalNPCDestination(pSoldier,pSoldier->usActionData,ENSURE_PATH,WATEROK, PATH_THROUGH_PEOPLE )) - { - // optimization - Ian: prevent another path call in SetNewCourse() - pSoldier->bPathStored = TRUE; - } - } - else - { - if (LegalNPCDestination(pSoldier,pSoldier->usActionData,ENSURE_PATH,WATEROK, 0)) - { - // optimization - Ian: prevent another path call in SetNewCourse() - pSoldier->bPathStored = TRUE; - } - } + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_ERROR, L"AI %s failed to get path for dialogue-related move!", pSoldier->name ); - // if we STILL don't have a path - if ( !pSoldier->bPathStored ) - { - // Check if we were told to move by NPC stuff - if ( pSoldier->sAbsoluteFinalDestination != NOWHERE && !(gTacticalStatus.uiFlags & INCOMBAT) ) + // Are we close enough? + if ( !ACTING_ON_SCHEDULE( pSoldier ) && SpacesAway( pSoldier->sGridNo, pSoldier->sAbsoluteFinalDestination ) < 4 ) { - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_ERROR, L"AI %s failed to get path for dialogue-related move!", pSoldier->name ); - - // Are we close enough? - if ( !ACTING_ON_SCHEDULE( pSoldier ) && SpacesAway( pSoldier->sGridNo, pSoldier->sAbsoluteFinalDestination ) < 4 ) - { - // This is close enough... - ReplaceLocationInNPCDataFromProfileID( pSoldier->ubProfile, pSoldier->sAbsoluteFinalDestination, pSoldier->sGridNo ); - NPCGotoGridNo( pSoldier->ubProfile, pSoldier->sGridNo, (UINT8) (pSoldier->ubQuoteRecord - 1) ); - } - else - { - // This is important, so try taking a path through people (and bumping them aside) - if (LegalNPCDestination(pSoldier,pSoldier->usActionData,ENSURE_PATH,WATEROK, PATH_THROUGH_PEOPLE)) - { - // optimization - Ian: prevent another path call in SetNewCourse() - pSoldier->bPathStored = TRUE; - } - else - { - // Have buddy wait a while... - pSoldier->bNextAction = AI_ACTION_WAIT; - pSoldier->usNextActionData = (UINT16)REALTIME_AI_DELAY; - } - } - - if (!pSoldier->bPathStored) - { - CancelAIAction(pSoldier,FORCE); - return(FALSE); // nothing is in progress - } + // This is close enough... + ReplaceLocationInNPCDataFromProfileID( pSoldier->ubProfile, pSoldier->sAbsoluteFinalDestination, pSoldier->sGridNo ); + NPCGotoGridNo( pSoldier->ubProfile, pSoldier->sGridNo, (UINT8) (pSoldier->ubQuoteRecord - 1) ); } else + { + // This is important, so try taking a path through people (and bumping them aside) + if (LegalNPCDestination(pSoldier,pSoldier->usActionData,ENSURE_PATH,WATEROK, PATH_THROUGH_PEOPLE)) + { + // optimization - Ian: prevent another path call in SetNewCourse() + pSoldier->bPathStored = TRUE; + } + else + { + // Have buddy wait a while... + pSoldier->bNextAction = AI_ACTION_WAIT; + pSoldier->usNextActionData = (UINT16)REALTIME_AI_DELAY; + } + } + + if (!pSoldier->bPathStored) { CancelAIAction(pSoldier,FORCE); return(FALSE); // nothing is in progress } } + else + { + CancelAIAction(pSoldier,FORCE); + return(FALSE); // nothing is in progress + } } + } - // add on anything necessary to traverse off map edge - switch( pSoldier->ubQuoteActionID ) - { - case QUOTE_ACTION_ID_TRAVERSE_EAST: - pSoldier->sOffWorldGridNo = pSoldier->usActionData; - AdjustSoldierPathToGoOffEdge( pSoldier, pSoldier->usActionData, EAST ); - break; - case QUOTE_ACTION_ID_TRAVERSE_SOUTH: - pSoldier->sOffWorldGridNo = pSoldier->usActionData; - AdjustSoldierPathToGoOffEdge( pSoldier, pSoldier->usActionData, SOUTH ); - break; - case QUOTE_ACTION_ID_TRAVERSE_WEST: - pSoldier->sOffWorldGridNo = pSoldier->usActionData; - AdjustSoldierPathToGoOffEdge( pSoldier, pSoldier->usActionData, WEST ); - break; - case QUOTE_ACTION_ID_TRAVERSE_NORTH: - pSoldier->sOffWorldGridNo = pSoldier->usActionData; - AdjustSoldierPathToGoOffEdge( pSoldier, pSoldier->usActionData, NORTH ); - break; - default: - break; - } + // add on anything necessary to traverse off map edge + switch( pSoldier->ubQuoteActionID ) + { + case QUOTE_ACTION_ID_TRAVERSE_EAST: + pSoldier->sOffWorldGridNo = pSoldier->usActionData; + AdjustSoldierPathToGoOffEdge( pSoldier, pSoldier->usActionData, EAST ); + break; + case QUOTE_ACTION_ID_TRAVERSE_SOUTH: + pSoldier->sOffWorldGridNo = pSoldier->usActionData; + AdjustSoldierPathToGoOffEdge( pSoldier, pSoldier->usActionData, SOUTH ); + break; + case QUOTE_ACTION_ID_TRAVERSE_WEST: + pSoldier->sOffWorldGridNo = pSoldier->usActionData; + AdjustSoldierPathToGoOffEdge( pSoldier, pSoldier->usActionData, WEST ); + break; + case QUOTE_ACTION_ID_TRAVERSE_NORTH: + pSoldier->sOffWorldGridNo = pSoldier->usActionData; + AdjustSoldierPathToGoOffEdge( pSoldier, pSoldier->usActionData, NORTH ); + break; + default: + break; + } - NewDest(pSoldier,pSoldier->usActionData); // set new ->sDestination to actionData + NewDest(pSoldier,pSoldier->usActionData); // set new ->sDestination to actionData - // make sure it worked (check that pSoldier->sDestination == pSoldier->usActionData) - if (pSoldier->sFinalDestination != pSoldier->usActionData) - { + // make sure it worked (check that pSoldier->sDestination == pSoldier->usActionData) + if (pSoldier->sFinalDestination != pSoldier->usActionData) + { #ifdef BETAVERSION - // this should NEVER happen, indicates AI picked an illegal spot! - sprintf(tempstr,"ExecuteAction: ERROR - %s tried MOVE to gridno %d, NewDest failed, action %d CANCELED", - pSoldier->name,pSoldier->usActionData,pSoldier->bAction); + // this should NEVER happen, indicates AI picked an illegal spot! + sprintf(tempstr,"ExecuteAction: ERROR - %s tried MOVE to gridno %d, NewDest failed, action %d CANCELED", + pSoldier->name,pSoldier->usActionData,pSoldier->bAction); #ifdef RECORDNET - fprintf(NetDebugFile,"\n%s\n\n",tempstr); + fprintf(NetDebugFile,"\n%s\n\n",tempstr); #endif - PopMessage(tempstr); + PopMessage(tempstr); - sprintf(tempstr,"BLACK-LISTING gridno %d for %s",pSoldier->usActionData,pSoldier->name); - PopMessage(tempstr); + sprintf(tempstr,"BLACK-LISTING gridno %d for %s",pSoldier->usActionData,pSoldier->name); + PopMessage(tempstr); - SaveGame(ERROR_SAVE); + SaveGame(ERROR_SAVE); #endif - // temporarily black list this gridno to stop enemy from going there - pSoldier->sBlackList = (INT16) pSoldier->usActionData; + // temporarily black list this gridno to stop enemy from going there + pSoldier->sBlackList = (INT16) pSoldier->usActionData; - DebugAI( String( "Setting blacklist for %d to %d", pSoldier->ubID, pSoldier->sBlackList ) ); + DebugAI( String( "Setting blacklist for %d to %d", pSoldier->ubID, pSoldier->sBlackList ) ); - CancelAIAction(pSoldier,FORCE); - return(FALSE); // nothing is in progress - } + CancelAIAction(pSoldier,FORCE); + return(FALSE); // nothing is in progress + } - // cancel any old black-listed gridno, got a valid new ->sDestination - pSoldier->sBlackList = NOWHERE; - break; + // cancel any old black-listed gridno, got a valid new ->sDestination + pSoldier->sBlackList = NOWHERE; + break; - case AI_ACTION_ESCORTED_MOVE: // go where told to by escortPlayer - // since this is a delayed move, gotta make sure that it hasn't become - // illegal since escort orders were issued (->sDestination/route blocked). - // So treat it like a CONTINUE movement, and handle errors that way - if (!TryToResumeMovement(pSoldier,pSoldier->usActionData)) + case AI_ACTION_ESCORTED_MOVE: // go where told to by escortPlayer + // since this is a delayed move, gotta make sure that it hasn't become + // illegal since escort orders were issued (->sDestination/route blocked). + // So treat it like a CONTINUE movement, and handle errors that way + if (!TryToResumeMovement(pSoldier,pSoldier->usActionData)) + { + // don't black-list anything here, and action already got canceled + return(FALSE); // nothing is in progress + } + + // cancel any old black-listed gridno, got a valid new ->sDestination + pSoldier->sBlackList = NOWHERE; + break; + + case AI_ACTION_TOSS_PROJECTILE: // throw grenade at/near opponent(s) + LoadWeaponIfNeeded(pSoldier); + // drop through here... + + case AI_ACTION_KNIFE_MOVE: // preparing to stab opponent + if (pSoldier->bAction == AI_ACTION_KNIFE_MOVE) // if statement because toss falls through + { + pSoldier->usUIMovementMode = DetermineMovementMode( pSoldier, AI_ACTION_KNIFE_MOVE ); + } + + // fall through + case AI_ACTION_FIRE_GUN: // shoot at nearby opponent + case AI_ACTION_THROW_KNIFE: // throw knife at nearby opponent + // randomly decide whether to say civ quote + if ( pSoldier->bVisible != -1 && pSoldier->bTeam != MILITIA_TEAM ) + { + // ATE: Make sure it's a person :) + if ( IS_MERC_BODY_TYPE( pSoldier ) && pSoldier->ubProfile == NO_PROFILE ) { - // don't black-list anything here, and action already got canceled - return(FALSE); // nothing is in progress - } - - // cancel any old black-listed gridno, got a valid new ->sDestination - pSoldier->sBlackList = NOWHERE; - break; - - case AI_ACTION_TOSS_PROJECTILE: // throw grenade at/near opponent(s) - LoadWeaponIfNeeded(pSoldier); - // drop through here... - - case AI_ACTION_KNIFE_MOVE: // preparing to stab opponent - if (pSoldier->bAction == AI_ACTION_KNIFE_MOVE) // if statement because toss falls through - { - pSoldier->usUIMovementMode = DetermineMovementMode( pSoldier, AI_ACTION_KNIFE_MOVE ); - } - - // fall through - case AI_ACTION_FIRE_GUN: // shoot at nearby opponent - case AI_ACTION_THROW_KNIFE: // throw knife at nearby opponent - // randomly decide whether to say civ quote - if ( pSoldier->bVisible != -1 && pSoldier->bTeam != MILITIA_TEAM ) - { - // ATE: Make sure it's a person :) - if ( IS_MERC_BODY_TYPE( pSoldier ) && pSoldier->ubProfile == NO_PROFILE ) - { - // CC, ATE here - I put in some TEMP randomness... - if ( Random( 50 ) == 0 ) - { - StartCivQuote( pSoldier ); - } - } + // CC, ATE here - I put in some TEMP randomness... + if ( Random( 50 ) == 0 ) + { + StartCivQuote( pSoldier ); + } } + } #ifdef RECORDNET - fprintf(NetDebugFile,"\tExecuteAction: %d calling HandleItem(), inHand %d, actionData %d, anitype %d, oldani %d\n", - pSoldier->ubID,pSoldier->inv[HANDPOS].item,pSoldier->usActionData,pSoldier->anitype[pSoldier->anim],pSoldier->oldani); + fprintf(NetDebugFile,"\tExecuteAction: %d calling HandleItem(), inHand %d, actionData %d, anitype %d, oldani %d\n", + pSoldier->ubID,pSoldier->inv[HANDPOS].item,pSoldier->usActionData,pSoldier->anitype[pSoldier->anim],pSoldier->oldani); #endif #ifdef TESTVERSION - if (pSoldier->bAction == AI_ACTION_KNIFE_MOVE) - { - sprintf(tempstr,"TEST MSG: %s is about to go stab %s. MAKE SURE HE DOES!", - pSoldier->name, + if (pSoldier->bAction == AI_ACTION_KNIFE_MOVE) + { + sprintf(tempstr,"TEST MSG: %s is about to go stab %s. MAKE SURE HE DOES!", + pSoldier->name, ExtMen[WhoIsThere(pSoldier->usActionData)].name); - SimulMessage(tempstr,3000,NODECRYPT); + SimulMessage(tempstr,3000,NODECRYPT); + } +#endif + + if ( pSoldier->bAction == AI_ACTION_TOSS_PROJECTILE && IsGrenadeLauncherAttached(&pSoldier->inv[HANDPOS]) ) + usHandItem = GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS]); + + iRetCode = HandleItem( pSoldier, pSoldier->usActionData, pSoldier->bTargetLevel, usHandItem, FALSE ); + if ( iRetCode != ITEM_HANDLE_OK) + { + if ( iRetCode != ITEM_HANDLE_BROKEN ) // if the item broke, this is 'legal' and doesn't need reporting + { + DebugAI( String( "AI %d got error code %ld from HandleItem, doing action %d, has %d APs... aborting deadlock!", pSoldier->ubID, iRetCode, pSoldier->bAction, pSoldier->bActionPoints ) ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"AI %d got error code %ld from HandleItem, doing action %d... aborting deadlock!", pSoldier->ubID, iRetCode, pSoldier->bAction ); + } + CancelAIAction( pSoldier, FORCE); +#ifdef TESTAICONTROL + if (gfTurnBasedAI) + { + DebugAI( String("Ending turn for %d because of error from HandleItem", pSoldier->ubID ) ); } #endif - - if ( pSoldier->bAction == AI_ACTION_TOSS_PROJECTILE && IsGrenadeLauncherAttached(&pSoldier->inv[HANDPOS]) ) - usHandItem = GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS]); + EndAIGuysTurn( pSoldier ); + } + break; - iRetCode = HandleItem( pSoldier, pSoldier->usActionData, pSoldier->bTargetLevel, usHandItem, FALSE ); - if ( iRetCode != ITEM_HANDLE_OK) - { - if ( iRetCode != ITEM_HANDLE_BROKEN ) // if the item broke, this is 'legal' and doesn't need reporting - { - DebugAI( String( "AI %d got error code %ld from HandleItem, doing action %d, has %d APs... aborting deadlock!", pSoldier->ubID, iRetCode, pSoldier->bAction, pSoldier->bActionPoints ) ); - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"AI %d got error code %ld from HandleItem, doing action %d... aborting deadlock!", pSoldier->ubID, iRetCode, pSoldier->bAction ); - } - CancelAIAction( pSoldier, FORCE); - #ifdef TESTAICONTROL - if (gfTurnBasedAI) - { - DebugAI( String("Ending turn for %d because of error from HandleItem", pSoldier->ubID ) ); - } - #endif - EndAIGuysTurn( pSoldier ); - } - break; + case AI_ACTION_PULL_TRIGGER: // activate an adjacent panic trigger - case AI_ACTION_PULL_TRIGGER: // activate an adjacent panic trigger + // turn to face trigger first + if ( FindStructure( (INT16)(pSoldier->sGridNo + DirectionInc( NORTH )), STRUCTURE_SWITCH ) ) + { + SendSoldierSetDesiredDirectionEvent( pSoldier, NORTH ); + } + else + { + SendSoldierSetDesiredDirectionEvent( pSoldier, WEST ); + } - // turn to face trigger first - if ( FindStructure( (INT16)(pSoldier->sGridNo + DirectionInc( NORTH )), STRUCTURE_SWITCH ) ) - { - SendSoldierSetDesiredDirectionEvent( pSoldier, NORTH ); - } - else - { - SendSoldierSetDesiredDirectionEvent( pSoldier, WEST ); - } - - EVENT_InitNewSoldierAnim( pSoldier, AI_PULL_SWITCH, 0 , FALSE ); + EVENT_InitNewSoldierAnim( pSoldier, AI_PULL_SWITCH, 0 , FALSE ); - DeductPoints( pSoldier, AP_PULL_TRIGGER, 0 ); + DeductPoints( pSoldier, AP_PULL_TRIGGER, 0 ); - //gTacticalStatus.fPanicFlags = 0; // turn all flags off - gTacticalStatus.ubTheChosenOne = NOBODY; - break; + //gTacticalStatus.fPanicFlags = 0; // turn all flags off + gTacticalStatus.ubTheChosenOne = NOBODY; + break; - case AI_ACTION_USE_DETONATOR: - //gTacticalStatus.fPanicFlags = 0; // turn all flags off - gTacticalStatus.ubTheChosenOne = NOBODY; - //gTacticalStatus.sPanicTriggerGridno = NOWHERE; + case AI_ACTION_USE_DETONATOR: + //gTacticalStatus.fPanicFlags = 0; // turn all flags off + gTacticalStatus.ubTheChosenOne = NOBODY; + //gTacticalStatus.sPanicTriggerGridno = NOWHERE; - // grab detonator and set off bomb(s) - DeductPoints( pSoldier, AP_USE_REMOTE, BP_USE_DETONATOR);// pay for it! - //SetOffPanicBombs(1000,COMMUNICATE); // BOOOOOOOOOOOOOOOOOOOOM!!!!! - SetOffPanicBombs( pSoldier->ubID, 0 ); + // grab detonator and set off bomb(s) + DeductPoints( pSoldier, AP_USE_REMOTE, BP_USE_DETONATOR);// pay for it! + //SetOffPanicBombs(1000,COMMUNICATE); // BOOOOOOOOOOOOOOOOOOOOM!!!!! + SetOffPanicBombs( pSoldier->ubID, 0 ); - // action completed immediately, cancel it right away - pSoldier->usActionData = NOWHERE; - pSoldier->bLastAction = pSoldier->bAction; - pSoldier->bAction = AI_ACTION_NONE; - return(FALSE); // no longer in progress + // action completed immediately, cancel it right away + pSoldier->usActionData = NOWHERE; + pSoldier->bLastAction = pSoldier->bAction; + pSoldier->bAction = AI_ACTION_NONE; + return(FALSE); // no longer in progress - break; + break; - case AI_ACTION_RED_ALERT: // tell friends opponent(s) seen - // if a computer merc, and up to now they didn't know you're here - if (!(pSoldier->uiStatusFlags & SOLDIER_PC) && ( !(gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition) || ( ( gTacticalStatus.fPanicFlags & PANIC_TRIGGERS_HERE ) && gTacticalStatus.ubTheChosenOne == NOBODY ) ) ) - { - HandleInitialRedAlert(pSoldier->bTeam, TRUE); - } - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Debug: AI radios your position!" ); - // DROP THROUGH HERE! - case AI_ACTION_YELLOW_ALERT: // tell friends opponent(s) heard - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Debug: AI radios about a noise!" ); -/* - NetSend.msgType = NET_RADIO_SIGHTINGS; - NetSend.ubID = pSoldier->ubID; + case AI_ACTION_RED_ALERT: // tell friends opponent(s) seen + // if a computer merc, and up to now they didn't know you're here + if (!(pSoldier->uiStatusFlags & SOLDIER_PC) && ( !(gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition) || ( ( gTacticalStatus.fPanicFlags & PANIC_TRIGGERS_HERE ) && gTacticalStatus.ubTheChosenOne == NOBODY ) ) ) + { + HandleInitialRedAlert(pSoldier->bTeam, TRUE); + } + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Debug: AI radios your position!" ); + // DROP THROUGH HERE! + case AI_ACTION_YELLOW_ALERT: // tell friends opponent(s) heard + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Debug: AI radios about a noise!" ); + /* + NetSend.msgType = NET_RADIO_SIGHTINGS; + NetSend.ubID = pSoldier->ubID; - SendNetData(ALL_NODES); -*/ - DeductPoints(pSoldier,AP_RADIO,BP_RADIO);// pay for it! - RadioSightings(pSoldier,EVERYBODY,pSoldier->bTeam); // about everybody - // action completed immediately, cancel it right away + SendNetData(ALL_NODES); + */ + DeductPoints(pSoldier,AP_RADIO,BP_RADIO);// pay for it! + RadioSightings(pSoldier,EVERYBODY,pSoldier->bTeam); // about everybody + // action completed immediately, cancel it right away - // ATE: Change to an animation! - AIDecideRadioAnimation( pSoldier ); - //return(FALSE); // no longer in progress - break; + // ATE: Change to an animation! + AIDecideRadioAnimation( pSoldier ); + //return(FALSE); // no longer in progress + break; - case AI_ACTION_CREATURE_CALL: // creature calling to others - DeductPoints(pSoldier,AP_RADIO,BP_RADIO);// pay for it! - CreatureCall( pSoldier ); - //return( FALSE ); // no longer in progress - break; + case AI_ACTION_CREATURE_CALL: // creature calling to others + DeductPoints(pSoldier,AP_RADIO,BP_RADIO);// pay for it! + CreatureCall( pSoldier ); + //return( FALSE ); // no longer in progress + break; - case AI_ACTION_CHANGE_STANCE: // crouch - if ( gAnimControl[ pSoldier->usAnimState ].ubHeight == pSoldier->usActionData ) - { - // abort! - ActionDone( pSoldier ); - return( FALSE ); - } + case AI_ACTION_CHANGE_STANCE: // crouch + if ( gAnimControl[ pSoldier->usAnimState ].ubHeight == pSoldier->usActionData ) + { + // abort! + ActionDone( pSoldier ); + return( FALSE ); + } - SkipCoverCheck = TRUE; + SkipCoverCheck = TRUE; #ifdef DEBUGDECISIONS - sprintf( tempstr, "ExecuteAction: SkipCoverCheck ON\n" ); - DebugAI (tempstr); + sprintf( tempstr, "ExecuteAction: SkipCoverCheck ON\n" ); + DebugAI (tempstr); #endif - SendChangeSoldierStanceEvent( pSoldier, (UINT8) pSoldier->usActionData ); - break; + SendChangeSoldierStanceEvent( pSoldier, (UINT8) pSoldier->usActionData ); + break; - case AI_ACTION_COWER: - // make sure action data is set right - if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) - { - // nothing to do! - ActionDone( pSoldier ); - return( FALSE ); - } - else - { - pSoldier->usActionData = ANIM_CROUCH; - SetSoldierCowerState( pSoldier, TRUE ); - } - break; + case AI_ACTION_COWER: + // make sure action data is set right + if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) + { + // nothing to do! + ActionDone( pSoldier ); + return( FALSE ); + } + else + { + pSoldier->usActionData = ANIM_CROUCH; + SetSoldierCowerState( pSoldier, TRUE ); + } + break; - case AI_ACTION_STOP_COWERING: - // make sure action data is set right - if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) - { - pSoldier->usActionData = ANIM_STAND; - SetSoldierCowerState( pSoldier, FALSE ); - } - else - { - // nothing to do! - ActionDone( pSoldier ); - return( FALSE ); - } - break; + case AI_ACTION_STOP_COWERING: + // make sure action data is set right + if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) + { + pSoldier->usActionData = ANIM_STAND; + SetSoldierCowerState( pSoldier, FALSE ); + } + else + { + // nothing to do! + ActionDone( pSoldier ); + return( FALSE ); + } + break; - case AI_ACTION_GIVE_AID: // help injured/dying friend - //pSoldier->usUIMovementMode = RUNNING; - iRetCode = HandleItem( pSoldier, pSoldier->usActionData, 0, pSoldier->inv[HANDPOS].usItem, FALSE ); - if ( iRetCode != ITEM_HANDLE_OK) - { + case AI_ACTION_GIVE_AID: // help injured/dying friend + //pSoldier->usUIMovementMode = RUNNING; + iRetCode = HandleItem( pSoldier, pSoldier->usActionData, 0, pSoldier->inv[HANDPOS].usItem, FALSE ); + if ( iRetCode != ITEM_HANDLE_OK) + { #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_ERROR, L"AI %d got error code %ld from HandleItem, doing action %d... aborting deadlock!", pSoldier->ubID, iRetCode, pSoldier->bAction ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_ERROR, L"AI %d got error code %ld from HandleItem, doing action %d... aborting deadlock!", pSoldier->ubID, iRetCode, pSoldier->bAction ); +#endif + CancelAIAction( pSoldier, FORCE); +#ifdef TESTAICONTROL + if (gfTurnBasedAI) + { + DebugAI( String("Ending turn for %d because of error from HandleItem", pSoldier->ubID ) ); + } +#endif + EndAIGuysTurn( pSoldier ); + } + break; + + case AI_ACTION_OPEN_OR_CLOSE_DOOR: + case AI_ACTION_UNLOCK_DOOR: + case AI_ACTION_LOCK_DOOR: + { + STRUCTURE * pStructure; + INT8 bDirection; + INT16 sDoorGridNo; + + bDirection = (INT8) GetDirectionFromGridNo( pSoldier->usActionData, pSoldier ); + if (bDirection == EAST || bDirection == SOUTH) + { + sDoorGridNo = pSoldier->sGridNo; + } + else + { + sDoorGridNo = pSoldier->sGridNo + DirectionInc( bDirection ); + } + + pStructure = FindStructure( sDoorGridNo, STRUCTURE_ANYDOOR ); + if (pStructure == NULL) + { +#ifdef JA2TESTVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_ERROR, L"AI %d tried to open door it could not then find in %d", pSoldier->ubID, sDoorGridNo ); #endif CancelAIAction( pSoldier, FORCE); - #ifdef TESTAICONTROL - if (gfTurnBasedAI) - { - DebugAI( String("Ending turn for %d because of error from HandleItem", pSoldier->ubID ) ); - } - #endif - EndAIGuysTurn( pSoldier ); - } - break; - - case AI_ACTION_OPEN_OR_CLOSE_DOOR: - case AI_ACTION_UNLOCK_DOOR: - case AI_ACTION_LOCK_DOOR: - { - STRUCTURE * pStructure; - INT8 bDirection; - INT16 sDoorGridNo; - - bDirection = (INT8) GetDirectionFromGridNo( pSoldier->usActionData, pSoldier ); - if (bDirection == EAST || bDirection == SOUTH) +#ifdef TESTAICONTROL + if (gfTurnBasedAI) { - sDoorGridNo = pSoldier->sGridNo; + DebugAI( String("Ending turn for %d because of error opening door", pSoldier->ubID ) ); } - else - { - sDoorGridNo = pSoldier->sGridNo + DirectionInc( bDirection ); - } - - pStructure = FindStructure( sDoorGridNo, STRUCTURE_ANYDOOR ); - if (pStructure == NULL) - { -#ifdef JA2TESTVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_ERROR, L"AI %d tried to open door it could not then find in %d", pSoldier->ubID, sDoorGridNo ); #endif - CancelAIAction( pSoldier, FORCE); - #ifdef TESTAICONTROL - if (gfTurnBasedAI) - { - DebugAI( String("Ending turn for %d because of error opening door", pSoldier->ubID ) ); - } - #endif - EndAIGuysTurn( pSoldier ); - } - - StartInteractiveObject( sDoorGridNo, pStructure->usStructureID, pSoldier, bDirection ); - InteractWithInteractiveObject( pSoldier, pStructure, bDirection ); + EndAIGuysTurn( pSoldier ); } - break; - case AI_ACTION_LOWER_GUN: - // for now, just do "action done" - InternalSoldierReadyWeapon(pSoldier,pSoldier->bDirection,TRUE); - HandleSight(pSoldier, SIGHT_LOOK ); - ActionDone( pSoldier ); - break; + StartInteractiveObject( sDoorGridNo, pStructure->usStructureID, pSoldier, bDirection ); + InteractWithInteractiveObject( pSoldier, pStructure, bDirection ); + } + break; - case AI_ACTION_RAISE_GUN: //Madd: action added for snipers to ready weapon and use vision range bonuses - SoldierReadyWeapon(pSoldier); - HandleSight(pSoldier, SIGHT_LOOK | SIGHT_RADIO); - - //AXP 23.03.2007: Sniper deadlock fix - if ( pSoldier->bOrders == SNIPER && pSoldier->bLastAction == AI_ACTION_RAISE_GUN) - { - pSoldier->bNextAction = AI_ACTION_END_TURN; - } - - ActionDone( pSoldier ); - break; + case AI_ACTION_LOWER_GUN: + // for now, just do "action done" + InternalSoldierReadyWeapon(pSoldier,pSoldier->bDirection,TRUE); + HandleSight(pSoldier, SIGHT_LOOK ); + ActionDone( pSoldier ); + break; - case AI_ACTION_CLIMB_ROOF: - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Executing: AI_ACTION_CLIMB_ROOF"); + case AI_ACTION_RAISE_GUN: //Madd: action added for snipers to ready weapon and use vision range bonuses + SoldierReadyWeapon(pSoldier); + HandleSight(pSoldier, SIGHT_LOOK | SIGHT_RADIO); - if (pSoldier->bLevel == 0) - { - BeginSoldierClimbUpRoof( pSoldier ); - } - else - { - BeginSoldierClimbDownRoof( pSoldier ); - } - break; + //AXP 23.03.2007: Sniper deadlock fix + if ( pSoldier->bOrders == SNIPER && pSoldier->bLastAction == AI_ACTION_RAISE_GUN) + { + pSoldier->bNextAction = AI_ACTION_END_TURN; + } - case AI_ACTION_END_TURN: - ActionDone( pSoldier ); - if (gfTurnBasedAI) - { - EndAIGuysTurn( pSoldier ); - } - return( FALSE ); // nothing is in progress + ActionDone( pSoldier ); + break; - case AI_ACTION_TRAVERSE_DOWN: - if (gfTurnBasedAI) - { - EndAIGuysTurn( pSoldier ); - } - if ( pSoldier->ubProfile != NO_PROFILE ) - { - gMercProfiles[ pSoldier->ubProfile ].bSectorZ++; - gMercProfiles[ pSoldier->ubProfile ].fUseProfileInsertionInfo = FALSE; - } - TacticalRemoveSoldier( pSoldier->ubID ); - CheckForEndOfBattle( TRUE ); + case AI_ACTION_CLIMB_ROOF: + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Executing: AI_ACTION_CLIMB_ROOF"); - return( FALSE ); // nothing is in progress + if (pSoldier->bLevel == 0) + { + BeginSoldierClimbUpRoof( pSoldier ); + } + else + { + BeginSoldierClimbDownRoof( pSoldier ); + } + break; - case AI_ACTION_OFFER_SURRENDER: - // start the offer of surrender! - StartCivQuote( pSoldier ); - break; + case AI_ACTION_END_TURN: + ActionDone( pSoldier ); + if (gfTurnBasedAI) + { + EndAIGuysTurn( pSoldier ); + } + return( FALSE ); // nothing is in progress - default: + case AI_ACTION_TRAVERSE_DOWN: + if (gfTurnBasedAI) + { + EndAIGuysTurn( pSoldier ); + } + if ( pSoldier->ubProfile != NO_PROFILE ) + { + gMercProfiles[ pSoldier->ubProfile ].bSectorZ++; + gMercProfiles[ pSoldier->ubProfile ].fUseProfileInsertionInfo = FALSE; + } + TacticalRemoveSoldier( pSoldier->ubID ); + CheckForEndOfBattle( TRUE ); + + return( FALSE ); // nothing is in progress + + case AI_ACTION_OFFER_SURRENDER: + // start the offer of surrender! + StartCivQuote( pSoldier ); + break; + + default: #ifdef BETAVERSION - NumMessage("ExecuteAction - Illegal action type = ",pSoldier->bAction); + NumMessage("ExecuteAction - Illegal action type = ",pSoldier->bAction); #endif - return(FALSE); + return(FALSE); } // return status indicating execution of action was properly started @@ -2634,85 +2653,85 @@ void CheckForChangingOrders(SOLDIERTYPE *pSoldier) { switch( pSoldier->bAlertStatus ) { - case STATUS_GREEN: - if ( !CREATURE_OR_BLOODCAT( pSoldier ) ) + case STATUS_GREEN: + if ( !CREATURE_OR_BLOODCAT( pSoldier ) ) + { + if ( pSoldier->bTeam == CIV_TEAM && pSoldier->ubProfile != NO_PROFILE && pSoldier->bNeutral && gMercProfiles[ pSoldier->ubProfile ].sPreCombatGridNo != NOWHERE && pSoldier->ubCivilianGroup != QUEENS_CIV_GROUP ) { - if ( pSoldier->bTeam == CIV_TEAM && pSoldier->ubProfile != NO_PROFILE && pSoldier->bNeutral && gMercProfiles[ pSoldier->ubProfile ].sPreCombatGridNo != NOWHERE && pSoldier->ubCivilianGroup != QUEENS_CIV_GROUP ) - { - // must make them uncower first, then return to start location - pSoldier->bNextAction = AI_ACTION_END_COWER_AND_MOVE; - pSoldier->usNextActionData = gMercProfiles[ pSoldier->ubProfile ].sPreCombatGridNo; - gMercProfiles[ pSoldier->ubProfile ].sPreCombatGridNo = NOWHERE; - } - else if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) - { - pSoldier->bNextAction = AI_ACTION_STOP_COWERING; - pSoldier->usNextActionData = ANIM_STAND; - } - else - { - pSoldier->bNextAction = AI_ACTION_CHANGE_STANCE; - pSoldier->usNextActionData = ANIM_STAND; - } + // must make them uncower first, then return to start location + pSoldier->bNextAction = AI_ACTION_END_COWER_AND_MOVE; + pSoldier->usNextActionData = gMercProfiles[ pSoldier->ubProfile ].sPreCombatGridNo; + gMercProfiles[ pSoldier->ubProfile ].sPreCombatGridNo = NOWHERE; } - break; - case STATUS_YELLOW: - break; - default: - if ((pSoldier->bOrders == ONGUARD) || (pSoldier->bOrders == CLOSEPATROL)) + else if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) { - // crank up ONGUARD to CLOSEPATROL, and CLOSEPATROL to FARPATROL - pSoldier->bOrders++; // increase roaming range by 1 category + pSoldier->bNextAction = AI_ACTION_STOP_COWERING; + pSoldier->usNextActionData = ANIM_STAND; } - else if ( pSoldier->bTeam == MILITIA_TEAM && pSoldier->bOrders != SNIPER ) + else + { + pSoldier->bNextAction = AI_ACTION_CHANGE_STANCE; + pSoldier->usNextActionData = ANIM_STAND; + } + } + break; + case STATUS_YELLOW: + break; + default: + if ((pSoldier->bOrders == ONGUARD) || (pSoldier->bOrders == CLOSEPATROL)) + { + // crank up ONGUARD to CLOSEPATROL, and CLOSEPATROL to FARPATROL + pSoldier->bOrders++; // increase roaming range by 1 category + } + else if ( pSoldier->bTeam == MILITIA_TEAM && pSoldier->bOrders != SNIPER ) + { + // go on alert! + pSoldier->bOrders = SEEKENEMY; + } + else if ( CREATURE_OR_BLOODCAT( pSoldier ) ) + { + if (pSoldier->bOrders != STATIONARY && pSoldier->bOrders != ONCALL) { - // go on alert! pSoldier->bOrders = SEEKENEMY; } - else if ( CREATURE_OR_BLOODCAT( pSoldier ) ) - { - if (pSoldier->bOrders != STATIONARY && pSoldier->bOrders != ONCALL) - { - pSoldier->bOrders = SEEKENEMY; - } - } + } - if ( pSoldier->ubProfile == WARDEN ) - { - // Tixa - MakeClosestEnemyChosenOne(); - } - break; + if ( pSoldier->ubProfile == WARDEN ) + { + // Tixa + MakeClosestEnemyChosenOne(); + } + break; } } void InitAttackType(ATTACKTYPE *pAttack) { - // initialize the given bestAttack structure fields to their default values - pAttack->ubPossible = FALSE; - pAttack->ubOpponent = NOBODY; - pAttack->ubAimTime = 0; - pAttack->ubChanceToReallyHit = 0; - pAttack->sTarget = NOWHERE; - pAttack->iAttackValue = 0; - pAttack->ubAPCost = 0; + // initialize the given bestAttack structure fields to their default values + pAttack->ubPossible = FALSE; + pAttack->ubOpponent = NOBODY; + pAttack->ubAimTime = 0; + pAttack->ubChanceToReallyHit = 0; + pAttack->sTarget = NOWHERE; + pAttack->iAttackValue = 0; + pAttack->ubAPCost = 0; } void HandleInitialRedAlert( INT8 bTeam, UINT8 ubCommunicate) { -/* - if (ubCommunicate) - { - NetSend.msgType = NET_RED_ALERT; - SendNetData(ALL_NODES); - }*/ + /* + if (ubCommunicate) + { + NetSend.msgType = NET_RED_ALERT; + SendNetData(ALL_NODES); + }*/ - if ( gTacticalStatus.Team[bTeam].bAwareOfOpposition == FALSE ) - { - #ifdef JA2TESTVERSION + if ( gTacticalStatus.Team[bTeam].bAwareOfOpposition == FALSE ) + { +#ifdef JA2TESTVERSION ScreenMsg( FONT_MCOLOR_RED, MSG_ERROR, L"Enemies on team %d prompted to go on RED ALERT!", bTeam ); - #endif - } +#endif + } // if there is a stealth mission in progress here, and a panic trigger exists if ( bTeam == ENEMY_TEAM && (gTacticalStatus.fPanicFlags & PANIC_TRIGGERS_HERE) ) @@ -2725,7 +2744,7 @@ void HandleInitialRedAlert( INT8 bTeam, UINT8 ubCommunicate) { // alert Queen and Joe if they are around SOLDIERTYPE * pSoldier; - + pSoldier = FindSoldierByProfileID( QUEEN, FALSE ); if ( pSoldier ) { @@ -2739,57 +2758,57 @@ void HandleInitialRedAlert( INT8 bTeam, UINT8 ubCommunicate) } } - // open and close certain doors when this happens - //AffectDoors(OPENDOORS, MapExt[Status.cur_sector].opendoors); - //AffectDoors(CLOSEDOORS,MapExt[Status.cur_sector].closedoors); + // open and close certain doors when this happens + //AffectDoors(OPENDOORS, MapExt[Status.cur_sector].opendoors); + //AffectDoors(CLOSEDOORS,MapExt[Status.cur_sector].closedoors); - // remember enemies are alerted, prevent another red alert from happening - gTacticalStatus.Team[ bTeam ].bAwareOfOpposition = TRUE; + // remember enemies are alerted, prevent another red alert from happening + gTacticalStatus.Team[ bTeam ].bAwareOfOpposition = TRUE; } void ManChecksOnFriends(SOLDIERTYPE *pSoldier) { - UINT32 uiLoop; - SOLDIERTYPE *pFriend; - INT16 sDistVisible; + UINT32 uiLoop; + SOLDIERTYPE *pFriend; + INT16 sDistVisible; - // THIS ROUTINE SHOULD ONLY BE CALLED FOR SOLDIERS ON STATUS GREEN or YELLOW + // THIS ROUTINE SHOULD ONLY BE CALLED FOR SOLDIERS ON STATUS GREEN or YELLOW - // go through each soldier, looking for "friends" (soldiers on same side) - for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) - { - pFriend = MercSlots[ uiLoop ]; + // go through each soldier, looking for "friends" (soldiers on same side) + for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) + { + pFriend = MercSlots[ uiLoop ]; - if (!pFriend) - { - continue; - } + if (!pFriend) + { + continue; + } - // if this man is neutral / NOT on my side, he's not my friend - if (pFriend->bNeutral || (pSoldier->bSide != pFriend->bSide)) - continue; // next merc + // if this man is neutral / NOT on my side, he's not my friend + if (pFriend->bNeutral || (pSoldier->bSide != pFriend->bSide)) + continue; // next merc - // if this merc is actually ME - if (pFriend->ubID == pSoldier->ubID) - continue; // next merc + // if this merc is actually ME + if (pFriend->ubID == pSoldier->ubID) + continue; // next merc - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, pFriend->sGridNo, pFriend->bLevel, pFriend ); - // if we can see far enough to see this friend - if (PythSpacesAway(pSoldier->sGridNo,pFriend->sGridNo) <= sDistVisible) - { - // and can trace a line of sight to his x,y coordinates - //if (1) //*** SoldierToSoldierLineOfSightTest(pSoldier,pFriend,STRAIGHT,TRUE)) - if (SoldierToSoldierLineOfSightTest(pSoldier, pFriend, (UINT8)sDistVisible, TRUE)) - { + sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, pFriend->sGridNo, pFriend->bLevel, pFriend ); + // if we can see far enough to see this friend + if (PythSpacesAway(pSoldier->sGridNo,pFriend->sGridNo) <= sDistVisible) + { + // and can trace a line of sight to his x,y coordinates + //if (1) //*** SoldierToSoldierLineOfSightTest(pSoldier,pFriend,STRAIGHT,TRUE)) + if (SoldierToSoldierLineOfSightTest(pSoldier, pFriend, (UINT8)sDistVisible, TRUE)) + { // if my friend is in battle or something is clearly happening there if ((pFriend->bAlertStatus >= STATUS_RED) || pFriend->bUnderFire || (pFriend->bLife < OKLIFE)) { - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS STR16 tempstr; sprintf(tempstr,"%s sees %s on alert, goes to RED ALERT!",pSoldier->name,pFriend->name ); AIPopMessage(tempstr); - #endif +#endif pSoldier->bAlertStatus = STATUS_RED; CheckForChangingOrders(pSoldier); @@ -2803,10 +2822,10 @@ void ManChecksOnFriends(SOLDIERTYPE *pSoldier) if ((pFriend->bAlertStatus == STATUS_YELLOW) && (pSoldier->bAlertStatus < STATUS_YELLOW)) { - #ifdef TESTVERSION +#ifdef TESTVERSION sprintf(tempstr,"TEST MSG: %s sees %s listening, goes to YELLOW ALERT!",pSoldier->name,ExtMen[pFriend->ubID].name); PopMessage(tempstr); - #endif +#endif pSoldier->bAlertStatus = STATUS_YELLOW; // also get suspicious SetNewSituation( pSoldier ); pSoldier->sNoiseGridno = pFriend->sGridNo; // pretend FRIEND made noise @@ -2814,9 +2833,9 @@ void ManChecksOnFriends(SOLDIERTYPE *pSoldier) // keep check other friends, too, in case any are already on RED } } - } - } - } + } + } + } } @@ -2827,12 +2846,20 @@ void SetNewSituation( SOLDIERTYPE * pSoldier ) if ( pSoldier->ubQuoteRecord == 0 && !gTacticalStatus.fAutoBandageMode && !(pSoldier->bNeutral && gTacticalStatus.uiFlags & ENGAGED_IN_CONV) ) { // allow new situation to be set - pSoldier->bNewSituation = IS_NEW_SITUATION; + if (gTacticalStatus.ubAttackBusyCount > 0) + { + DebugAttackBusy( "@#!% NOT setting NewSituation because still busy attacking.\n" ); + } + else + { + // 0verhaul: Let's see if we can do without this. + // pSoldier->bNewSituation = IS_NEW_SITUATION; + } - if ( gTacticalStatus.ubAttackBusyCount != 0 ) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("BBBBBB bNewSituation is set for %d when ABC !=0.", pSoldier->ubID ) ); - } + if ( gTacticalStatus.ubAttackBusyCount != 0 ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("BBBBBB bNewSituation is set for %d when ABC !=0.", pSoldier->ubID ) ); + } if ( !(gTacticalStatus.uiFlags & INCOMBAT) || (gTacticalStatus.uiFlags & REALTIME) ) { @@ -2859,12 +2886,12 @@ void HandleAITacticalTraversal( SOLDIERTYPE * pSoldier ) pSoldier->ubQuoteActionID = 0; } - #ifdef TESTAICONTROL - if (gfTurnBasedAI) - { - DebugAI( String("Ending turn for %d because traversing out", pSoldier->ubID ) ); - } - #endif +#ifdef TESTAICONTROL + if (gfTurnBasedAI) + { + DebugAI( String("Ending turn for %d because traversing out", pSoldier->ubID ) ); + } +#endif EndAIGuysTurn( pSoldier ); RemoveManAsTarget( pSoldier ); @@ -2893,7 +2920,7 @@ void HandleAITacticalTraversal( SOLDIERTYPE * pSoldier ) --iMapY; break; } - + SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( iMapX, iMapY ) ] ); switch( pSoldier->ubSoldierClass ) @@ -2916,4 +2943,4 @@ void HandleAITacticalTraversal( SOLDIERTYPE * pSoldier ) TacticalRemoveSoldier( pSoldier->ubID ); } CheckForEndOfBattle( TRUE ); -} \ No newline at end of file +} diff --git a/TacticalAI/AIUtils.cpp b/TacticalAI/AIUtils.cpp index 6993b3cf..4c0c0428 100644 --- a/TacticalAI/AIUtils.cpp +++ b/TacticalAI/AIUtils.cpp @@ -17,6 +17,12 @@ #include "Points.h" #include "GameSettings.h" #include "Buildings.h" + #include "Soldier macros.h" + #include "Render Fun.h" + #include "strategicmap.h" + #include "environment.h" + #include "lighting.h" + #include "Soldier Create.h" #endif // @@ -173,7 +179,7 @@ UINT8 ShootingStanceChange( SOLDIERTYPE * pSoldier, ATTACKTYPE * pAttack, INT8 b UINT16 usRealAnimState, usBestAnimState; INT8 bBestStanceDiff=-1; - INT8 bLoop, bStanceNum, bStanceDiff, bAPsAfterAttack; + INT8 bLoop, bStanceNum, bStanceDiff, bAPsAfterAttack, bCurAimTime; UINT32 uiChanceOfDamage, uiBestChanceOfDamage, uiCurrChanceOfDamage; UINT32 uiStanceBonus, uiMinimumStanceBonusPerChange = 20 - 3 * pAttack->ubAimTime; INT32 iRange; @@ -181,7 +187,7 @@ UINT8 ShootingStanceChange( SOLDIERTYPE * pSoldier, ATTACKTYPE * pAttack, INT8 b bStanceNum = 0; uiCurrChanceOfDamage = 0; - bAPsAfterAttack = pSoldier->bActionPoints - pAttack->ubAPCost - GetAPsToReadyWeapon( pSoldier, pSoldier->usAnimState ); + bAPsAfterAttack = pSoldier->bActionPoints - MinAPsToAttack( pSoldier, pAttack->sTarget, ADDTURNCOST, 1); if (bAPsAfterAttack < AP_CROUCH) { return( 0 ); @@ -241,7 +247,15 @@ UINT8 ShootingStanceChange( SOLDIERTYPE * pSoldier, ATTACKTYPE * pAttack, INT8 b break; } - uiChanceOfDamage = SoldierToLocationChanceToGetThrough( pSoldier, pAttack->sTarget, pSoldier->bTargetLevel, pSoldier->bTargetCubeLevel, pAttack->ubOpponent ) * CalcChanceToHitGun( pSoldier, pAttack->sTarget, pAttack->ubAimTime, AIM_SHOT_TORSO ) / 100; + // Hack: Assumes the cost to reach the target stance from the current stance is the same as going back. Probably true. + bCurAimTime = __min( bAPsAfterAttack - GetAPsToChangeStance( pSoldier, bStanceNum), pAttack->ubAimTime); + // If can't fire at all from this stance, don't bother with the chances of hitting + if (bCurAimTime < 0) + { + continue; + } + + uiChanceOfDamage = SoldierToLocationChanceToGetThrough( pSoldier, pAttack->sTarget, pSoldier->bTargetLevel, pSoldier->bTargetCubeLevel, pAttack->ubOpponent ) * CalcChanceToHitGun( pSoldier, pAttack->sTarget, bCurAimTime, AIM_SHOT_TORSO ) / 100; if (uiChanceOfDamage > 0) { uiStanceBonus = 0; diff --git a/TacticalAI/Attacks.cpp b/TacticalAI/Attacks.cpp index c284e36a..5e53b44e 100644 --- a/TacticalAI/Attacks.cpp +++ b/TacticalAI/Attacks.cpp @@ -1,24 +1,31 @@ #ifdef PRECOMPILEDHEADERS - #include "AI All.h" +#include "AI All.h" #else - #include "ai.h" - #include "Weapons.h" - #include "opplist.h" - #include "AIInternals.h" - #include "LOS.h" - #include "Physics.h" - #include "Items.h" - #include "Weapons.h" - #include "Spread Burst.h" - #include "overhead.h" - #include "SkillCheck.h" - #include "Soldier Profile.h" - #include "Isometric Utils.h" +#include "ai.h" +#include "Weapons.h" +#include "opplist.h" +#include "AIInternals.h" +#include "LOS.h" +#include "Physics.h" +#include "Items.h" +#include "Weapons.h" +#include "Spread Burst.h" +#include "overhead.h" +#include "SkillCheck.h" +#include "Soldier Profile.h" +#include "Isometric Utils.h" +#include "Soldier macros.h" +#include "PATHAI.H" +#include "GameSettings.h" +#include "strategicmap.h" +#include "environment.h" +#include "lighting.h" +#include "Sound Control.h" #endif extern INT16 DirIncrementer[8]; -// +// // CJC DG->JA2 conversion notes // // Still commented out: @@ -40,13 +47,13 @@ void LoadWeaponIfNeeded(SOLDIERTYPE *pSoldier) usInHand = pSoldier->inv[HANDPOS].usItem; - if ( IsGrenadeLauncherAttached(&pSoldier->inv[HANDPOS]) ) + if ( IsGrenadeLauncherAttached(&pSoldier->inv[HANDPOS]) ) usInHand = GetAttachedGrenadeLauncher(&pSoldier->inv[HANDPOS]); // if he's got a MORTAR in his hand, make sure he has a MORTARSHELL avail. if (Item[usInHand].mortar ) { -// bPayloadPocket = FindObj( pSoldier, MORTAR_SHELL ); + // bPayloadPocket = FindObj( pSoldier, MORTAR_SHELL ); bPayloadPocket = FindLaunchable( pSoldier, usInHand ); if (bPayloadPocket == NO_SLOT) { @@ -74,7 +81,7 @@ void LoadWeaponIfNeeded(SOLDIERTYPE *pSoldier) bPayloadPocket = FindLaunchable (pSoldier, usInHand ); if (bPayloadPocket == NO_SLOT) { - return; // no grenades, can't fire + return; // no grenades, can't fire } } else if (Item[usInHand].cannon ) @@ -119,92 +126,93 @@ void LoadWeaponIfNeeded(SOLDIERTYPE *pSoldier) void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUnseen) { - UINT32 uiLoop; - INT32 iAttackValue; - INT32 iThreatValue; - INT32 iHitRate,iBestHitRate,iPercentBetter; - INT32 iEstDamage; - UINT8 ubRawAPCost,ubMinAPcost,ubMaxPossibleAimTime,ubAimTime,ubBestAimTime; - UINT8 ubChanceToHit,ubChanceToGetThrough,ubChanceToReallyHit,ubBestChanceToHit = 0; - SOLDIERTYPE *pOpponent; - UINT8 ubBurstAPs; + UINT32 uiLoop; + INT32 iAttackValue; + INT32 iThreatValue; + INT32 iHitRate,iBestHitRate,iPercentBetter; + INT32 iEstDamage; + UINT8 ubRawAPCost,ubMinAPcost,ubMaxPossibleAimTime,ubAimTime,ubBestAimTime; + UINT8 ubChanceToHit,ubChanceToGetThrough,ubChanceToReallyHit,ubBestChanceToHit = 0; + SOLDIERTYPE *pOpponent; + UINT8 ubBurstAPs; - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalcBestShot"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalcBestShot"); - ubBestChanceToHit = ubBestAimTime = ubChanceToHit = 0; + ubBestChanceToHit = ubBestAimTime = ubChanceToHit = 0; - pSoldier->usAttackingWeapon = pSoldier->inv[HANDPOS].usItem; - pSoldier->bWeaponMode = WM_NORMAL; + pSoldier->usAttackingWeapon = pSoldier->inv[HANDPOS].usItem; + pSoldier->bWeaponMode = WM_NORMAL; - ubBurstAPs = CalcAPsToBurst( CalcActionPoints( pSoldier ), &(pSoldier->inv[HANDPOS]) ); + ubBurstAPs = CalcAPsToBurst( CalcActionPoints( pSoldier ), &(pSoldier->inv[HANDPOS]) ); - InitAttackType(pBestShot); // set all structure fields to defaults + InitAttackType(pBestShot); // set all structure fields to defaults - // hang a pointer into active soldier's personal opponent list - //pbPersOL = &(pSoldier->bOppList[0]); + // hang a pointer into active soldier's personal opponent list + //pbPersOL = &(pSoldier->bOppList[0]); - // determine which attack against which target has the greatest attack value - for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) - { - pOpponent = MercSlots[ uiLoop ]; + // determine which attack against which target has the greatest attack value + for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) + { + pOpponent = MercSlots[ uiLoop ]; - // if this merc is inactive, at base, on assignment, or dead - if (!pOpponent || !pOpponent->bLife) - continue; // next merc + // if this merc is inactive, at base, on assignment, or dead + if (!pOpponent || !pOpponent->bLife) + continue; // next merc - // if this man is neutral / on the same side, he's not an opponent - if ( CONSIDERED_NEUTRAL( pSoldier, pOpponent ) || (pSoldier->bSide == pOpponent->bSide)) - continue; // next merc + // if this man is neutral / on the same side, he's not an opponent + if ( CONSIDERED_NEUTRAL( pSoldier, pOpponent ) || (pSoldier->bSide == pOpponent->bSide)) + continue; // next merc - // if this opponent is not currently in sight (ignore known but unseen!) - if ((pSoldier->bOppList[pOpponent->ubID] != SEEN_CURRENTLY && !shootUnseen)) //guys we can't see - { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("CalcBestShot: soldier = %d, target = %d, skip guys we can't see, shootUnseen = %d, personal opplist = %d",pSoldier->ubID, pOpponent->ubID, shootUnseen, pSoldier->bOppList[pOpponent->ubID])); - continue; // next opponent - } - if ((pSoldier->bOppList[pOpponent->ubID] != SEEN_CURRENTLY && gbPublicOpplist[pSoldier->bTeam][pOpponent->ubID] != SEEN_CURRENTLY)) // guys nobody sees - { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("CalcBestShot: soldier = %d, target = %d, skip guys nobody sees, shootUnseen = %d, public opplist = %d",pSoldier->ubID, pOpponent->ubID, shootUnseen,gbPublicOpplist[pSoldier->bTeam][pOpponent->ubID])); - continue; // next opponent - } + // if this opponent is not currently in sight (ignore known but unseen!) + if ((pSoldier->bOppList[pOpponent->ubID] != SEEN_CURRENTLY && !shootUnseen)) //guys we can't see + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("CalcBestShot: soldier = %d, target = %d, skip guys we can't see, shootUnseen = %d, personal opplist = %d",pSoldier->ubID, pOpponent->ubID, shootUnseen, pSoldier->bOppList[pOpponent->ubID])); + continue; // next opponent + } + if ((pSoldier->bOppList[pOpponent->ubID] != SEEN_CURRENTLY && gbPublicOpplist[pSoldier->bTeam][pOpponent->ubID] != SEEN_CURRENTLY)) // guys nobody sees + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("CalcBestShot: soldier = %d, target = %d, skip guys nobody sees, shootUnseen = %d, public opplist = %d",pSoldier->ubID, pOpponent->ubID, shootUnseen,gbPublicOpplist[pSoldier->bTeam][pOpponent->ubID])); + continue; // next opponent + } - // Special stuff for Carmen the bounty hunter - if (pSoldier->bAttitude == ATTACKSLAYONLY && pOpponent->ubProfile != SLAY) - continue; // next opponent + // Special stuff for Carmen the bounty hunter + if (pSoldier->bAttitude == ATTACKSLAYONLY && pOpponent->ubProfile != SLAY) + continue; // next opponent #ifdef DEBUGATTACKS - DebugAI( String( "%s sees %s at gridno %d\n",pSoldier->name,ExtMen[pOpponent->ubID].name,pOpponent->sGridNo ) ); + DebugAI( String( "%s sees %s at gridno %d\n",pSoldier->name,ExtMen[pOpponent->ubID].name,pOpponent->sGridNo ) ); #endif - // calculate minimum action points required to shoot at this opponent - if ( !Weapon[pSoldier->usAttackingWeapon].NoSemiAuto ) + // calculate minimum action points required to shoot at this opponent + // if ( !Weapon[pSoldier->usAttackingWeapon].NoSemiAuto ) ubMinAPcost = MinAPsToAttack(pSoldier,pOpponent->sGridNo,ADDTURNCOST); - else - ubMinAPcost = CalcAPsToAutofire( CalcActionPoints( pSoldier ), &(pSoldier->inv[HANDPOS]), 3 ); + // What the.... The APs to attack on the HandleItem side does not make a test like this. It always uses the MinAPs as a base. + // else + // ubMinAPcost = CalcAPsToAutofire( CalcActionPoints( pSoldier ), &(pSoldier->inv[HANDPOS]), 3 ); - //NumMessage("MinAPcost to shoot this opponent = ",ubMinAPcost); + //NumMessage("MinAPcost to shoot this opponent = ",ubMinAPcost); - // if we don't have enough APs left to shoot even a snap-shot at this guy - if (ubMinAPcost > pSoldier->bActionPoints) - continue; // next opponent + // if we don't have enough APs left to shoot even a snap-shot at this guy + if (ubMinAPcost > pSoldier->bActionPoints) + continue; // next opponent - //KeepInterfaceGoing(); + //KeepInterfaceGoing(); - // calculate chance to get through the opponent's cover (if any) + // calculate chance to get through the opponent's cover (if any) ubChanceToGetThrough = AISoldierToSoldierChanceToGetThrough( pSoldier, pOpponent ); -// ubChanceToGetThrough = ChanceToGetThrough(pSoldier,pOpponent->sGridNo,NOTFAKE,ACTUAL,TESTWALLS,9999,M9PISTOL,NOT_FOR_LOS); + // ubChanceToGetThrough = ChanceToGetThrough(pSoldier,pOpponent->sGridNo,NOTFAKE,ACTUAL,TESTWALLS,9999,M9PISTOL,NOT_FOR_LOS); - //NumMessage("Chance to get through = ",ubChanceToGetThrough); + //NumMessage("Chance to get through = ",ubChanceToGetThrough); - // if we can't possibly get through all the cover - if (ubChanceToGetThrough == 0) - continue; // next opponent + // if we can't possibly get through all the cover + if (ubChanceToGetThrough == 0) + continue; // next opponent - if ( (pSoldier->uiStatusFlags & SOLDIER_MONSTER) && (pSoldier->ubBodyType != QUEENMONSTER ) ) - { + if ( (pSoldier->uiStatusFlags & SOLDIER_MONSTER) && (pSoldier->ubBodyType != QUEENMONSTER ) ) + { STRUCTURE_FILE_REF * pStructureFileRef; UINT16 usAnimSurface; @@ -235,154 +243,154 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns continue; } } - } - - // calc next attack's minimum shooting cost (excludes readying & turning) - ubRawAPCost = MinAPsToShootOrStab(pSoldier,pOpponent->sGridNo,FALSE); - - if (pOpponent->sGridNo != pSoldier->sLastTarget) - { - // raw AP cost calculation included cost of changing target! - ubRawAPCost -= AP_CHANGE_TARGET; - } - - iBestHitRate = 0; // reset best hit rate to minimum - - // calculate the maximum possible aiming time - - if ( TANK( pSoldier ) ) - { - ubMaxPossibleAimTime = pSoldier->bActionPoints - ubMinAPcost; - - // always burst - if ( ubMaxPossibleAimTime < ubBurstAPs ) - { - // should this be a return instead? - continue; - } - // bursts aren't aimed - ubMaxPossibleAimTime = 0; - - } - else - { - ubMaxPossibleAimTime = min(AllowedAimingLevels(pSoldier),pSoldier->bActionPoints - ubMinAPcost); - } - - // consider the various aiming times - if ( !Weapon[pSoldier->usAttackingWeapon].NoSemiAuto ) - { - for (ubAimTime = AP_MIN_AIM_ATTACK; ubAimTime <= ubMaxPossibleAimTime; ubAimTime++) - { - //HandleMyMouseCursor(KEYBOARDALSO); - - //NumMessage("ubAimTime = ",ubAimTime); - - ubChanceToHit = (UINT8) AICalcChanceToHitGun(pSoldier,pOpponent->sGridNo,ubAimTime, AIM_SHOT_TORSO); - // ExtMen[pOpponent->ubID].haveStats = TRUE; - //NumMessage("chance to Hit = ",ubChanceToHit); - - //sprintf(tempstr,"Vs. %s, at AimTime %d, ubChanceToHit = %d",ExtMen[pOpponent->ubID].name,ubAimTime,ubChanceToHit); - //PopMessage(tempstr); - - iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime); - //NumMessage("hitRate = ",iHitRate); - - // if aiming for this amount of time produces a better hit rate - if (iHitRate > iBestHitRate) - { - iBestHitRate = iHitRate; - ubBestAimTime = ubAimTime; - ubBestChanceToHit = ubChanceToHit; - } } - } - else - { - ubAimTime = AP_MIN_AIM_ATTACK; - ubChanceToHit = (UINT8) AICalcChanceToHitGun(pSoldier,pOpponent->sGridNo,ubAimTime, AIM_SHOT_TORSO); - iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime); - iBestHitRate = iHitRate; - ubBestAimTime = ubAimTime; - ubBestChanceToHit = ubChanceToHit; - } + // calc next attack's minimum shooting cost (excludes readying & turning) + ubRawAPCost = MinAPsToShootOrStab(pSoldier,pOpponent->sGridNo,FALSE); - // if we can't get any kind of hit rate at all - if (iBestHitRate == 0) - continue; // next opponent + if (pOpponent->sGridNo != pSoldier->sLastTarget) + { + // raw AP cost calculation included cost of changing target! + ubRawAPCost -= AP_CHANGE_TARGET; + } - // calculate chance to REALLY hit: shoot accurately AND get past cover - ubChanceToReallyHit = (ubBestChanceToHit * ubChanceToGetThrough) / 100; + iBestHitRate = 0; // reset best hit rate to minimum - // if we can't REALLY hit at all - if (ubChanceToReallyHit == 0) - continue; // next opponent + // calculate the maximum possible aiming time - // really limit knife throwing so it doesn't look wrong - if ( Item[ pSoldier->usAttackingWeapon ].usItemClass == IC_THROWING_KNIFE && (ubChanceToReallyHit < 30 || ( PythSpacesAway( pSoldier->sGridNo, pOpponent->sGridNo ) > CalcMaxTossRange( pSoldier, pSoldier->usAttackingWeapon, FALSE ) )))// Madd / 2 ) ) ) - continue; // don't bother... next opponent + if ( TANK( pSoldier ) ) + { + ubMaxPossibleAimTime = pSoldier->bActionPoints - ubMinAPcost; - // calculate this opponent's threat value (factor in my cover from him) - iThreatValue = CalcManThreatValue(pOpponent,pSoldier->sGridNo,TRUE,pSoldier); + // always burst + if ( ubMaxPossibleAimTime < ubBurstAPs ) + { + // should this be a return instead? + continue; + } + // bursts aren't aimed + ubMaxPossibleAimTime = 0; - // estimate the damage this shot would do to this opponent - iEstDamage = EstimateShotDamage(pSoldier,pOpponent,ubBestChanceToHit); - //NumMessage("SHOT EstDamage = ",iEstDamage); + } + else + { + ubMaxPossibleAimTime = min(AllowedAimingLevels(pSoldier),pSoldier->bActionPoints - ubMinAPcost); + } - // calculate the combined "attack value" for this opponent - // highest possible value before division should be about 1.8 billion... - // normal value before division should be about 5 million... - iAttackValue = (iEstDamage * iBestHitRate * ubChanceToReallyHit * iThreatValue) / 1000; - //NumMessage("SHOT AttackValue = ",iAttackValue / 1000); + // consider the various aiming times + if ( !Weapon[pSoldier->usAttackingWeapon].NoSemiAuto ) + { + for (ubAimTime = AP_MIN_AIM_ATTACK; ubAimTime <= ubMaxPossibleAimTime; ubAimTime++) + { + //HandleMyMouseCursor(KEYBOARDALSO); - // special stuff for assassins to ignore militia more - if ( pSoldier->ubProfile >= JIM && pSoldier->ubProfile <= TYRONE && pOpponent->bTeam == MILITIA_TEAM ) - { - iAttackValue /= 2; - } + //NumMessage("ubAimTime = ",ubAimTime); + + ubChanceToHit = (UINT8) AICalcChanceToHitGun(pSoldier,pOpponent->sGridNo,ubAimTime, AIM_SHOT_TORSO); + // ExtMen[pOpponent->ubID].haveStats = TRUE; + //NumMessage("chance to Hit = ",ubChanceToHit); + + //sprintf(tempstr,"Vs. %s, at AimTime %d, ubChanceToHit = %d",ExtMen[pOpponent->ubID].name,ubAimTime,ubChanceToHit); + //PopMessage(tempstr); + + iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime); + //NumMessage("hitRate = ",iHitRate); + + // if aiming for this amount of time produces a better hit rate + if (iHitRate > iBestHitRate) + { + iBestHitRate = iHitRate; + ubBestAimTime = ubAimTime; + ubBestChanceToHit = ubChanceToHit; + } + } + } + else + { + ubAimTime = AP_MIN_AIM_ATTACK; + ubChanceToHit = (UINT8) AICalcChanceToHitGun(pSoldier,pOpponent->sGridNo,ubAimTime, AIM_SHOT_TORSO); + iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime); + + iBestHitRate = iHitRate; + ubBestAimTime = ubAimTime; + ubBestChanceToHit = ubChanceToHit; + } + + // if we can't get any kind of hit rate at all + if (iBestHitRate == 0) + continue; // next opponent + + // calculate chance to REALLY hit: shoot accurately AND get past cover + ubChanceToReallyHit = (ubBestChanceToHit * ubChanceToGetThrough) / 100; + + // if we can't REALLY hit at all + if (ubChanceToReallyHit == 0) + continue; // next opponent + + // really limit knife throwing so it doesn't look wrong + if ( Item[ pSoldier->usAttackingWeapon ].usItemClass == IC_THROWING_KNIFE && (ubChanceToReallyHit < 30 || ( PythSpacesAway( pSoldier->sGridNo, pOpponent->sGridNo ) > CalcMaxTossRange( pSoldier, pSoldier->usAttackingWeapon, FALSE ) )))// Madd / 2 ) ) ) + continue; // don't bother... next opponent + + // calculate this opponent's threat value (factor in my cover from him) + iThreatValue = CalcManThreatValue(pOpponent,pSoldier->sGridNo,TRUE,pSoldier); + + // estimate the damage this shot would do to this opponent + iEstDamage = EstimateShotDamage(pSoldier,pOpponent,ubBestChanceToHit); + //NumMessage("SHOT EstDamage = ",iEstDamage); + + // calculate the combined "attack value" for this opponent + // highest possible value before division should be about 1.8 billion... + // normal value before division should be about 5 million... + iAttackValue = (iEstDamage * iBestHitRate * ubChanceToReallyHit * iThreatValue) / 1000; + //NumMessage("SHOT AttackValue = ",iAttackValue / 1000); + + // special stuff for assassins to ignore militia more + if ( pSoldier->ubProfile >= JIM && pSoldier->ubProfile <= TYRONE && pOpponent->bTeam == MILITIA_TEAM ) + { + iAttackValue /= 2; + } #ifdef DEBUGATTACKS - DebugAI( String( "CalcBestShot: best AttackValue vs %d = %d\n",uiLoop,iAttackValue ) ); + DebugAI( String( "CalcBestShot: best AttackValue vs %d = %d\n",uiLoop,iAttackValue ) ); #endif - // if we can hurt the guy, OR probably not, but at least it's our best - // chance to actually hit him and maybe scare him, knock him down, etc. - if ((iAttackValue > 0) || (ubChanceToReallyHit > pBestShot->ubChanceToReallyHit)) - { - // if there already was another viable target - if (pBestShot->ubChanceToReallyHit > 0) - { - // OK, how does our chance to hit him compare to the previous best one? - iPercentBetter = ((ubChanceToReallyHit * 100) / pBestShot->ubChanceToReallyHit) - 100; + // if we can hurt the guy, OR probably not, but at least it's our best + // chance to actually hit him and maybe scare him, knock him down, etc. + if ((iAttackValue > 0) || (ubChanceToReallyHit > pBestShot->ubChanceToReallyHit)) + { + // if there already was another viable target + if (pBestShot->ubChanceToReallyHit > 0) + { + // OK, how does our chance to hit him compare to the previous best one? + iPercentBetter = ((ubChanceToReallyHit * 100) / pBestShot->ubChanceToReallyHit) - 100; - // if this chance to really hit is more than 50% worse, and the other - // guy is conscious at all - if ((iPercentBetter < -PERCENT_TO_IGNORE_THREAT) && (Menptr[pBestShot->ubOpponent].bLife >= OKLIFE)) - // then stick with the older guy as the better target - continue; + // if this chance to really hit is more than 50% worse, and the other + // guy is conscious at all + if ((iPercentBetter < -PERCENT_TO_IGNORE_THREAT) && (Menptr[pBestShot->ubOpponent].bLife >= OKLIFE)) + // then stick with the older guy as the better target + continue; - // if this chance to really hit between 50% worse to 50% better - if (iPercentBetter < PERCENT_TO_IGNORE_THREAT) + // if this chance to really hit between 50% worse to 50% better + if (iPercentBetter < PERCENT_TO_IGNORE_THREAT) { - // then the one with the higher ATTACK VALUE is the better target - if (iAttackValue < pBestShot->iAttackValue) - // the previous guy is more important since he's more dangerous - continue; // next opponent + // then the one with the higher ATTACK VALUE is the better target + if (iAttackValue < pBestShot->iAttackValue) + // the previous guy is more important since he's more dangerous + continue; // next opponent } - } + } - // OOOF! That was a lot of work! But we've got a new best target! - pBestShot->ubPossible = TRUE; - pBestShot->ubOpponent = pOpponent->ubID; - pBestShot->ubAimTime = ubBestAimTime; - pBestShot->ubChanceToReallyHit = ubChanceToReallyHit; - pBestShot->sTarget = pOpponent->sGridNo; - pBestShot->bTargetLevel = pOpponent->bLevel; - pBestShot->iAttackValue = iAttackValue; - pBestShot->ubAPCost = ubMinAPcost + ubBestAimTime; - } - } + // OOOF! That was a lot of work! But we've got a new best target! + pBestShot->ubPossible = TRUE; + pBestShot->ubOpponent = pOpponent->ubID; + pBestShot->ubAimTime = ubBestAimTime; + pBestShot->ubChanceToReallyHit = ubChanceToReallyHit; + pBestShot->sTarget = pOpponent->sGridNo; + pBestShot->bTargetLevel = pOpponent->bLevel; + pBestShot->iAttackValue = iAttackValue; + pBestShot->ubAPCost = ubMinAPcost; + } + } } // JA2Gold: added @@ -395,7 +403,7 @@ BOOLEAN CloseEnoughForGrenadeToss( INT16 sGridNo, INT16 sGridNo2 ) if (sGridNo == sGridNo2 ) { - // checking the same space; if there is a closed door next to location in ANY direction then forget it + // checking the same space; if there is a closed door next to location in ANY direction then forget it // (could be the player closed a door on us) for (bDirection = 0; bDirection < NUM_WORLD_DIRECTIONS; bDirection++) { @@ -420,7 +428,7 @@ BOOLEAN CloseEnoughForGrenadeToss( INT16 sGridNo, INT16 sGridNo2 ) // we are within 1 space diagonally or at most 2 horizontally or vertically, // so we can now do a loop safely - + sTempGridNo = sGridNo; sXPos = CenterX( sGridNo ); @@ -501,14 +509,14 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) if (Item[usInHand].mortar ) { DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"calcbestthrow: buddy's got a mortar"); - // bPayloadPocket = FindObj( pSoldier, MORTAR_SHELL ); + // bPayloadPocket = FindObj( pSoldier, MORTAR_SHELL ); bPayloadPocket = FindLaunchable ( pSoldier, usInHand ); if (bPayloadPocket == NO_SLOT) { return; // no shells, can't fire the MORTAR } ubSafetyMargin = (UINT8)Explosive[ Item[ pSoldier->inv[bPayloadPocket].usItem ].ubClassIndex ].ubRadius; - } + } // if he's got a GL in his hand, make sure he has some type of GRENADE avail. else if (Item[usInHand].grenadelauncher ) { @@ -534,7 +542,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) bPayloadPocket = FindLaunchable ( pSoldier, usInHand ); if (bPayloadPocket == NO_SLOT) { - return; // no ammo, can't fire + return; // no ammo, can't fire } ubSafetyMargin = (UINT8)Explosive[ Item[ pSoldier->inv[bPayloadPocket].usItem ].ubClassIndex ].ubRadius; } @@ -545,7 +553,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) bPayloadPocket = FindLaunchable ( pSoldier, usInHand ); if (bPayloadPocket == NO_SLOT) { - return; // no ammo, can't fire + return; // no ammo, can't fire } ubSafetyMargin = (UINT8)Explosive[ Item[ pSoldier->inv[bPayloadPocket].usItem ].ubClassIndex ].ubRadius; @@ -556,7 +564,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) // return; // no grenades, can't fire the GLAUNCHER //} //ubSafetyMargin = Explosive[ Item[ TANK_SHELL ].ubClassIndex ].ubRadius; - + } else { @@ -594,7 +602,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) /* // if this soldier is inactive, at base, on assignment, or dead if (!Menptr[ubLoop].bActive || !Menptr[ubLoop].bInSector || !Menptr[ubLoop].bLife) - continue; // next soldier + continue; // next soldier */ // if this man is neutral / NOT on the same side, he's not a friend @@ -627,15 +635,15 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) { continue; // next soldier } - + /* // if this soldier is inactive, at base, on assignment, or dead if (!pOpponent->bActive || !pOpponent->bInSector || !pOpponent->bLife) - continue; // next soldier + continue; // next soldier */ // if this man is neutral / on the same side, he's not an opponent - if ( CONSIDERED_NEUTRAL( pSoldier, pOpponent ) || (pSoldier->bSide == pOpponent->bSide)) + if ( CONSIDERED_NEUTRAL( pSoldier, pOpponent ) || (pSoldier->bSide == pOpponent->bSide)) { continue; // next soldier } @@ -666,7 +674,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) /* if (bPersOL != SEEN_CURRENTLY && bPersOL != SEEN_LAST_TURN) // if not in sight right now { - continue; // next soldier + continue; // next soldier } */ if (bPersOL == SEEN_CURRENTLY) @@ -683,7 +691,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) /* if ( pOpponent->sGridNo == gsLastKnownOppLoc[ pSoldier->ubID ][ pOpponent->ubID ] ) { - continue; + continue; } else */ if ( !CloseEnoughForGrenadeToss( pOpponent->sGridNo, gsLastKnownOppLoc[ pSoldier->ubID ][ pOpponent->ubID ] ) ) @@ -694,11 +702,11 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) sOpponentTile[ubOpponentCnt] = gsLastKnownOppLoc[ pSoldier->ubID ][ pOpponent->ubID ]; bOpponentLevel[ubOpponentCnt] = gbLastKnownOppLevel[ pSoldier->ubID ][ pOpponent->ubID ]; - // JA2Gold: commented out + // JA2Gold: commented out /* if ( SpacesAway( pOpponent->sGridNo, gsLastKnownOppLoc[ pSoldier->ubID ][ pOpponent->ubID ] ) > 2 ) { - continue; + continue; } sOpponentTile[ubOpponentCnt] = gsLastKnownOppLoc[ pSoldier->ubID ][ pOpponent->ubID ]; bOpponentLevel[ubOpponentCnt] = gbLastKnownOppLevel[ pSoldier->ubID ][ pOpponent->ubID ]; @@ -706,7 +714,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) } else if (bPersOL == HEARD_LAST_TURN ) { - // cheat; only allow throw if person is REALLY within 2 tiles of where last seen + // cheat; only allow throw if person is REALLY within 2 tiles of where last seen // screen out some ppl who have thrown if ( PreRandom( 3 ) == 0 ) @@ -721,9 +729,9 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) /* if ( pOpponent->sGridNo == gsLastKnownOppLoc[ pSoldier->ubID ][ pOpponent->ubID ] ) { - continue; + continue; } - else + else */ if ( !CloseEnoughForGrenadeToss( pOpponent->sGridNo, gsLastKnownOppLoc[ pSoldier->ubID ][ pOpponent->ubID ] ) ) { @@ -751,7 +759,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) iOppThreatValue[ubOpponentCnt] = CalcManThreatValue(pOpponent,pSoldier->sGridNo,FALSE,pSoldier); ubOpponentCnt++; - } + } //NumMessage("ubOpponentCnt = ",ubOpponentCnt); @@ -761,28 +769,28 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) { switch( ubDiff ) { - case 0: - case 1: - // they won't use them until they have 2+ opponents as long as half life left - if ((ubOpponentCnt < 2) && (pSoldier->bLife > (pSoldier->bLifeMax / 2))) - { - return; - } - break; - case 2: - // they won't use them until they have 2+ opponents as long as 3/4 life left - if ((ubOpponentCnt < 2) && (pSoldier->bLife > (pSoldier->bLifeMax / 4) * 3 )) - { - return; - } - break; - break; - default: - break; + case 0: + case 1: + // they won't use them until they have 2+ opponents as long as half life left + if ((ubOpponentCnt < 2) && (pSoldier->bLife > (pSoldier->bLifeMax / 2))) + { + return; + } + break; + case 2: + // they won't use them until they have 2+ opponents as long as 3/4 life left + if ((ubOpponentCnt < 2) && (pSoldier->bLife > (pSoldier->bLifeMax / 4) * 3 )) + { + return; + } + break; + break; + default: + break; } } - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"calcbestthrow: about to initattacktype"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"calcbestthrow: about to initattacktype"); InitAttackType(pBestThrow); // set all structure fields to defaults // look at the squares near each known opponent and try to find the one @@ -823,9 +831,9 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) // this shouldn't ever happen if ((sGridNo < 0) || (sGridNo >= GRIDSIZE)) { - #ifdef BETAVERSION - NumMessage("CalcBestThrow: ERROR - invalid gridno being tested ",sGridNo); - #endif +#ifdef BETAVERSION + NumMessage("CalcBestThrow: ERROR - invalid gridno being tested ",sGridNo); +#endif continue; } @@ -838,9 +846,9 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) // if considering a gas/smoke grenade, check to see if there is such stuff already there! if ( usGrenade ) { -// if ( gpWorldLevelData[ sGridNo ].ubExtFlags[ bOpponentLevel[ubLoop] ] & MAPELEMENT_EXT_SMOKE || -// gpWorldLevelData[ sGridNo ].ubExtFlags[ bOpponentLevel[ubLoop] ] & (MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS) || -// gpWorldLevelData[ sGridNo ].ubExtFlags[ bOpponentLevel[ubLoop] ] & MAPELEMENT_EXT_MUSTARDGAS) + // if ( gpWorldLevelData[ sGridNo ].ubExtFlags[ bOpponentLevel[ubLoop] ] & MAPELEMENT_EXT_SMOKE || + // gpWorldLevelData[ sGridNo ].ubExtFlags[ bOpponentLevel[ubLoop] ] & (MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS) || + // gpWorldLevelData[ sGridNo ].ubExtFlags[ bOpponentLevel[ubLoop] ] & MAPELEMENT_EXT_MUSTARDGAS) if ( gpWorldLevelData[ sGridNo ].ubExtFlags[ bOpponentLevel[ubLoop] ] & MAPELEMENT_EXT_SMOKE || gpWorldLevelData[ sGridNo ].ubExtFlags[ bOpponentLevel[ubLoop] ] & (MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS | MAPELEMENT_EXT_BURNABLEGAS) || gpWorldLevelData[ sGridNo ].ubExtFlags[ bOpponentLevel[ubLoop] ] & MAPELEMENT_EXT_MUSTARDGAS || gpWorldLevelData[ sGridNo ].ubExtFlags[ bOpponentLevel[ubLoop] ] & MAPELEMENT_EXT_BURNABLEGAS) @@ -922,7 +930,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) iTotalThreatValue = 0; ubOppsInRange = 0; ubOppsAdjacent = 0; - // skip this location unless it's right on top of an enemy or + // skip this location unless it's right on top of an enemy or // adjacent to more than 1 fSkipLocation = TRUE; @@ -1050,7 +1058,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) // this is try to minimize enemies wasting their (few) mortar shells or LAWs // they won't use them on less than 2 targets as long as half life left if ((Item[usInHand].mortar || Item[usInHand].rocketlauncher ) && (ubOppsInRange < 2) && - (pSoldier->bLife > (pSoldier->bLifeMax / 2))) + (pSoldier->bLife > (pSoldier->bLifeMax / 2))) { continue; // next gridno } @@ -1078,7 +1086,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) ubChanceToHit = (UINT8) CalcThrownChanceToHit( pSoldier, sGridNo, ubMaxPossibleAimTime, AIM_SHOT_TORSO ); DebugMsg(TOPIC_JA2 , DBG_LEVEL_3 , String("Chance to hit = %d",ubChanceToHit )); } - + // mortars are inherently quite inaccurate, don't get proximity bonus // rockets can go right past people too so... if (!Item[usInHand].mortar && EXPLOSIVE_GUN( usInHand ) ) @@ -1094,8 +1102,8 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) } } - if (ubRawAPCost < 1) - ubRawAPCost = ubMinAPcost; + if (ubRawAPCost < 1) + ubRawAPCost = ubMinAPcost; DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("calcbestthrow: checking hit rate: ubRawAPCost %d, ubMaxPossibleAimTime %d", ubRawAPCost, ubMaxPossibleAimTime )); iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubMaxPossibleAimTime); @@ -1108,7 +1116,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) // if we can't REALLY hit at all if (ubChanceToReallyHit == 0) continue; // next gridno - + // calculate the combined "attack value" for this opponent // maximum possible attack value here should be about 140 million // typical attack value here should be about 500 thousand @@ -1119,9 +1127,9 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) // unlike SHOOTing and STABbing, find strictly the highest attackValue if (iAttackValue > pBestThrow->iAttackValue) { - #ifdef DEBUGATTACKS - DebugAI( String( "CalcBestThrow: new best attackValue vs %d = %d\n",ubOpponentID[ubLoop],iAttackValue ) ); - #endif +#ifdef DEBUGATTACKS + DebugAI( String( "CalcBestThrow: new best attackValue vs %d = %d\n",ubOpponentID[ubLoop],iAttackValue ) ); +#endif // OOOF! That was a lot of work! But we've got a new best target! pBestThrow->ubPossible = TRUE; @@ -1143,25 +1151,25 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) // this is try to minimize enemies wasting their (limited) toss attacks: switch( ubDiff ) { - case 0: - case 1: - // don't use unless have a 70% chance to hit - if (pBestThrow->ubChanceToReallyHit < 70) - { - pBestThrow->ubPossible = FALSE; - } - break; - case 2: - case 3: - case 4: - // don't use unless have a 50% chance to hit - if (pBestThrow->ubChanceToReallyHit < 50) - { - pBestThrow->ubPossible = FALSE; - } - break; - default: - break; + case 0: + case 1: + // don't use unless have a 70% chance to hit + if (pBestThrow->ubChanceToReallyHit < 70) + { + pBestThrow->ubPossible = FALSE; + } + break; + case 2: + case 3: + case 4: + // don't use unless have a 50% chance to hit + if (pBestThrow->ubChanceToReallyHit < 50) + { + pBestThrow->ubPossible = FALSE; + } + break; + default: + break; } DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"calcbestthrow done"); @@ -1169,120 +1177,120 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) void CalcBestStab(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestStab, BOOLEAN fBladeAttack ) { - UINT32 uiLoop; - INT32 iAttackValue; - INT32 iThreatValue,iHitRate,iBestHitRate,iPercentBetter, iEstDamage; - BOOLEAN fSurpriseStab; - UINT8 ubRawAPCost,ubMinAPCost,ubMaxPossibleAimTime,ubAimTime,ubBestAimTime; - UINT8 ubChanceToHit,ubChanceToReallyHit,ubBestChanceToHit = 0; - SOLDIERTYPE *pOpponent; - UINT16 usTrueMovementMode; - - InitAttackType(pBestStab); // set all structure fields to defaults + UINT32 uiLoop; + INT32 iAttackValue; + INT32 iThreatValue,iHitRate,iBestHitRate,iPercentBetter, iEstDamage; + BOOLEAN fSurpriseStab; + UINT8 ubRawAPCost,ubMinAPCost,ubMaxPossibleAimTime,ubAimTime,ubBestAimTime; + UINT8 ubChanceToHit,ubChanceToReallyHit,ubBestChanceToHit = 0; + SOLDIERTYPE *pOpponent; + UINT16 usTrueMovementMode; - pSoldier->usAttackingWeapon = pSoldier->inv[HANDPOS].usItem; + InitAttackType(pBestStab); // set all structure fields to defaults - // temporarily make this guy run so we get a proper AP cost value - // from CalcTotalAPsToAttack - usTrueMovementMode = pSoldier->usUIMovementMode; - pSoldier->usUIMovementMode = RUNNING; + pSoldier->usAttackingWeapon = pSoldier->inv[HANDPOS].usItem; - // determine which attack against which target has the greatest attack value + // temporarily make this guy run so we get a proper AP cost value + // from CalcTotalAPsToAttack + usTrueMovementMode = pSoldier->usUIMovementMode; + pSoldier->usUIMovementMode = RUNNING; - for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) - { - pOpponent = MercSlots[ uiLoop ]; + // determine which attack against which target has the greatest attack value - // if this merc is inactive, at base, on assignment, or dead - if (!pOpponent || !pOpponent->bLife) - continue; // next merc + for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) + { + pOpponent = MercSlots[ uiLoop ]; - // if this man is neutral / on the same side, he's not an opponent - if ( CONSIDERED_NEUTRAL( pSoldier, pOpponent ) || (pSoldier->bSide == pOpponent->bSide) ) - continue; // next merc + // if this merc is inactive, at base, on assignment, or dead + if (!pOpponent || !pOpponent->bLife) + continue; // next merc - // if this opponent is not currently in sight (ignore known but unseen!) - if (pSoldier->bOppList[pOpponent->ubID] != SEEN_CURRENTLY) - continue; // next merc + // if this man is neutral / on the same side, he's not an opponent + if ( CONSIDERED_NEUTRAL( pSoldier, pOpponent ) || (pSoldier->bSide == pOpponent->bSide) ) + continue; // next merc - // if this opponent is not on the same level - if (pSoldier->bLevel != pOpponent->bLevel) - continue; // next merc + // if this opponent is not currently in sight (ignore known but unseen!) + if (pSoldier->bOppList[pOpponent->ubID] != SEEN_CURRENTLY) + continue; // next merc + + // if this opponent is not on the same level + if (pSoldier->bLevel != pOpponent->bLevel) + continue; // next merc // Special stuff for Carmen the bounty hunter if (pSoldier->bAttitude == ATTACKSLAYONLY && pOpponent->ubProfile != 64) continue; // next opponent #ifdef DEBUGATTACKS - DebugAI( String( "%s can see %s\n",pSoldier->name,ExtMen[pOpponent->ubID].name ) ); + DebugAI( String( "%s can see %s\n",pSoldier->name,ExtMen[pOpponent->ubID].name ) ); #endif - // calculate minimum action points required to stab at this opponent - ubMinAPCost = CalcTotalAPsToAttack( pSoldier,pOpponent->sGridNo,ADDTURNCOST, 0 ); + // calculate minimum action points required to stab at this opponent + ubMinAPCost = CalcTotalAPsToAttack( pSoldier,pOpponent->sGridNo,ADDTURNCOST, 0 ); - //ubMinAPCost = MinAPsToAttack(pSoldier,pOpponent->sGridNo,ADDTURNCOST); - //NumMessage("MinAPcost to stab this opponent = ",ubMinAPCost); + //ubMinAPCost = MinAPsToAttack(pSoldier,pOpponent->sGridNo,ADDTURNCOST); + //NumMessage("MinAPcost to stab this opponent = ",ubMinAPCost); - // Human: if I don't have enough APs left to get there & stab at this guy, skip 'im. - // Monster: I'll do an extra check later on to see if I can reach the guy this turn. + // Human: if I don't have enough APs left to get there & stab at this guy, skip 'im. + // Monster: I'll do an extra check later on to see if I can reach the guy this turn. - // if 0 is returned then no path! - if ( ubMinAPCost > pSoldier->bActionPoints || ubMinAPCost == 0 ) - { - continue; - /* - if ( CREATURE_OR_BLOODCAT( pSoldier ) ) - { - // hardcode ubMinAPCost so that aiming time is 0 and can start move to stab - // at any time - ubMinAPCost = pSoldier->bActionPoints; - } - else - { - continue; // next merc - } - */ - } + // if 0 is returned then no path! + if ( ubMinAPCost > pSoldier->bActionPoints || ubMinAPCost == 0 ) + { + continue; + /* + if ( CREATURE_OR_BLOODCAT( pSoldier ) ) + { + // hardcode ubMinAPCost so that aiming time is 0 and can start move to stab + // at any time + ubMinAPCost = pSoldier->bActionPoints; + } + else + { + continue; // next merc + } + */ + } - //KeepInterfaceGoing(); + //KeepInterfaceGoing(); - // calc next attack's minimum stabbing cost (excludes movement & turning) - //ubRawAPCost = MinAPsToShootOrStab(pSoldier,pOpponent->sGridNo, FALSE) - AP_CHANGE_TARGET; - ubRawAPCost = MinAPsToAttack(pSoldier,pOpponent->sGridNo, FALSE) - AP_CHANGE_TARGET; - //NumMessage("ubRawAPCost to stab this opponent = ",ubRawAPCost); + // calc next attack's minimum stabbing cost (excludes movement & turning) + //ubRawAPCost = MinAPsToShootOrStab(pSoldier,pOpponent->sGridNo, FALSE) - AP_CHANGE_TARGET; + ubRawAPCost = MinAPsToAttack(pSoldier,pOpponent->sGridNo, FALSE) - AP_CHANGE_TARGET; + //NumMessage("ubRawAPCost to stab this opponent = ",ubRawAPCost); - // determine if this is a surprise stab (must be next to opponent & unseen) - fSurpriseStab = FALSE; // assume it is not a surprise stab + // determine if this is a surprise stab (must be next to opponent & unseen) + fSurpriseStab = FALSE; // assume it is not a surprise stab - // if opponent doesn't see the attacker - if (pOpponent->bOppList[pSoldier->ubID] != SEEN_CURRENTLY) - { + // if opponent doesn't see the attacker + if (pOpponent->bOppList[pSoldier->ubID] != SEEN_CURRENTLY) + { fSurpriseStab = TRUE; - // and he's only one space away from attacker - if (SpacesAway(pSoldier->sGridNo,pOpponent->sGridNo) == 1) - { - fSurpriseStab = TRUE; // we got 'im lined up where we want 'im! - } - } + // and he's only one space away from attacker + if (SpacesAway(pSoldier->sGridNo,pOpponent->sGridNo) == 1) + { + fSurpriseStab = TRUE; // we got 'im lined up where we want 'im! + } + } - iBestHitRate = 0; // reset best hit rate to minimum + iBestHitRate = 0; // reset best hit rate to minimum - // calculate the maximum possible aiming time - ubMaxPossibleAimTime = min(AllowedAimingLevels(pSoldier),pSoldier->bActionPoints - ubMinAPCost); - //NumMessage("Max Possible Aim Time = ",ubMaxPossibleAimTime); + // calculate the maximum possible aiming time + ubMaxPossibleAimTime = min(AllowedAimingLevels(pSoldier),pSoldier->bActionPoints - ubMinAPCost); + //NumMessage("Max Possible Aim Time = ",ubMaxPossibleAimTime); - // consider the various aiming times - for (ubAimTime = AP_MIN_AIM_ATTACK; ubAimTime <= ubMaxPossibleAimTime; ubAimTime++) - { - //HandleMyMouseCursor(KEYBOARDALSO); + // consider the various aiming times + for (ubAimTime = AP_MIN_AIM_ATTACK; ubAimTime <= ubMaxPossibleAimTime; ubAimTime++) + { + //HandleMyMouseCursor(KEYBOARDALSO); - //NumMessage("ubAimTime = ",ubAimTime); + //NumMessage("ubAimTime = ",ubAimTime); - if (!fSurpriseStab) - { + if (!fSurpriseStab) + { if (fBladeAttack) { ubChanceToHit = (UINT8) CalcChanceToStab(pSoldier,pOpponent,ubAimTime); @@ -1291,249 +1299,249 @@ void CalcBestStab(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestStab, BOOLEAN fBladeAt { ubChanceToHit = (UINT8) CalcChanceToPunch(pSoldier,pOpponent,ubAimTime); } - } - else - ubChanceToHit = MAXCHANCETOHIT; - //NumMessage("chance to Hit = ",ubChanceToHit); + } + else + ubChanceToHit = MAXCHANCETOHIT; + //NumMessage("chance to Hit = ",ubChanceToHit); - //sprintf(tempstr,"Vs. %s, at AimTime %d, ubChanceToHit = %d",ExtMen[pOpponent->ubID].name,ubAimTime,ubChanceToHit); - //PopMessage(tempstr); + //sprintf(tempstr,"Vs. %s, at AimTime %d, ubChanceToHit = %d",ExtMen[pOpponent->ubID].name,ubAimTime,ubChanceToHit); + //PopMessage(tempstr); - if (ubRawAPCost < 1) - ubRawAPCost = ubMinAPCost; + if (ubRawAPCost < 1) + ubRawAPCost = ubMinAPCost; - iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime); - //NumMessage("hitRate = ",iHitRate); + iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime); + //NumMessage("hitRate = ",iHitRate); - // if aiming for this amount of time produces a better hit rate - if (iHitRate > iBestHitRate) - { - iBestHitRate = iHitRate; - ubBestAimTime = ubAimTime; - ubBestChanceToHit = ubChanceToHit; - } - } + // if aiming for this amount of time produces a better hit rate + if (iHitRate > iBestHitRate) + { + iBestHitRate = iHitRate; + ubBestAimTime = ubAimTime; + ubBestChanceToHit = ubChanceToHit; + } + } - // if we can't get any kind of hit rate at all - if (iBestHitRate == 0) - continue; // next opponent + // if we can't get any kind of hit rate at all + if (iBestHitRate == 0) + continue; // next opponent - // stabs are not affected by cover, so the chance to REALLY hit is the same - ubChanceToReallyHit = ubBestChanceToHit; + // stabs are not affected by cover, so the chance to REALLY hit is the same + ubChanceToReallyHit = ubBestChanceToHit; - // calculate this opponent's threat value - // NOTE: ignore my cover! By the time I run beside him I won't have any! - iThreatValue = CalcManThreatValue(pOpponent,pSoldier->sGridNo,FALSE,pSoldier); + // calculate this opponent's threat value + // NOTE: ignore my cover! By the time I run beside him I won't have any! + iThreatValue = CalcManThreatValue(pOpponent,pSoldier->sGridNo,FALSE,pSoldier); - // estimate the damage this stab would do to this opponent - iEstDamage = EstimateStabDamage(pSoldier,pOpponent,ubBestChanceToHit, fBladeAttack ); - //NumMessage("STAB EstDamage = ", iEstDamage); + // estimate the damage this stab would do to this opponent + iEstDamage = EstimateStabDamage(pSoldier,pOpponent,ubBestChanceToHit, fBladeAttack ); + //NumMessage("STAB EstDamage = ", iEstDamage); - // calculate the combined "attack value" for this opponent - // highest possible value before division should be about 1 billion... - // normal value before division should be about 5 million... - iAttackValue = ( iEstDamage * iBestHitRate * ubChanceToReallyHit * iThreatValue) / 1000; - //NumMessage("STAB AttackValue = ",iAttackValue / 1000); + // calculate the combined "attack value" for this opponent + // highest possible value before division should be about 1 billion... + // normal value before division should be about 5 million... + iAttackValue = ( iEstDamage * iBestHitRate * ubChanceToReallyHit * iThreatValue) / 1000; + //NumMessage("STAB AttackValue = ",iAttackValue / 1000); #ifdef DEBUGATTACKS - DebugAI( String( "CalcBestStab: best AttackValue vs %d = %d\n",ubLoop,iAttackValue ) ); + DebugAI( String( "CalcBestStab: best AttackValue vs %d = %d\n",ubLoop,iAttackValue ) ); #endif - // if we can hurt the guy, OR probably not, but at least it's our best - // chance to actually hit him and maybe scare him, knock him down, etc. - if ((iAttackValue > 0) || (ubChanceToReallyHit > pBestStab->ubChanceToReallyHit)) - { - // if there already was another viable target - if (pBestStab->ubChanceToReallyHit > 0) - { - // OK, how does our chance to hit him compare to the previous best one? - iPercentBetter = ((ubChanceToReallyHit * 100) / pBestStab->ubChanceToReallyHit) - 100; + // if we can hurt the guy, OR probably not, but at least it's our best + // chance to actually hit him and maybe scare him, knock him down, etc. + if ((iAttackValue > 0) || (ubChanceToReallyHit > pBestStab->ubChanceToReallyHit)) + { + // if there already was another viable target + if (pBestStab->ubChanceToReallyHit > 0) + { + // OK, how does our chance to hit him compare to the previous best one? + iPercentBetter = ((ubChanceToReallyHit * 100) / pBestStab->ubChanceToReallyHit) - 100; - // if this chance to really hit is more than 50% worse, and the other - // guy is conscious at all - if ((iPercentBetter < -PERCENT_TO_IGNORE_THREAT) && (Menptr[pBestStab->ubOpponent].bLife >= OKLIFE)) - // then stick with the older guy as the better target - continue; + // if this chance to really hit is more than 50% worse, and the other + // guy is conscious at all + if ((iPercentBetter < -PERCENT_TO_IGNORE_THREAT) && (Menptr[pBestStab->ubOpponent].bLife >= OKLIFE)) + // then stick with the older guy as the better target + continue; - // if this chance to really hit between 50% worse to 50% better - if (iPercentBetter < PERCENT_TO_IGNORE_THREAT) + // if this chance to really hit between 50% worse to 50% better + if (iPercentBetter < PERCENT_TO_IGNORE_THREAT) { - // then the one with the higher ATTACK VALUE is the better target - if (iAttackValue < pBestStab->iAttackValue) - // the previous guy is more important since he's more dangerous - continue; // next opponent + // then the one with the higher ATTACK VALUE is the better target + if (iAttackValue < pBestStab->iAttackValue) + // the previous guy is more important since he's more dangerous + continue; // next opponent } - } + } - // OOOF! That was a lot of work! But we've got a new best target! - pBestStab->ubPossible = TRUE; - pBestStab->ubOpponent = pOpponent->ubID; - pBestStab->ubAimTime = ubBestAimTime; - pBestStab->ubChanceToReallyHit = ubChanceToReallyHit; - pBestStab->sTarget = pOpponent->sGridNo; - pBestStab->bTargetLevel = pOpponent->bLevel; - pBestStab->iAttackValue = iAttackValue; - pBestStab->ubAPCost = ubMinAPCost + ubBestAimTime; - } - } + // OOOF! That was a lot of work! But we've got a new best target! + pBestStab->ubPossible = TRUE; + pBestStab->ubOpponent = pOpponent->ubID; + pBestStab->ubAimTime = ubBestAimTime; + pBestStab->ubChanceToReallyHit = ubChanceToReallyHit; + pBestStab->sTarget = pOpponent->sGridNo; + pBestStab->bTargetLevel = pOpponent->bLevel; + pBestStab->iAttackValue = iAttackValue; + pBestStab->ubAPCost = ubMinAPCost + ubBestAimTime; + } + } pSoldier->usUIMovementMode = usTrueMovementMode; } void CalcTentacleAttack(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestStab ) { - UINT32 uiLoop; - INT32 iAttackValue; - INT32 iThreatValue,iHitRate,iBestHitRate, iEstDamage; - BOOLEAN fSurpriseStab; - UINT8 ubRawAPCost,ubMinAPCost,ubMaxPossibleAimTime,ubAimTime,ubBestAimTime; - UINT8 ubChanceToHit,ubChanceToReallyHit,ubBestChanceToHit = 0; - SOLDIERTYPE *pOpponent; + UINT32 uiLoop; + INT32 iAttackValue; + INT32 iThreatValue,iHitRate,iBestHitRate, iEstDamage; + BOOLEAN fSurpriseStab; + UINT8 ubRawAPCost,ubMinAPCost,ubMaxPossibleAimTime,ubAimTime,ubBestAimTime; + UINT8 ubChanceToHit,ubChanceToReallyHit,ubBestChanceToHit = 0; + SOLDIERTYPE *pOpponent; - InitAttackType(pBestStab); // set all structure fields to defaults + InitAttackType(pBestStab); // set all structure fields to defaults - pSoldier->usAttackingWeapon = pSoldier->inv[HANDPOS].usItem; + pSoldier->usAttackingWeapon = pSoldier->inv[HANDPOS].usItem; - // determine which attack against which target has the greatest attack value + // determine which attack against which target has the greatest attack value - for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) - { - pOpponent = MercSlots[ uiLoop ]; + for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) + { + pOpponent = MercSlots[ uiLoop ]; - // if this merc is inactive, at base, on assignment, or dead - if (!pOpponent || !pOpponent->bLife) - continue; // next merc + // if this merc is inactive, at base, on assignment, or dead + if (!pOpponent || !pOpponent->bLife) + continue; // next merc - // if this man is neutral / on the same side, he's not an opponent - if ( CONSIDERED_NEUTRAL( pSoldier, pOpponent ) || (pSoldier->bSide == pOpponent->bSide)) - continue; // next merc + // if this man is neutral / on the same side, he's not an opponent + if ( CONSIDERED_NEUTRAL( pSoldier, pOpponent ) || (pSoldier->bSide == pOpponent->bSide)) + continue; // next merc - // if this opponent is not currently in sight (ignore known but unseen!) - if (pSoldier->bOppList[pOpponent->ubID] != SEEN_CURRENTLY) - continue; // next merc + // if this opponent is not currently in sight (ignore known but unseen!) + if (pSoldier->bOppList[pOpponent->ubID] != SEEN_CURRENTLY) + continue; // next merc - // if this opponent is not on the same level - if (pSoldier->bLevel != pOpponent->bLevel) - continue; // next merc + // if this opponent is not on the same level + if (pSoldier->bLevel != pOpponent->bLevel) + continue; // next merc - // if this opponent is outside the range of our tentacles - if ( GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, pOpponent->sGridNo ) > Weapon[ CREATURE_QUEEN_TENTACLES].usRange ) - { - continue; // next merc - } + // if this opponent is outside the range of our tentacles + if ( GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, pOpponent->sGridNo ) > Weapon[ CREATURE_QUEEN_TENTACLES].usRange ) + { + continue; // next merc + } #ifdef DEBUGATTACKS - DebugAI( String( "%s can see %s\n",pSoldier->name,ExtMen[pOpponent->ubID].name ) ); + DebugAI( String( "%s can see %s\n",pSoldier->name,ExtMen[pOpponent->ubID].name ) ); #endif - // calculate minimum action points required to stab at this opponent - ubMinAPCost = CalcTotalAPsToAttack( pSoldier,pOpponent->sGridNo,ADDTURNCOST, 0 ); - //ubMinAPCost = MinAPsToAttack(pSoldier,pOpponent->sGridNo,ADDTURNCOST); - //NumMessage("MinAPcost to stab this opponent = ",ubMinAPCost); + // calculate minimum action points required to stab at this opponent + ubMinAPCost = CalcTotalAPsToAttack( pSoldier,pOpponent->sGridNo,ADDTURNCOST, 0 ); + //ubMinAPCost = MinAPsToAttack(pSoldier,pOpponent->sGridNo,ADDTURNCOST); + //NumMessage("MinAPcost to stab this opponent = ",ubMinAPCost); - // calc next attack's minimum stabbing cost (excludes movement & turning) - //ubRawAPCost = MinAPsToShootOrStab(pSoldier,pOpponent->sGridNo, FALSE) - AP_CHANGE_TARGET; - ubRawAPCost = MinAPsToAttack(pSoldier,pOpponent->sGridNo, FALSE) - AP_CHANGE_TARGET; - //NumMessage("ubRawAPCost to stab this opponent = ",ubRawAPCost); + // calc next attack's minimum stabbing cost (excludes movement & turning) + //ubRawAPCost = MinAPsToShootOrStab(pSoldier,pOpponent->sGridNo, FALSE) - AP_CHANGE_TARGET; + ubRawAPCost = MinAPsToAttack(pSoldier,pOpponent->sGridNo, FALSE) - AP_CHANGE_TARGET; + //NumMessage("ubRawAPCost to stab this opponent = ",ubRawAPCost); - // determine if this is a surprise stab (for tentacles, enemy must not see us, no dist limit) - fSurpriseStab = FALSE; // assume it is not a surprise stab + // determine if this is a surprise stab (for tentacles, enemy must not see us, no dist limit) + fSurpriseStab = FALSE; // assume it is not a surprise stab - // if opponent doesn't see the attacker - if (pOpponent->bOppList[pSoldier->ubID] != SEEN_CURRENTLY) - { - fSurpriseStab = TRUE; // we got 'im lined up where we want 'im! - } + // if opponent doesn't see the attacker + if (pOpponent->bOppList[pSoldier->ubID] != SEEN_CURRENTLY) + { + fSurpriseStab = TRUE; // we got 'im lined up where we want 'im! + } - iBestHitRate = 0; // reset best hit rate to minimum - - // calculate the maximum possible aiming time + iBestHitRate = 0; // reset best hit rate to minimum - //ubMaxPossibleAimTime = min(AllowedAimingLevels(pSoldier),pSoldier->bActionPoints - ubMinAPCost); - ubMaxPossibleAimTime = 0; - //NumMessage("Max Possible Aim Time = ",ubMaxPossibleAimTime); + // calculate the maximum possible aiming time - // consider the various aiming times - for (ubAimTime = AP_MIN_AIM_ATTACK; ubAimTime <= ubMaxPossibleAimTime; ubAimTime++) - { - //HandleMyMouseCursor(KEYBOARDALSO); + //ubMaxPossibleAimTime = min(AllowedAimingLevels(pSoldier),pSoldier->bActionPoints - ubMinAPCost); + ubMaxPossibleAimTime = 0; + //NumMessage("Max Possible Aim Time = ",ubMaxPossibleAimTime); - //NumMessage("ubAimTime = ",ubAimTime); + // consider the various aiming times + for (ubAimTime = AP_MIN_AIM_ATTACK; ubAimTime <= ubMaxPossibleAimTime; ubAimTime++) + { + //HandleMyMouseCursor(KEYBOARDALSO); - if (!fSurpriseStab) - { + //NumMessage("ubAimTime = ",ubAimTime); + + if (!fSurpriseStab) + { ubChanceToHit = (UINT8) CalcChanceToStab(pSoldier,pOpponent,ubAimTime); - } - else - ubChanceToHit = MAXCHANCETOHIT; - //NumMessage("chance to Hit = ",ubChanceToHit); + } + else + ubChanceToHit = MAXCHANCETOHIT; + //NumMessage("chance to Hit = ",ubChanceToHit); - //sprintf(tempstr,"Vs. %s, at AimTime %d, ubChanceToHit = %d",ExtMen[pOpponent->ubID].name,ubAimTime,ubChanceToHit); - //PopMessage(tempstr); + //sprintf(tempstr,"Vs. %s, at AimTime %d, ubChanceToHit = %d",ExtMen[pOpponent->ubID].name,ubAimTime,ubChanceToHit); + //PopMessage(tempstr); - if (ubRawAPCost < 1) - ubRawAPCost = ubMinAPCost; + if (ubRawAPCost < 1) + ubRawAPCost = ubMinAPCost; - iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime); - //NumMessage("hitRate = ",iHitRate); + iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime); + //NumMessage("hitRate = ",iHitRate); - // if aiming for this amount of time produces a better hit rate - if (iHitRate > iBestHitRate) - { - iBestHitRate = iHitRate; - ubBestAimTime = ubAimTime; - ubBestChanceToHit = ubChanceToHit; - } - } + // if aiming for this amount of time produces a better hit rate + if (iHitRate > iBestHitRate) + { + iBestHitRate = iHitRate; + ubBestAimTime = ubAimTime; + ubBestChanceToHit = ubChanceToHit; + } + } - // if we can't get any kind of hit rate at all - if (iBestHitRate == 0) - continue; // next opponent + // if we can't get any kind of hit rate at all + if (iBestHitRate == 0) + continue; // next opponent - // stabs are not affected by cover, so the chance to REALLY hit is the same - ubChanceToReallyHit = ubBestChanceToHit; + // stabs are not affected by cover, so the chance to REALLY hit is the same + ubChanceToReallyHit = ubBestChanceToHit; - // calculate this opponent's threat value - // NOTE: ignore my cover! By the time I run beside him I won't have any! - iThreatValue = CalcManThreatValue(pOpponent,pSoldier->sGridNo,FALSE,pSoldier); + // calculate this opponent's threat value + // NOTE: ignore my cover! By the time I run beside him I won't have any! + iThreatValue = CalcManThreatValue(pOpponent,pSoldier->sGridNo,FALSE,pSoldier); - // estimate the damage this stab would do to this opponent - iEstDamage = EstimateStabDamage(pSoldier,pOpponent,ubBestChanceToHit, TRUE ); - //NumMessage("STAB EstDamage = ", iEstDamage); + // estimate the damage this stab would do to this opponent + iEstDamage = EstimateStabDamage(pSoldier,pOpponent,ubBestChanceToHit, TRUE ); + //NumMessage("STAB EstDamage = ", iEstDamage); - // calculate the combined "attack value" for this opponent - // highest possible value before division should be about 1 billion... - // normal value before division should be about 5 million... - iAttackValue = ( iEstDamage * iBestHitRate * ubChanceToReallyHit * iThreatValue) / 1000; - //NumMessage("STAB AttackValue = ",iAttackValue / 1000); + // calculate the combined "attack value" for this opponent + // highest possible value before division should be about 1 billion... + // normal value before division should be about 5 million... + iAttackValue = ( iEstDamage * iBestHitRate * ubChanceToReallyHit * iThreatValue) / 1000; + //NumMessage("STAB AttackValue = ",iAttackValue / 1000); #ifdef DEBUGATTACKS - DebugAI( String( "CalcBestStab: best AttackValue vs %d = %d\n",ubLoop,iAttackValue ) ); + DebugAI( String( "CalcBestStab: best AttackValue vs %d = %d\n",ubLoop,iAttackValue ) ); #endif - // if we can hurt the guy, OR probably not, but at least it's our best - // chance to actually hit him and maybe scare him, knock him down, etc. - if (iAttackValue > 0) - { - // OOOF! That was a lot of work! But we've got a new best target! - pBestStab->ubPossible = TRUE; - pBestStab->ubOpponent = pOpponent->ubID; - pBestStab->ubAimTime = ubBestAimTime; - pBestStab->ubChanceToReallyHit = ubChanceToReallyHit; - pBestStab->sTarget = pOpponent->sGridNo; - pBestStab->bTargetLevel = pOpponent->bLevel; + // if we can hurt the guy, OR probably not, but at least it's our best + // chance to actually hit him and maybe scare him, knock him down, etc. + if (iAttackValue > 0) + { + // OOOF! That was a lot of work! But we've got a new best target! + pBestStab->ubPossible = TRUE; + pBestStab->ubOpponent = pOpponent->ubID; + pBestStab->ubAimTime = ubBestAimTime; + pBestStab->ubChanceToReallyHit = ubChanceToReallyHit; + pBestStab->sTarget = pOpponent->sGridNo; + pBestStab->bTargetLevel = pOpponent->bLevel; - // ADD this target's attack value to our TOTAL... - pBestStab->iAttackValue += iAttackValue; + // ADD this target's attack value to our TOTAL... + pBestStab->iAttackValue += iAttackValue; - pBestStab->ubAPCost = ubMinAPCost + ubBestAimTime; + pBestStab->ubAPCost = ubMinAPCost + ubBestAimTime; - } - } + } + } } UINT8 NumMercsCloseTo( INT16 sGridNo, UINT8 ubMaxDist ) @@ -1560,19 +1568,19 @@ UINT8 NumMercsCloseTo( INT16 sGridNo, UINT8 ubMaxDist ) INT32 EstimateShotDamage(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ubChanceToHit) { - INT32 iRange,iMaxRange,iPowerLost; - INT32 iDamage; - UINT8 ubBonus; - INT32 iHeadProt = 0, iTorsoProt = 0, iLegProt = 0; - INT32 iTotalProt; - INT8 bPlatePos; - UINT8 ubAmmoType; + INT32 iRange,iMaxRange,iPowerLost; + INT32 iDamage; + UINT8 ubBonus; + INT32 iHeadProt = 0, iTorsoProt = 0, iLegProt = 0; + INT32 iTotalProt; + INT8 bPlatePos; + UINT8 ubAmmoType; -/* + /* if ( pOpponent->uiStatusFlags & SOLDIER_VEHICLE ) { - // only thing that can damage vehicles is HEAP rounds? - return( 0 ); + // only thing that can damage vehicles is HEAP rounds? + return( 0 ); } */ @@ -1585,26 +1593,26 @@ INT32 EstimateShotDamage(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ub ubAmmoType = pSoldier->inv[pSoldier->ubAttackingHand].ubGunAmmoType; } - // calculate distance to target, obtain his gun's maximum range rating + // calculate distance to target, obtain his gun's maximum range rating - iRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, pOpponent->sGridNo ); - iMaxRange = Weapon[pSoldier->inv[HANDPOS].usItem].usRange; + iRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, pOpponent->sGridNo ); + iMaxRange = Weapon[pSoldier->inv[HANDPOS].usItem].usRange; - // bullet loses speed and penetrating power, 50% loss per maximum range - iPowerLost = ((50 * iRange) / iMaxRange); + // bullet loses speed and penetrating power, 50% loss per maximum range + iPowerLost = ((50 * iRange) / iMaxRange); - // up to 50% extra impact for making particularly accurate successful shots - ubBonus = ubChanceToHit / 4; // /4 is really /2 and /2 again + // up to 50% extra impact for making particularly accurate successful shots + ubBonus = ubChanceToHit / 4; // /4 is really /2 and /2 again - iDamage = ((GetDamage(&pSoldier->inv[HANDPOS])) * (100 - iPowerLost + ubBonus) / 100) ; + iDamage = ((GetDamage(&pSoldier->inv[HANDPOS])) * (100 - iPowerLost + ubBonus) / 100) ; - //NumMessage("Pre-protection damage: ",damage); + //NumMessage("Pre-protection damage: ",damage); - // if opponent is wearing a helmet - if (pOpponent->inv[HELMETPOS].usItem) - { - iHeadProt += (INT32) Armour[Item[pOpponent->inv[HELMETPOS].usItem].ubClassIndex].ubProtection * - (INT32) pOpponent->inv[HELMETPOS].bStatus[0] / 100; + // if opponent is wearing a helmet + if (pOpponent->inv[HELMETPOS].usItem) + { + iHeadProt += (INT32) Armour[Item[pOpponent->inv[HELMETPOS].usItem].ubClassIndex].ubProtection * + (INT32) pOpponent->inv[HELMETPOS].bStatus[0] / 100; } // if opponent is wearing a protective vest @@ -1614,7 +1622,7 @@ INT32 EstimateShotDamage(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ub if (pOpponent->inv[VESTPOS].usItem) { iTorsoProt += (INT32) Armour[Item[pOpponent->inv[VESTPOS].usItem].ubClassIndex].ubProtection * - (INT32) pOpponent->inv[VESTPOS].bStatus[0] / 100; + (INT32) pOpponent->inv[VESTPOS].bStatus[0] / 100; } } @@ -1623,7 +1631,7 @@ INT32 EstimateShotDamage(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ub if (bPlatePos != -1) { iTorsoProt += (INT32) Armour[Item[pOpponent->inv[VESTPOS].usAttachItem[bPlatePos]].ubClassIndex].ubProtection * - (INT32) pOpponent->inv[VESTPOS].bAttachStatus[bPlatePos] / 100; + (INT32) pOpponent->inv[VESTPOS].bAttachStatus[bPlatePos] / 100; } @@ -1633,7 +1641,7 @@ INT32 EstimateShotDamage(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ub if (pOpponent->inv[LEGPOS].usItem) { iLegProt += (INT32) Armour[Item[pOpponent->inv[LEGPOS].usItem].ubClassIndex].ubProtection * - (INT32) pOpponent->inv[LEGPOS].bStatus[0] / 100; + (INT32) pOpponent->inv[LEGPOS].bStatus[0] / 100; } } @@ -1658,7 +1666,7 @@ INT32 EstimateShotDamage(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ub //} iDamage -= iTotalProt; - //NumMessage("After-protection damage: ",damage); + //NumMessage("After-protection damage: ",damage); //if (ubAmmoType == AMMO_HP) //{ @@ -1674,22 +1682,22 @@ INT32 EstimateShotDamage(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ub switch( pSoldier->inv[pSoldier->ubAttackingHand].usItem ) { // explosive damage is 100-200% that of the rated, so multiply by 3/2s here - case CREATURE_QUEEN_SPIT: //TODO: Madd - remove the hardcoding here - iDamage += ( 3 * Explosive[ Item[ LARGE_CREATURE_GAS ].ubClassIndex ].ubDamage * NumMercsCloseTo( pOpponent->sGridNo, (UINT8)Explosive[ Item[ LARGE_CREATURE_GAS ].ubClassIndex ].ubRadius ) ) / 2; - break; - case CREATURE_OLD_MALE_SPIT: - iDamage += ( 3 * Explosive[ Item[ SMALL_CREATURE_GAS ].ubClassIndex ].ubDamage * NumMercsCloseTo( pOpponent->sGridNo, (UINT8)Explosive[ Item[ SMALL_CREATURE_GAS ].ubClassIndex ].ubRadius ) ) / 2; - break; - default: - iDamage += ( 3 * Explosive[ Item[ VERY_SMALL_CREATURE_GAS ].ubClassIndex ].ubDamage * NumMercsCloseTo( pOpponent->sGridNo, (UINT8)Explosive[ Item[ VERY_SMALL_CREATURE_GAS ].ubClassIndex ].ubRadius ) ) / 2; - break; + case CREATURE_QUEEN_SPIT: //TODO: Madd - remove the hardcoding here + iDamage += ( 3 * Explosive[ Item[ LARGE_CREATURE_GAS ].ubClassIndex ].ubDamage * NumMercsCloseTo( pOpponent->sGridNo, (UINT8)Explosive[ Item[ LARGE_CREATURE_GAS ].ubClassIndex ].ubRadius ) ) / 2; + break; + case CREATURE_OLD_MALE_SPIT: + iDamage += ( 3 * Explosive[ Item[ SMALL_CREATURE_GAS ].ubClassIndex ].ubDamage * NumMercsCloseTo( pOpponent->sGridNo, (UINT8)Explosive[ Item[ SMALL_CREATURE_GAS ].ubClassIndex ].ubRadius ) ) / 2; + break; + default: + iDamage += ( 3 * Explosive[ Item[ VERY_SMALL_CREATURE_GAS ].ubClassIndex ].ubDamage * NumMercsCloseTo( pOpponent->sGridNo, (UINT8)Explosive[ Item[ VERY_SMALL_CREATURE_GAS ].ubClassIndex ].ubRadius ) ) / 2; + break; } - } + } - if (iDamage < 1) - iDamage = 1; // assume we can do at LEAST 1 pt minimum damage + if (iDamage < 1) + iDamage = 1; // assume we can do at LEAST 1 pt minimum damage - return( iDamage ); + return( iDamage ); } INT32 EstimateThrowDamage( SOLDIERTYPE *pSoldier, UINT8 ubItemPos, SOLDIERTYPE *pOpponent, INT16 sGridno ) @@ -1735,7 +1743,7 @@ INT32 EstimateThrowDamage( SOLDIERTYPE *pSoldier, UINT8 ubItemPos, SOLDIERTYPE * ubExplosiveIndex = Item[ pSoldier->inv[ubItemPos].usItem ].ubClassIndex; // break; - //} + //} // JA2Gold: added if ( Item[pSoldier->inv[ubItemPos].usItem].flare ) { @@ -1807,7 +1815,7 @@ INT32 EstimateThrowDamage( SOLDIERTYPE *pSoldier, UINT8 ubItemPos, SOLDIERTYPE * } INT32 EstimateStabDamage( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, - UINT8 ubChanceToHit, BOOLEAN fBladeAttack ) + UINT8 ubChanceToHit, BOOLEAN fBladeAttack ) { INT32 iImpact, iFluke, iBonus; @@ -1840,7 +1848,7 @@ INT32 EstimateStabDamage( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, iFluke = 0; iBonus = ubChanceToHit / 4; // up to 50% extra impact for accurate attacks - + iImpact = iImpact * (100 + iFluke + iBonus) / 100; if (!fBladeAttack) @@ -1850,10 +1858,10 @@ INT32 EstimateStabDamage( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, { iImpact = iImpact * (100 + gbSkillTraitBonus[MARTIALARTS] * NUM_SKILL_TRAITS( pSoldier, MARTIALARTS ) ) / 100; } - if ( HAS_SKILL_TRAIT( pSoldier, HANDTOHAND ) ) + if ( HAS_SKILL_TRAIT( pSoldier, HANDTOHAND ) ) { iImpact = iImpact * (100 + gbSkillTraitBonus[HANDTOHAND] * NUM_SKILL_TRAITS( pSoldier, HANDTOHAND ) ) / 100; - } + } // Here, if we're doing a bare-fisted attack, // we want to pay attention just to wounds inflicted iImpact = iImpact / PUNCH_REAL_DAMAGE_PORTION; @@ -1884,7 +1892,7 @@ INT8 TryToReload( SOLDIERTYPE * pSoldier ) // } //} -// manual recharge + // manual recharge pObj = &(pSoldier->inv[HANDPOS]); if (pObj->ubGunShotsLeft && !(pObj->ubGunState & GS_CARTRIDGE_IN_CHAMBER) ) @@ -1892,21 +1900,21 @@ INT8 TryToReload( SOLDIERTYPE * pSoldier ) pObj->ubGunState |= GS_CARTRIDGE_IN_CHAMBER; DeductPoints(pSoldier, Weapon[Item[(pObj)->usItem].ubClassIndex].APsToReloadManually, 0); - + PlayJA2Sample( Weapon[ Item[pObj->usItem].ubClassIndex ].ManualReloadSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - + if ( IsValidSecondHandShot( pSoldier ) ) { pObj2 = &(pSoldier->inv[SECONDHANDPOS]); if (pObj2->ubGunShotsLeft && !(pObj2->ubGunState & GS_CARTRIDGE_IN_CHAMBER) ) - { + { pObj2->ubGunState |= GS_CARTRIDGE_IN_CHAMBER; PlayJA2Sample( Weapon[ Item[pObj2->usItem].ubClassIndex ].ManualReloadSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); } } - + return TRUE; } else @@ -1918,20 +1926,20 @@ INT8 TryToReload( SOLDIERTYPE * pSoldier ) if (pObj2->ubGunShotsLeft && !(pObj2->ubGunState & GS_CARTRIDGE_IN_CHAMBER) ) { pObj2->ubGunState |= GS_CARTRIDGE_IN_CHAMBER; - + DeductPoints(pSoldier, Weapon[Item[(pObj2)->usItem].ubClassIndex].APsToReloadManually, 0); PlayJA2Sample( Weapon[ Item[pObj2->usItem].ubClassIndex ].ManualReloadSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); - + return TRUE; } } } -// + // if (bSlot != NO_SLOT && ReloadGun( pSoldier, &(pSoldier->inv[HANDPOS]), &(pSoldier->inv[bSlot]) )) { - return( TRUE ); + return( TRUE ); } return( NOSHOOT_NOAMMO ); @@ -1940,24 +1948,24 @@ INT8 TryToReload( SOLDIERTYPE * pSoldier ) /* INT8 TryToReloadLauncher( SOLDIERTYPE * pSoldier ) { - UINT16 usWeapon; - INT8 bSlot; - - usWeapon = pSoldier->inv[HANDPOS].usItem; - - if ( usWeapon == TANK_CANNON ) - { - bSlot = FindObj( pSoldier, TANK_SHELL ); - } - else - { - bSlot = FindLaunchable( pSoldier, usWeapon ); - } - - if (bSlot != NO_SLOT) - { - } - return( NOSHOOT_NOAMMO ); +UINT16 usWeapon; +INT8 bSlot; + +usWeapon = pSoldier->inv[HANDPOS].usItem; + +if ( usWeapon == TANK_CANNON ) +{ +bSlot = FindObj( pSoldier, TANK_SHELL ); +} +else +{ +bSlot = FindLaunchable( pSoldier, usWeapon ); +} + +if (bSlot != NO_SLOT) +{ +} +return( NOSHOOT_NOAMMO ); } */ @@ -1989,24 +1997,24 @@ INT8 CanNPCAttack(SOLDIERTYPE *pSoldier) bWeaponIn = FindAIUsableObjClass( pSoldier, IC_WEAPON ); if (bWeaponIn != NO_SLOT) { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"cannpcattack: swapping weapon into hand"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"cannpcattack: swapping weapon into hand"); RearrangePocket( pSoldier, HANDPOS, bWeaponIn, FOREVER ); // look for another weapon if this one is 1-handed -// if ( (Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass == IC_GUN) && !(Item[ pSoldier->inv[ HANDPOS ].usItem ].fFlags & ITEM_TWO_HANDED ) ) + // if ( (Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass == IC_GUN) && !(Item[ pSoldier->inv[ HANDPOS ].usItem ].fFlags & ITEM_TWO_HANDED ) ) if ( (Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass == IC_GUN) && !(Item[ pSoldier->inv[ HANDPOS ].usItem ].twohanded ) ) { // look for another pistol/SMG if available bWeaponIn = FindAIUsableObjClassWithin( pSoldier, IC_WEAPON, BIGPOCK1POS, SMALLPOCK8POS ); -// if (bWeaponIn != NO_SLOT && (Item[ pSoldier->inv[ bWeaponIn ].usItem ].usItemClass == IC_GUN) && !(Item[ pSoldier->inv[ bWeaponIn ].usItem ].fFlags & ITEM_TWO_HANDED ) ) + // if (bWeaponIn != NO_SLOT && (Item[ pSoldier->inv[ bWeaponIn ].usItem ].usItemClass == IC_GUN) && !(Item[ pSoldier->inv[ bWeaponIn ].usItem ].fFlags & ITEM_TWO_HANDED ) ) if (bWeaponIn != NO_SLOT && (Item[ pSoldier->inv[ bWeaponIn ].usItem ].usItemClass == IC_GUN) && !(Item[ pSoldier->inv[ bWeaponIn ].usItem ].twohanded ) ) { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"cannpcattack: swapping weapon into holster"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"cannpcattack: swapping weapon into holster"); RearrangePocket( pSoldier, SECONDHANDPOS, bWeaponIn, FOREVER ); } } // might need to reload bCanAttack = CanNPCAttack( pSoldier ); - } + } } #ifdef DEBUGDECISIONS @@ -2037,21 +2045,29 @@ void CheckIfTossPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) { pBestThrow->bWeaponIn = FindAIUsableObjClass( pSoldier, IC_LAUNCHER ); - if ( pBestThrow->bWeaponIn == NO_SLOT ) + if ( pBestThrow->bWeaponIn == NO_SLOT || ( !EnoughAmmo( pSoldier, FALSE, pBestThrow->bWeaponIn) && FindAmmoToReload( pSoldier, pBestThrow->bWeaponIn, NO_SLOT) == NO_SLOT) ) { // Consider rocket launcher/cannon pBestThrow->bWeaponIn = FindRocketLauncherOrCannon( pSoldier ); - if ( pBestThrow->bWeaponIn == NO_SLOT ) + if ( pBestThrow->bWeaponIn == NO_SLOT || ( !EnoughAmmo( pSoldier, FALSE, pBestThrow->bWeaponIn) && FindAmmoToReload( pSoldier, pBestThrow->bWeaponIn, NO_SLOT) == NO_SLOT) ) { - //no rocket launcher -- let's look for an underslung/attached GL + //no rocket launcher (or empty) -- let's look for an underslung/attached GL + // AND a launchable grenade! + INT8 bOldWeaponMode = pSoldier->bWeaponMode; + pSoldier->bWeaponMode = WM_ATTACHED_GL; // So that EnoughAmmo will check for a grenade not a bullet INT8 bGunSlot = FindAIUsableObjClass( pSoldier, IC_GUN ); - if ( bGunSlot != NO_SLOT && IsGrenadeLauncherAttached(&pSoldier->inv[bGunSlot]) ) + if ( bGunSlot != NO_SLOT && + IsGrenadeLauncherAttached(&pSoldier->inv[bGunSlot]) && + ( EnoughAmmo( pSoldier, FALSE, bGunSlot) || FindGLGrenade( pSoldier) == NO_SLOT) ) { pBestThrow->bWeaponIn = bGunSlot; - pSoldier->bWeaponMode = WM_ATTACHED_GL; } - else // no rocket launcher or attached GL, consider grenades + else + { + // no rocket launcher or attached GL, consider grenades + pSoldier->bWeaponMode = bOldWeaponMode; pBestThrow->bWeaponIn = FindThrowableGrenade( pSoldier ); + } } else { @@ -2074,7 +2090,7 @@ void CheckIfTossPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) RearrangePocket(pSoldier, HANDPOS, pBestThrow->bWeaponIn, TEMPORARILY); } - + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"checkiftosspossible: get minapstoattack"); // get the minimum cost to attack with this tossable item ubMinAPcost = MinAPsToAttack( pSoldier, pSoldier->sLastTarget, DONTADDTURNCOST); @@ -2092,7 +2108,7 @@ void CheckIfTossPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow) DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"checkiftosspossible: swapping item into holster"); RearrangePocket( pSoldier, HANDPOS, pBestThrow->bWeaponIn, TEMPORARILY ); } - } + } } INT8 CountAdjacentSpreadTargets( SOLDIERTYPE * pSoldier, INT16 sFirstTarget, INT8 bTargetLevel ) @@ -2102,11 +2118,11 @@ INT8 CountAdjacentSpreadTargets( SOLDIERTYPE * pSoldier, INT16 sFirstTarget, INT INT8 bDirLoop, bDir, bCheckDir, bTargetIndex, bTargets; INT16 sTarget; SOLDIERTYPE * pTarget, * pTargets[5] = {NULL}; - + bTargetIndex = -1; bCheckDir = -1; - pTargets[2] = SimpleFindSoldier( sFirstTarget, bTargetLevel ); + pTargets[2] = SimpleFindSoldier( sFirstTarget, bTargetLevel ); if (pTargets[2] == NULL) { return( 0 ); @@ -2122,40 +2138,40 @@ INT8 CountAdjacentSpreadTargets( SOLDIERTYPE * pSoldier, INT16 sFirstTarget, INT // odd direction = diagonal direction switch( bDirLoop ) { - case 0: - bCheckDir = (bDir + 6) % 8; - bTargetIndex = 0; - break; - case 1: - bCheckDir = (bDir + 5) % 8; - bTargetIndex = 1; - break; - case 2: - bCheckDir = (bDir + 7) % 8; - bTargetIndex = 1; - break; - case 3: - bCheckDir = (bDir + 3) % 8; - bTargetIndex = 3; - break; - case 4: - bCheckDir = (bDir + 1) % 8; - bTargetIndex = 3; - break; - case 5: - bCheckDir = (bDir + 2) % 8; - bTargetIndex = 4; - break; - case 6: - // check in front - bCheckDir = (bDir + 4) % 8; - bTargetIndex = 1; - break; - case 7: - // check behind - bCheckDir = (bDir) % 8; - bTargetIndex = 3; - break; + case 0: + bCheckDir = (bDir + 6) % 8; + bTargetIndex = 0; + break; + case 1: + bCheckDir = (bDir + 5) % 8; + bTargetIndex = 1; + break; + case 2: + bCheckDir = (bDir + 7) % 8; + bTargetIndex = 1; + break; + case 3: + bCheckDir = (bDir + 3) % 8; + bTargetIndex = 3; + break; + case 4: + bCheckDir = (bDir + 1) % 8; + bTargetIndex = 3; + break; + case 5: + bCheckDir = (bDir + 2) % 8; + bTargetIndex = 4; + break; + case 6: + // check in front + bCheckDir = (bDir + 4) % 8; + bTargetIndex = 1; + break; + case 7: + // check behind + bCheckDir = (bDir) % 8; + bTargetIndex = 3; + break; } } else @@ -2163,40 +2179,40 @@ INT8 CountAdjacentSpreadTargets( SOLDIERTYPE * pSoldier, INT16 sFirstTarget, INT // even = straight switch( bDirLoop ) { - case 0: - bCheckDir = (bDir + 5) % 8; - bTargetIndex = 1; - break; - case 1: - bCheckDir = (bDir + 6) % 8; - bTargetIndex = 1; - break; - case 2: - bCheckDir = (bDir + 7) % 8; - bTargetIndex = 1; - break; - case 3: - bCheckDir = (bDir + 3) % 8; - bTargetIndex = 3; - break; - case 4: - bCheckDir = (bDir + 2) % 8; - bTargetIndex = 3; - break; - case 5: - bCheckDir = (bDir + 1) % 8; - bTargetIndex = 3; - break; - case 6: - // check in front - bCheckDir = (bDir + 4) % 8; - bTargetIndex = 1; - break; - case 7: - // check behind - bCheckDir = (bDir) % 8; - bTargetIndex = 3; - break; + case 0: + bCheckDir = (bDir + 5) % 8; + bTargetIndex = 1; + break; + case 1: + bCheckDir = (bDir + 6) % 8; + bTargetIndex = 1; + break; + case 2: + bCheckDir = (bDir + 7) % 8; + bTargetIndex = 1; + break; + case 3: + bCheckDir = (bDir + 3) % 8; + bTargetIndex = 3; + break; + case 4: + bCheckDir = (bDir + 2) % 8; + bTargetIndex = 3; + break; + case 5: + bCheckDir = (bDir + 1) % 8; + bTargetIndex = 3; + break; + case 6: + // check in front + bCheckDir = (bDir + 4) % 8; + bTargetIndex = 1; + break; + case 7: + // check behind + bCheckDir = (bDir) % 8; + bTargetIndex = 3; + break; } } @@ -2230,11 +2246,11 @@ INT16 CalcSpreadBurst( SOLDIERTYPE * pSoldier, INT16 sFirstTarget, INT8 bTargetL INT16 sTarget; SOLDIERTYPE * pTarget, * pTargets[5] = {NULL}; INT8 bAdjacents, bOtherAdjacents; - + bCheckDir = -1; - pTargets[2] = SimpleFindSoldier( sFirstTarget, bTargetLevel ); + pTargets[2] = SimpleFindSoldier( sFirstTarget, bTargetLevel ); if (pTargets[2] == NULL) { return( sFirstTarget ); @@ -2251,40 +2267,40 @@ INT16 CalcSpreadBurst( SOLDIERTYPE * pSoldier, INT16 sFirstTarget, INT8 bTargetL // odd direction = diagonal direction switch( bDirLoop ) { - case 0: - bCheckDir = (bDir + 6) % 8; - bTargetIndex = 0; - break; - case 1: - bCheckDir = (bDir + 5) % 8; - bTargetIndex = 1; - break; - case 2: - bCheckDir = (bDir + 7) % 8; - bTargetIndex = 1; - break; - case 3: - bCheckDir = (bDir + 3) % 8; - bTargetIndex = 3; - break; - case 4: - bCheckDir = (bDir + 1) % 8; - bTargetIndex = 3; - break; - case 5: - bCheckDir = (bDir + 2) % 8; - bTargetIndex = 4; - break; - case 6: - // check in front - bCheckDir = (bDir + 4) % 8; - bTargetIndex = 1; - break; - case 7: - // check behind - bCheckDir = (bDir) % 8; - bTargetIndex = 3; - break; + case 0: + bCheckDir = (bDir + 6) % 8; + bTargetIndex = 0; + break; + case 1: + bCheckDir = (bDir + 5) % 8; + bTargetIndex = 1; + break; + case 2: + bCheckDir = (bDir + 7) % 8; + bTargetIndex = 1; + break; + case 3: + bCheckDir = (bDir + 3) % 8; + bTargetIndex = 3; + break; + case 4: + bCheckDir = (bDir + 1) % 8; + bTargetIndex = 3; + break; + case 5: + bCheckDir = (bDir + 2) % 8; + bTargetIndex = 4; + break; + case 6: + // check in front + bCheckDir = (bDir + 4) % 8; + bTargetIndex = 1; + break; + case 7: + // check behind + bCheckDir = (bDir) % 8; + bTargetIndex = 3; + break; } } else @@ -2292,40 +2308,40 @@ INT16 CalcSpreadBurst( SOLDIERTYPE * pSoldier, INT16 sFirstTarget, INT8 bTargetL // even = straight switch( bDirLoop ) { - case 0: - bCheckDir = (bDir + 5) % 8; - bTargetIndex = 1; - break; - case 1: - bCheckDir = (bDir + 6) % 8; - bTargetIndex = 1; - break; - case 2: - bCheckDir = (bDir + 7) % 8; - bTargetIndex = 1; - break; - case 3: - bCheckDir = (bDir + 3) % 8; - bTargetIndex = 3; - break; - case 4: - bCheckDir = (bDir + 2) % 8; - bTargetIndex = 3; - break; - case 5: - bCheckDir = (bDir + 1) % 8; - bTargetIndex = 3; - break; - case 6: - // check in front - bCheckDir = (bDir + 4) % 8; - bTargetIndex = 1; - break; - case 7: - // check behind - bCheckDir = (bDir) % 8; - bTargetIndex = 3; - break; + case 0: + bCheckDir = (bDir + 5) % 8; + bTargetIndex = 1; + break; + case 1: + bCheckDir = (bDir + 6) % 8; + bTargetIndex = 1; + break; + case 2: + bCheckDir = (bDir + 7) % 8; + bTargetIndex = 1; + break; + case 3: + bCheckDir = (bDir + 3) % 8; + bTargetIndex = 3; + break; + case 4: + bCheckDir = (bDir + 2) % 8; + bTargetIndex = 3; + break; + case 5: + bCheckDir = (bDir + 1) % 8; + bTargetIndex = 3; + break; + case 6: + // check in front + bCheckDir = (bDir + 4) % 8; + bTargetIndex = 1; + break; + case 7: + // check behind + bCheckDir = (bDir) % 8; + bTargetIndex = 3; + break; } } @@ -2359,7 +2375,7 @@ INT16 CalcSpreadBurst( SOLDIERTYPE * pSoldier, INT16 sFirstTarget, INT8 bTargetL // Check the 4th position if (pTargets[3] == NULL && pTargets[4] != NULL) { - pTargets[3] = pTargets[4]; + pTargets[3] = pTargets[4]; pTargets[4] = NULL; } // Check the first two positions; we know the 3rd value is set because @@ -2418,7 +2434,7 @@ INT16 AdvanceToFiringRange( SOLDIERTYPE * pSoldier, INT16 sClosestOpponent ) usActionData = GoAsFarAsPossibleTowards( pSoldier, sClosestOpponent, AI_ACTION_SEEK_OPPONENT ); pSoldier->bActionPoints = bTrueActionPoints; - + return( usActionData ); } @@ -2443,7 +2459,7 @@ void CheckIfShotPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN s { OBJECTTYPE * pObj = &pSoldier->inv[pBestShot->bWeaponIn]; DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("CheckIfShotPossible: found a gun item # %d",pObj->usItem )); - + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("CheckIfShotPossible: weapon type %d",Weapon [pObj->usItem ].ubWeaponType )); // if it's in his holster, swap it into his hand temporarily @@ -2453,14 +2469,15 @@ void CheckIfShotPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN s RearrangePocket(pSoldier, HANDPOS, pBestShot->bWeaponIn, TEMPORARILY); } - if ( (!suppressionFire && ( (IsScoped(pObj) && GunRange(pObj) > MaxDistanceVisible() ) || pSoldier->bOrders == SNIPER ) ) || (suppressionFire && IsGunAutofireCapable(pSoldier,pBestShot->bWeaponIn ) && GetMagSize(pObj) > 30 && pObj->ubGunShotsLeft > 20 )) + if ( (!suppressionFire && ( (IsScoped(pObj) && GunRange(pObj) > MaxDistanceVisible() ) || pSoldier->bOrders == SNIPER ) ) || + (suppressionFire && IsGunAutofireCapable(pSoldier,pBestShot->bWeaponIn ) && GetMagSize(pObj) > 30 && pObj->ubGunShotsLeft > 20 )) { // get the minimum cost to attack with this item DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CheckIfShotPossible: getting min aps"); ubMinAPcost = MinAPsToAttack( pSoldier, pSoldier->sLastTarget, ADDTURNCOST); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("CheckIfShotPossible: min AP cost: %d", ubMinAPcost)); - // if we can afford the minimum AP cost + // if we can afford the minimum AP cost if (pSoldier->bActionPoints >= ubMinAPcost) { DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("CheckIfShotPossible: CalcBestShot")); @@ -2475,5 +2492,5 @@ void CheckIfShotPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN s DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CheckIfShotPossible: Rearranging pocket"); RearrangePocket( pSoldier, HANDPOS, pBestShot->bWeaponIn, TEMPORARILY ); } - } + } } diff --git a/TacticalAI/DecideAction.cpp b/TacticalAI/DecideAction.cpp index bcd4ca67..78bf0cb2 100644 --- a/TacticalAI/DecideAction.cpp +++ b/TacticalAI/DecideAction.cpp @@ -1,38 +1,38 @@ -//#ifdef PRECOMPILEDHEADERS -// #include "AI All.h" -//#else - #include "ai.h" - #include "AIInternals.h" - #include "Isometric utils.h" - #include "Points.h" - #include "overhead.h" - #include "opplist.h" - #include "items.h" - #include "Weapons.h" - #include "NPC.h" - #include "Soldier Functions.h" - #include "worldman.h" - #include "Scheduling.h" - #include "Message.h" - #include "Structure Wrap.h" - #include "Keys.h" - #include "pathai.h" - #include "Render Fun.h" - #include "Boxing.h" - #include "strategic status.h" - #include "Soldier Profile.h" - #include "Soldier macros.h" - #include "los.h" - #include "Buildings.h" - #include "strategicmap.h" - #include "Quests.h" - #include "soldier ani.h" - #include "Map Screen Interface Map.h" - #include "GameSettings.h" - #include "rotting corpses.h" - #include "Dialogue Control.h" +#ifdef PRECOMPILEDHEADERS +#include "AI All.h" +#else +#include "ai.h" +#include "AIInternals.h" +#include "Isometric utils.h" +#include "Points.h" +#include "overhead.h" +#include "opplist.h" +#include "items.h" +#include "Weapons.h" +#include "NPC.h" +#include "Soldier Functions.h" +#include "worldman.h" +#include "Scheduling.h" +#include "Message.h" +#include "Structure Wrap.h" +#include "Keys.h" +#include "pathai.h" +#include "Render Fun.h" +#include "Boxing.h" // #include "Air Raid.h" -//#endif +#include "Soldier Profile.h" +#include "soldier profile type.h" +#include "Soldier macros.h" +#include "los.h" +#include "Buildings.h" +#include "strategicmap.h" +#include "Quests.h" +#include "Map Screen Interface Map.h" +#include "soldier ani.h" +#include "rotting corpses.h" +#include "GameSettings.h" +#include "Dialogue Control.h" +#endif extern BOOLEAN InternalIsValidStance( SOLDIERTYPE *pSoldier, INT8 bDirection, INT8 bNewStance ); extern BOOLEAN gfHiddenInterrupt; @@ -77,7 +77,7 @@ INT8 DecideActionSchedule( SOLDIERTYPE * pSoldier ) STRUCTURE * pStructure; BOOLEAN fDoUseDoor; DOOR_STATUS * pDoorStatus; - + pSchedule = GetSchedule( pSoldier->ubScheduleID ); if (!pSchedule) { @@ -115,270 +115,244 @@ INT8 DecideActionSchedule( SOLDIERTYPE * pSoldier ) switch( ubScheduleAction ) { - case SCHEDULE_ACTION_LOCKDOOR: - //Uses first gridno for locking door, then second to move to after door is locked. - //It is possible that the second gridno will border the edge of the map, meaning that - //the individual will walk off of the map. - //If this is a "merchant", make sure that nobody occupies the building/room. + case SCHEDULE_ACTION_LOCKDOOR: + //Uses first gridno for locking door, then second to move to after door is locked. + //It is possible that the second gridno will border the edge of the map, meaning that + //the individual will walk off of the map. + //If this is a "merchant", make sure that nobody occupies the building/room. - switch( pSoldier->bAIScheduleProgress ) + switch( pSoldier->bAIScheduleProgress ) + { + case 0: // move to gridno specified + if (pSoldier->sGridNo == usGridNo1) { - case 0: // move to gridno specified - if (pSoldier->sGridNo == usGridNo1) + pSoldier->bAIScheduleProgress++; + // fall through + } + else + { + pSoldier->usActionData = usGridNo1; + pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; + return( AI_ACTION_SCHEDULE_MOVE ); + } + // fall through + case 1: + // start the door open: find the door... + usGridNo1 = FindDoorAtGridNoOrAdjacent( usGridNo1 ); + + if ( usGridNo1 == NOWHERE ) + { + // do nothing right now! + return( AI_ACTION_NONE ); + } + + pDoorStatus = GetDoorStatus( usGridNo1 ); + if (pDoorStatus && pDoorStatus->ubFlags & DOOR_BUSY) + { + // do nothing right now! + return( AI_ACTION_NONE ); + } + + pStructure = FindStructure( usGridNo1, STRUCTURE_ANYDOOR ); + if (pStructure == NULL) + { + fDoUseDoor = FALSE; + } + else + { + // action-specific tests to not handle the door + fDoUseDoor = TRUE; + + if (pStructure->fFlags & STRUCTURE_OPEN) + { + // not only do we have to lock the door but + // close it too! + pSoldier->fAIFlags |= AI_LOCK_DOOR_INCLUDES_CLOSE; + } + else + { + DOOR * pDoor; + + pDoor = FindDoorInfoAtGridNo( usGridNo1 ); + if (pDoor) { - pSoldier->bAIScheduleProgress++; - // fall through + if (pDoor->fLocked) + { + // door already locked! + fDoUseDoor = FALSE; + } + else + { + pDoor->fLocked = TRUE; + } } else { - pSoldier->usActionData = usGridNo1; - pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; - return( AI_ACTION_SCHEDULE_MOVE ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Schedule involved locked door at %d but there's no lock there!", usGridNo1 ); + fDoUseDoor = FALSE; } - // fall through - case 1: - // start the door open: find the door... - usGridNo1 = FindDoorAtGridNoOrAdjacent( usGridNo1 ); + } + } - if ( usGridNo1 == NOWHERE ) - { - // do nothing right now! - return( AI_ACTION_NONE ); - } + if (fDoUseDoor) + { + pSoldier->usActionData = usGridNo1; + return( AI_ACTION_LOCK_DOOR ); + } - pDoorStatus = GetDoorStatus( usGridNo1 ); - if (pDoorStatus && pDoorStatus->ubFlags & DOOR_BUSY) - { - // do nothing right now! - return( AI_ACTION_NONE ); - } + // the door is already in the desired state, or it doesn't exist! + pSoldier->bAIScheduleProgress++; + // fall through - pStructure = FindStructure( usGridNo1, STRUCTURE_ANYDOOR ); - if (pStructure == NULL) + case 2: + if (pSoldier->sGridNo == usGridNo2 || pSoldier->sGridNo == NOWHERE) + { + // NOWHERE indicates we were supposed to go off map and have done so + DoneScheduleAction( pSoldier ); + + if ( pSoldier->sGridNo != NOWHERE ) + { + pSoldier->usPatrolGrid[0] = pSoldier->sGridNo; + } + } + else + { + if ( GridNoOnEdgeOfMap( usGridNo2, &bDirection ) ) + { + // told to go to edge of map, so go off at that point! + pSoldier->ubQuoteActionID = GetTraversalQuoteActionID( bDirection ); + } + pSoldier->usActionData = usGridNo2; + pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; + return( AI_ACTION_SCHEDULE_MOVE ); + } + break; + } + break; + + + case SCHEDULE_ACTION_UNLOCKDOOR: + case SCHEDULE_ACTION_OPENDOOR: + case SCHEDULE_ACTION_CLOSEDOOR: + //Uses first gridno for opening/closing/unlocking door, then second to move to after door is opened. + //It is possible that the second gridno will border the edge of the map, meaning that + //the individual will walk off of the map. + switch( pSoldier->bAIScheduleProgress ) + { + case 0: // move to gridno specified + if (pSoldier->sGridNo == usGridNo1) + { + pSoldier->bAIScheduleProgress++; + // fall through + } + else + { + pSoldier->usActionData = usGridNo1; + pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; + return( AI_ACTION_SCHEDULE_MOVE ); + } + // fall through + case 1: + // start the door open: find the door... + usGridNo1 = FindDoorAtGridNoOrAdjacent( usGridNo1 ); + + if ( usGridNo1 == NOWHERE ) + { + // do nothing right now! + return( AI_ACTION_NONE ); + } + + pDoorStatus = GetDoorStatus( usGridNo1 ); + if (pDoorStatus && pDoorStatus->ubFlags & DOOR_BUSY) + { + // do nothing right now! + return( AI_ACTION_NONE ); + } + + pStructure = FindStructure( usGridNo1, STRUCTURE_ANYDOOR ); + if (pStructure == NULL) + { + fDoUseDoor = FALSE; + } + else + { + fDoUseDoor = TRUE; + + // action-specific tests to not handle the door + switch( ubScheduleAction ) + { + case SCHEDULE_ACTION_UNLOCKDOOR: + if (pStructure->fFlags & STRUCTURE_OPEN) { + // door is already open! fDoUseDoor = FALSE; } else { - // action-specific tests to not handle the door - fDoUseDoor = TRUE; - - if (pStructure->fFlags & STRUCTURE_OPEN) - { - // not only do we have to lock the door but - // close it too! - pSoldier->fAIFlags |= AI_LOCK_DOOR_INCLUDES_CLOSE; - } - else - { - DOOR * pDoor; + // set the door to unlocked + DOOR * pDoor; - pDoor = FindDoorInfoAtGridNo( usGridNo1 ); - if (pDoor) + pDoor = FindDoorInfoAtGridNo( usGridNo1 ); + if (pDoor) + { + if (pDoor->fLocked) { - if (pDoor->fLocked) - { - // door already locked! - fDoUseDoor = FALSE; - } - else - { - pDoor->fLocked = TRUE; - } + pDoor->fLocked = FALSE; } else { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Schedule involved locked door at %d but there's no lock there!", usGridNo1 ); + // door already unlocked! fDoUseDoor = FALSE; } } - } - - if (fDoUseDoor) - { - pSoldier->usActionData = usGridNo1; - return( AI_ACTION_LOCK_DOOR ); - } - - // the door is already in the desired state, or it doesn't exist! - pSoldier->bAIScheduleProgress++; - // fall through - - case 2: - if (pSoldier->sGridNo == usGridNo2 || pSoldier->sGridNo == NOWHERE) - { - // NOWHERE indicates we were supposed to go off map and have done so - DoneScheduleAction( pSoldier ); - - if ( pSoldier->sGridNo != NOWHERE ) - { - pSoldier->usPatrolGrid[0] = pSoldier->sGridNo; - } - } - else - { - if ( GridNoOnEdgeOfMap( usGridNo2, &bDirection ) ) - { - // told to go to edge of map, so go off at that point! - pSoldier->ubQuoteActionID = GetTraversalQuoteActionID( bDirection ); - } - pSoldier->usActionData = usGridNo2; - pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; - return( AI_ACTION_SCHEDULE_MOVE ); - } - break; - } - break; - - - case SCHEDULE_ACTION_UNLOCKDOOR: - case SCHEDULE_ACTION_OPENDOOR: - case SCHEDULE_ACTION_CLOSEDOOR: - //Uses first gridno for opening/closing/unlocking door, then second to move to after door is opened. - //It is possible that the second gridno will border the edge of the map, meaning that - //the individual will walk off of the map. - switch( pSoldier->bAIScheduleProgress ) - { - case 0: // move to gridno specified - if (pSoldier->sGridNo == usGridNo1) - { - pSoldier->bAIScheduleProgress++; - // fall through - } - else - { - pSoldier->usActionData = usGridNo1; - pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; - return( AI_ACTION_SCHEDULE_MOVE ); - } - // fall through - case 1: - // start the door open: find the door... - usGridNo1 = FindDoorAtGridNoOrAdjacent( usGridNo1 ); - - if ( usGridNo1 == NOWHERE ) - { - // do nothing right now! - return( AI_ACTION_NONE ); - } - - pDoorStatus = GetDoorStatus( usGridNo1 ); - if (pDoorStatus && pDoorStatus->ubFlags & DOOR_BUSY) - { - // do nothing right now! - return( AI_ACTION_NONE ); - } - - pStructure = FindStructure( usGridNo1, STRUCTURE_ANYDOOR ); - if (pStructure == NULL) - { - fDoUseDoor = FALSE; - } - else - { - fDoUseDoor = TRUE; - - // action-specific tests to not handle the door - switch( ubScheduleAction ) - { - case SCHEDULE_ACTION_UNLOCKDOOR: - if (pStructure->fFlags & STRUCTURE_OPEN) - { - // door is already open! - fDoUseDoor = FALSE; - } - else - { - // set the door to unlocked - DOOR * pDoor; - - pDoor = FindDoorInfoAtGridNo( usGridNo1 ); - if (pDoor) - { - if (pDoor->fLocked) - { - pDoor->fLocked = FALSE; - } - else - { - // door already unlocked! - fDoUseDoor = FALSE; - } - } - else - { - // WTF? Warning time! - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Schedule involved locked door at %d but there's no lock there!", usGridNo1 ); - fDoUseDoor = FALSE; - } - } - break; - case SCHEDULE_ACTION_OPENDOOR: - if (pStructure->fFlags & STRUCTURE_OPEN) - { - // door is already open! - fDoUseDoor = FALSE; - } - break; - case SCHEDULE_ACTION_CLOSEDOOR: - if ( !(pStructure->fFlags & STRUCTURE_OPEN) ) - { - // door is already closed! - fDoUseDoor = FALSE; - } - break; - default: - break; - } - } - - if (fDoUseDoor) - { - pSoldier->usActionData = usGridNo1; - if (ubScheduleAction == SCHEDULE_ACTION_UNLOCKDOOR) - { - return( AI_ACTION_UNLOCK_DOOR ); - } else { - return( AI_ACTION_OPEN_OR_CLOSE_DOOR ); + // WTF? Warning time! + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Schedule involved locked door at %d but there's no lock there!", usGridNo1 ); + fDoUseDoor = FALSE; } } - - // the door is already in the desired state, or it doesn't exist! - pSoldier->bAIScheduleProgress++; - // fall through - - case 2: - if (pSoldier->sGridNo == usGridNo2 || pSoldier->sGridNo == NOWHERE) - { - // NOWHERE indicates we were supposed to go off map and have done so - DoneScheduleAction( pSoldier ); - if ( pSoldier->sGridNo != NOWHERE ) - { - pSoldier->usPatrolGrid[0] = pSoldier->sGridNo; - } - } - else - { - if ( GridNoOnEdgeOfMap( usGridNo2, &bDirection ) ) - { - // told to go to edge of map, so go off at that point! - pSoldier->ubQuoteActionID = GetTraversalQuoteActionID( bDirection ); - } - pSoldier->usActionData = usGridNo2; - pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; - return( AI_ACTION_SCHEDULE_MOVE ); - } break; + case SCHEDULE_ACTION_OPENDOOR: + if (pStructure->fFlags & STRUCTURE_OPEN) + { + // door is already open! + fDoUseDoor = FALSE; + } + break; + case SCHEDULE_ACTION_CLOSEDOOR: + if ( !(pStructure->fFlags & STRUCTURE_OPEN) ) + { + // door is already closed! + fDoUseDoor = FALSE; + } + break; + default: + break; + } } - break; - case SCHEDULE_ACTION_GRIDNO: - // Only uses the first gridno - if ( pSoldier->sGridNo == usGridNo1 ) + if (fDoUseDoor) { - // done! + pSoldier->usActionData = usGridNo1; + if (ubScheduleAction == SCHEDULE_ACTION_UNLOCKDOOR) + { + return( AI_ACTION_UNLOCK_DOOR ); + } + else + { + return( AI_ACTION_OPEN_OR_CLOSE_DOOR ); + } + } + + // the door is already in the desired state, or it doesn't exist! + pSoldier->bAIScheduleProgress++; + // fall through + + case 2: + if (pSoldier->sGridNo == usGridNo2 || pSoldier->sGridNo == NOWHERE) + { + // NOWHERE indicates we were supposed to go off map and have done so DoneScheduleAction( pSoldier ); if ( pSoldier->sGridNo != NOWHERE ) { @@ -386,131 +360,119 @@ INT8 DecideActionSchedule( SOLDIERTYPE * pSoldier ) } } else + { + if ( GridNoOnEdgeOfMap( usGridNo2, &bDirection ) ) + { + // told to go to edge of map, so go off at that point! + pSoldier->ubQuoteActionID = GetTraversalQuoteActionID( bDirection ); + } + pSoldier->usActionData = usGridNo2; + pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; + return( AI_ACTION_SCHEDULE_MOVE ); + } + break; + } + break; + + case SCHEDULE_ACTION_GRIDNO: + // Only uses the first gridno + if ( pSoldier->sGridNo == usGridNo1 ) + { + // done! + DoneScheduleAction( pSoldier ); + if ( pSoldier->sGridNo != NOWHERE ) + { + pSoldier->usPatrolGrid[0] = pSoldier->sGridNo; + } + } + else + { + // move! + pSoldier->usActionData = usGridNo1; + pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; + return( AI_ACTION_SCHEDULE_MOVE ); + } + break; + case SCHEDULE_ACTION_LEAVESECTOR: + //Doesn't use any gridno data + switch( pSoldier->bAIScheduleProgress ) + { + case 0: // start the action + + pSoldier->usActionData = FindNearestEdgePoint( pSoldier->sGridNo ); + + if (pSoldier->usActionData == NOWHERE) + { +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Civilian could not find path to map edge!" ); +#endif + DoneScheduleAction( pSoldier ); + return( AI_ACTION_NONE ); + } + + if ( pSoldier->sGridNo == pSoldier->usActionData ) + { + // time to go off the map + pSoldier->bAIScheduleProgress++; + } + else { // move! - pSoldier->usActionData = usGridNo1; pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; return( AI_ACTION_SCHEDULE_MOVE ); } - break; - case SCHEDULE_ACTION_LEAVESECTOR: - //Doesn't use any gridno data - switch( pSoldier->bAIScheduleProgress ) + + // fall through + + case 1: // near edge + + pSoldier->usActionData = FindNearbyPointOnEdgeOfMap( pSoldier, &bDirection ); + if (pSoldier->usActionData == NOWHERE) { - case 0: // start the action - - pSoldier->usActionData = FindNearestEdgePoint( pSoldier->sGridNo ); - - if (pSoldier->usActionData == NOWHERE) - { -#ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Civilian could not find path to map edge!" ); -#endif - DoneScheduleAction( pSoldier ); - return( AI_ACTION_NONE ); - } - - if ( pSoldier->sGridNo == pSoldier->usActionData ) - { - // time to go off the map - pSoldier->bAIScheduleProgress++; - } - else - { - // move! - pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; - return( AI_ACTION_SCHEDULE_MOVE ); - } - - // fall through - - case 1: // near edge - - pSoldier->usActionData = FindNearbyPointOnEdgeOfMap( pSoldier, &bDirection ); - if (pSoldier->usActionData == NOWHERE) - { - // what the heck?? - // ABORT! - DoneScheduleAction( pSoldier ); - } - else - { - pSoldier->ubQuoteActionID = GetTraversalQuoteActionID( bDirection ); - pSoldier->bAIScheduleProgress++; - pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; - return( AI_ACTION_SCHEDULE_MOVE ); - } - break; - - case 2: // should now be done! - DoneScheduleAction( pSoldier ); - break; - - default: - break; - } - break; - - case SCHEDULE_ACTION_ENTERSECTOR: - if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].ubMiscFlags & PROFILE_MISC_FLAG2_DONT_ADD_TO_SECTOR ) - { - // ignore. + // what the heck?? + // ABORT! DoneScheduleAction( pSoldier ); - break; - } - switch( pSoldier->bAIScheduleProgress ) - { - case 0: - sX = CenterX( pSoldier->sOffWorldGridNo ); - sY = CenterY( pSoldier->sOffWorldGridNo ); - EVENT_SetSoldierPosition( pSoldier, sX, sY ); - pSoldier->bInSector = TRUE; - MoveSoldierFromAwayToMercSlot( pSoldier ); - pSoldier->usActionData = usGridNo1; - pSoldier->bAIScheduleProgress++; - pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; - return( AI_ACTION_SCHEDULE_MOVE ); - case 1: - if (pSoldier->sGridNo == usGridNo1) - { - DoneScheduleAction( pSoldier ); - if ( pSoldier->sGridNo != NOWHERE ) - { - pSoldier->usPatrolGrid[0] = pSoldier->sGridNo; - } - } - else - { - pSoldier->usActionData = usGridNo1; - pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; - return( AI_ACTION_SCHEDULE_MOVE ); - } - break; - } - break; - - case SCHEDULE_ACTION_WAKE: - // Go to this position - if (pSoldier->sGridNo == pSoldier->sInitialGridNo) - { - // th-th-th-that's it! - DoneScheduleAction( pSoldier ); - pSoldier->usPatrolGrid[0] = pSoldier->sGridNo; } else { - pSoldier->usActionData = pSoldier->sInitialGridNo; + pSoldier->ubQuoteActionID = GetTraversalQuoteActionID( bDirection ); + pSoldier->bAIScheduleProgress++; pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; return( AI_ACTION_SCHEDULE_MOVE ); } break; - case SCHEDULE_ACTION_SLEEP: - // Go to this position + case 2: // should now be done! + DoneScheduleAction( pSoldier ); + break; + + default: + break; + } + break; + + case SCHEDULE_ACTION_ENTERSECTOR: + if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].ubMiscFlags & PROFILE_MISC_FLAG2_DONT_ADD_TO_SECTOR ) + { + // ignore. + DoneScheduleAction( pSoldier ); + break; + } + switch( pSoldier->bAIScheduleProgress ) + { + case 0: + sX = CenterX( pSoldier->sOffWorldGridNo ); + sY = CenterY( pSoldier->sOffWorldGridNo ); + EVENT_SetSoldierPosition( pSoldier, sX, sY ); + pSoldier->bInSector = TRUE; + MoveSoldierFromAwayToMercSlot( pSoldier ); + pSoldier->usActionData = usGridNo1; + pSoldier->bAIScheduleProgress++; + pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; + return( AI_ACTION_SCHEDULE_MOVE ); + case 1: if (pSoldier->sGridNo == usGridNo1) { - // Sleep - pSoldier->fAIFlags |= AI_ASLEEP; DoneScheduleAction( pSoldier ); if ( pSoldier->sGridNo != NOWHERE ) { @@ -524,6 +486,44 @@ INT8 DecideActionSchedule( SOLDIERTYPE * pSoldier ) return( AI_ACTION_SCHEDULE_MOVE ); } break; + } + break; + + case SCHEDULE_ACTION_WAKE: + // Go to this position + if (pSoldier->sGridNo == pSoldier->sInitialGridNo) + { + // th-th-th-that's it! + DoneScheduleAction( pSoldier ); + pSoldier->usPatrolGrid[0] = pSoldier->sGridNo; + } + else + { + pSoldier->usActionData = pSoldier->sInitialGridNo; + pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; + return( AI_ACTION_SCHEDULE_MOVE ); + } + break; + + case SCHEDULE_ACTION_SLEEP: + // Go to this position + if (pSoldier->sGridNo == usGridNo1) + { + // Sleep + pSoldier->fAIFlags |= AI_ASLEEP; + DoneScheduleAction( pSoldier ); + if ( pSoldier->sGridNo != NOWHERE ) + { + pSoldier->usPatrolGrid[0] = pSoldier->sGridNo; + } + } + else + { + pSoldier->usActionData = usGridNo1; + pSoldier->sAbsoluteFinalDestination = pSoldier->usActionData; + return( AI_ACTION_SCHEDULE_MOVE ); + } + break; } @@ -535,9 +535,9 @@ INT8 DecideActionBoxerEnteringRing(SOLDIERTYPE *pSoldier) UINT8 ubRoom; INT16 sDesiredMercLoc; UINT8 ubDesiredMercDir; - #ifdef DEBUGDECISIONS - STR16 tempstr; - #endif +#ifdef DEBUGDECISIONS + STR16 tempstr; +#endif // boxer, should move into ring! if ( InARoom( pSoldier->sGridNo, &ubRoom )) { @@ -556,10 +556,10 @@ INT8 DecideActionBoxerEnteringRing(SOLDIERTYPE *pSoldier) pSoldier->usActionData = ubDesiredMercDir; - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - TURNS TOWARDS CLOSEST PC to face direction %d",pSoldier->name,pSoldier->usActionData); AIPopMessage(tempstr); - #endif +#endif return( AI_ACTION_CHANGE_FACING ); } @@ -583,9 +583,9 @@ INT8 DecideActionNamedNPC( SOLDIERTYPE * pSoldier ) UINT8 ubDesiredMercDir; UINT8 ubDesiredMerc; INT16 sDesiredMercDist; - #ifdef DEBUGDECISIONS - STR16 tempstr; - #endif +#ifdef DEBUGDECISIONS + STR16 tempstr; +#endif // if a quote record has been set and we're not doing movement, then // it means we have to wait until someone is nearby and then see @@ -616,10 +616,10 @@ INT8 DecideActionNamedNPC( SOLDIERTYPE * pSoldier ) pSoldier->usActionData = ubDesiredMercDir; - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - TURNS TOWARDS CLOSEST PC to face direction %d",pSoldier->name,pSoldier->usActionData); AIPopMessage(tempstr); - #endif +#endif return( AI_ACTION_CHANGE_FACING ); } @@ -641,36 +641,36 @@ INT8 DecideActionNamedNPC( SOLDIERTYPE * pSoldier ) } } - switch( pSoldier->ubProfile ) + switch( pSoldier->ubProfile ) { - case JIM: - case JACK: - case OLAF: - case RAY: - case OLGA: - case TYRONE: - sDesiredMercLoc = ClosestPC( pSoldier, &sDesiredMercDist ); - if (sDesiredMercLoc != NOWHERE ) + case JIM: + case JACK: + case OLAF: + case RAY: + case OLGA: + case TYRONE: + sDesiredMercLoc = ClosestPC( pSoldier, &sDesiredMercDist ); + if (sDesiredMercLoc != NOWHERE ) + { + if ( sDesiredMercDist <= NPC_TALK_RADIUS * 2 ) { - if ( sDesiredMercDist <= NPC_TALK_RADIUS * 2 ) + AddToShouldBecomeHostileOrSayQuoteList( pSoldier->ubID ); + // now wait a bit! + pSoldier->usActionData = 5000; + return( AI_ACTION_WAIT ); + } + else + { + pSoldier->usActionData = GoAsFarAsPossibleTowards( pSoldier, sDesiredMercLoc, AI_ACTION_APPROACH_MERC ); + if ( pSoldier->usActionData != NOWHERE ) { - AddToShouldBecomeHostileOrSayQuoteList( pSoldier->ubID ); - // now wait a bit! - pSoldier->usActionData = 5000; - return( AI_ACTION_WAIT ); - } - else - { - pSoldier->usActionData = GoAsFarAsPossibleTowards( pSoldier, sDesiredMercLoc, AI_ACTION_APPROACH_MERC ); - if ( pSoldier->usActionData != NOWHERE ) - { - return( AI_ACTION_APPROACH_MERC ); - } + return( AI_ACTION_APPROACH_MERC ); } } - break; - default: - break; + } + break; + default: + break; } return( AI_ACTION_NONE ); @@ -681,14 +681,14 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier) { DOUBLE iChance, iSneaky = 10; INT8 bInWater,bInGas; - #ifdef DEBUGDECISIONS - STR16 tempstr; - #endif - -DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen, orders = %d",pSoldier->bOrders)); +#ifdef DEBUGDECISIONS + STR16 tempstr; +#endif -BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP || pSoldier->bNeutral || (pSoldier->ubBodyType >= FATCIV && pSoldier->ubBodyType <= CRIPPLECIV) ) ); - BOOLEAN fCivilianOrMilitia = PTR_CIV_OR_MILITIA; + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen, orders = %d",pSoldier->bOrders)); + + BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP || pSoldier->bNeutral || (pSoldier->ubBodyType >= FATCIV && pSoldier->ubBodyType <= CRIPPLECIV) ) ); + BOOLEAN fCivilianOrMilitia = PTR_CIV_OR_MILITIA; gubNPCPathCount = 0; @@ -771,13 +771,13 @@ BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP } - bInWater = Water( pSoldier->sGridNo ); + bInWater = Water( pSoldier->sGridNo ); - // check if standing in tear gas without a gas mask on, or in smoke - bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); + // check if standing in tear gas without a gas mask on, or in smoke + bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); - // if real-time, and not in the way, do nothing 90% of the time (for GUARDS!) - // unless in water (could've started there), then we better swim to shore! + // if real-time, and not in the way, do nothing 90% of the time (for GUARDS!) + // unless in water (could've started there), then we better swim to shore! if (fCivilian) { @@ -835,37 +835,18 @@ BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP } - - - -//////////////////////////////////////////////////////////////////////////// - // POINT PATROL: move towards next point unless getting a bit winded - //////////////////////////////////////////////////////////////////////////// - // this takes priority over water/gas checks, so that point patrol WILL work - // from island to island, and through gas covered areas, too - if ((pSoldier->bOrders == POINTPATROL) && (pSoldier->bBreath >= 75)) - { - if (PointPatrolAI(pSoldier)) - { - if (!gfTurnBasedAI) - { - // wait after this... - pSoldier->bNextAction = AI_ACTION_WAIT; - pSoldier->usNextActionData = RealtimeDelay( pSoldier ); - } - return(AI_ACTION_POINT_PATROL); - } - else - { - // Reset path count to avoid dedlok - gubNPCPathCount = 0; - } - } - if ((pSoldier->bOrders == RNDPTPATROL) && (pSoldier->bBreath >=75)) - { - if (RandomPointPatrolAI(pSoldier)) + + //////////////////////////////////////////////////////////////////////////// + // POINT PATROL: move towards next point unless getting a bit winded + //////////////////////////////////////////////////////////////////////////// + + // this takes priority over water/gas checks, so that point patrol WILL work + // from island to island, and through gas covered areas, too + if ((pSoldier->bOrders == POINTPATROL) && (pSoldier->bBreath >= 75)) + { + if (PointPatrolAI(pSoldier)) { if (!gfTurnBasedAI) { @@ -873,36 +854,55 @@ BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP pSoldier->bNextAction = AI_ACTION_WAIT; pSoldier->usNextActionData = RealtimeDelay( pSoldier ); } - return(AI_ACTION_POINT_PATROL); - } - else - { - // Reset path count to avoid dedlok + return(AI_ACTION_POINT_PATROL); + } + else + { + // Reset path count to avoid dedlok gubNPCPathCount = 0; - } + } + } - } + if ((pSoldier->bOrders == RNDPTPATROL) && (pSoldier->bBreath >=75)) + { + if (RandomPointPatrolAI(pSoldier)) + { + if (!gfTurnBasedAI) + { + // wait after this... + pSoldier->bNextAction = AI_ACTION_WAIT; + pSoldier->usNextActionData = RealtimeDelay( pSoldier ); + } + return(AI_ACTION_POINT_PATROL); + } + else + { + // Reset path count to avoid dedlok + gubNPCPathCount = 0; + } - //////////////////////////////////////////////////////////////////////////// - // WHEN LEFT IN WATER OR GAS, GO TO NEAREST REACHABLE SPOT OF UNGASSED LAND - //////////////////////////////////////////////////////////////////////////// + } - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: get out of water and gas")); + //////////////////////////////////////////////////////////////////////////// + // WHEN LEFT IN WATER OR GAS, GO TO NEAREST REACHABLE SPOT OF UNGASSED LAND + //////////////////////////////////////////////////////////////////////////// - if (bInWater || bInGas) - { - pSoldier->usActionData = FindNearestUngassedLand(pSoldier); + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: get out of water and gas")); - if (pSoldier->usActionData != NOWHERE) - { + if (bInWater || bInGas) + { + pSoldier->usActionData = FindNearestUngassedLand(pSoldier); + + if (pSoldier->usActionData != NOWHERE) + { #ifdef DEBUGDECISIONS sprintf(tempstr,"%s - SEEKING NEAREST UNGASSED LAND at grid %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); + AIPopMessage(tempstr); #endif - return(AI_ACTION_LEAVE_WATER_GAS); - } - } + return(AI_ACTION_LEAVE_WATER_GAS); + } + } @@ -910,7 +910,7 @@ BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP // REST IF RUNNING OUT OF BREATH //////////////////////////////////////////////////////////////////////// - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: rest if running out of breath")); + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: rest if running out of breath")); // if our breath is running a bit low, and we're not in the way or in water if ((pSoldier->bBreath < 75) && !bInWater) { @@ -921,9 +921,9 @@ BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP } - //////////////////////////////////////////////////////////////////////////// - // CLIMB A BUILDING - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // CLIMB A BUILDING + //////////////////////////////////////////////////////////////////////////// if (!fCivilian) { @@ -931,29 +931,29 @@ BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP // set base chance and maximum seeking distance according to orders switch (pSoldier->bOrders) - { - case STATIONARY: iChance *= 0; break; - case ONGUARD: iChance += 10; break; - case ONCALL: break; - case CLOSEPATROL: iChance += -20; break; - case RNDPTPATROL: - case POINTPATROL: iChance = -30; break; - case FARPATROL: iChance += -40; break; - case SEEKENEMY: iChance += -30; break; - case SNIPER: iChance += 70; break; - } + { + case STATIONARY: iChance *= 0; break; + case ONGUARD: iChance += 10; break; + case ONCALL: break; + case CLOSEPATROL: iChance += -20; break; + case RNDPTPATROL: + case POINTPATROL: iChance = -30; break; + case FARPATROL: iChance += -40; break; + case SEEKENEMY: iChance += -30; break; + case SNIPER: iChance += 70; break; + } // modify for attitude switch (pSoldier->bAttitude) - { - case DEFENSIVE: iChance *= 1.5; break; - case BRAVESOLO: iChance /= 2; break; - case BRAVEAID: iChance /= 2; break; - case CUNNINGSOLO: iChance *= 1; break; - case CUNNINGAID: iChance /= 1; break; - case AGGRESSIVE: iChance /= 3; break; - case ATTACKSLAYONLY: break; - } + { + case DEFENSIVE: iChance *= 1.5; break; + case BRAVESOLO: iChance /= 2; break; + case BRAVEAID: iChance /= 2; break; + case CUNNINGSOLO: iChance *= 1; break; + case CUNNINGAID: iChance /= 1; break; + case AGGRESSIVE: iChance /= 3; break; + case ATTACKSLAYONLY: break; + } //hide those suicidal militia on the roofs for better defensive positions @@ -967,78 +967,82 @@ BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP //iChance -= (100 - pSoldier->bBreath); // don't care if ((INT16) PreRandom(100) < iChance) + { + if ( pSoldier->bLevel == 0 ) { - if ( pSoldier->bLevel == 0 ) - { - BOOLEAN fUp = TRUE; - if (pSoldier->bLevel > 0 ) - fUp = FALSE; + BOOLEAN fUp = TRUE; + if (pSoldier->bLevel > 0 ) + fUp = FALSE; - if ( CanClimbFromHere ( pSoldier, fUp ) ) + if ( CanClimbFromHere ( pSoldier, fUp ) ) + { + DebugMsg ( TOPIC_JA2AI , DBG_LEVEL_3 , String("Soldier %d is climbing roof",pSoldier->ubID) ); + return( AI_ACTION_CLIMB_ROOF ); + } + else + { + pSoldier->usActionData = FindClosestClimbPoint(pSoldier, fUp ); + // Added the check here because sniper militia who are locked inside of a building without keys + // will still have a >100% chance to want to climb, which means an infinite loop. In fact, any + // time a move is desired, there is also probably be a need to check for a path. + if ( pSoldier->usActionData != NOWHERE && + LegalNPCDestination(pSoldier,pSoldier->usActionData,ENSURE_PATH,WATEROK, 0 )) { - DebugMsg ( TOPIC_JA2AI , DBG_LEVEL_3 , String("Soldier %d is climbing roof",pSoldier->ubID) ); - return( AI_ACTION_CLIMB_ROOF ); - } - else - { - pSoldier->usActionData = FindClosestClimbPoint(pSoldier, fUp ); - if ( pSoldier->usActionData != NOWHERE ) - { - return( AI_ACTION_MOVE_TO_CLIMB ); - } + return( AI_ACTION_MOVE_TO_CLIMB ); } } } - } + } + } - -//////////////////////////////////////////////////////////////////////////// - // RANDOM PATROL: determine % chance to start a new patrol route - //////////////////////////////////////////////////////////////////////////// - if (!gubNPCPathCount) // try to limit pathing in Green AI - { + + //////////////////////////////////////////////////////////////////////////// + // RANDOM PATROL: determine % chance to start a new patrol route + //////////////////////////////////////////////////////////////////////////// + if (!gubNPCPathCount) // try to limit pathing in Green AI + { iChance = 25 + pSoldier->bBypassToGreen; // set base chance according to orders switch (pSoldier->bOrders) - { - case STATIONARY: iChance += -20; break; - case ONGUARD: iChance += -15; break; - case ONCALL: break; - case CLOSEPATROL: iChance += +15; break; - case RNDPTPATROL: - case POINTPATROL: iChance = 0; break; + { + case STATIONARY: iChance += -20; break; + case ONGUARD: iChance += -15; break; + case ONCALL: break; + case CLOSEPATROL: iChance += +15; break; + case RNDPTPATROL: + case POINTPATROL: iChance = 0; break; /* if ( !gfTurnBasedAI ) - { - // realtime deadlock... increase chance! - iChance = 110;// more than 100 in case person is defensive - } - else if ( pSoldier->bInitialActionPoints < pSoldier->bActionPoints ) // could be less because of carried-over points - { - // CJC: allow pt patrol guys to do a random move in case - // of a deadlock provided they haven't done anything yet this turn - iChance= 0; - } - break; - */ - case FARPATROL: iChance += +25; break; - case SEEKENEMY: iChance += -10; break; - case SNIPER: iChance += -10; break; + { + // realtime deadlock... increase chance! + iChance = 110;// more than 100 in case person is defensive } + else if ( pSoldier->bInitialActionPoints < pSoldier->bActionPoints ) // could be less because of carried-over points + { + // CJC: allow pt patrol guys to do a random move in case + // of a deadlock provided they haven't done anything yet this turn + iChance= 0; + } + break; + */ + case FARPATROL: iChance += +25; break; + case SEEKENEMY: iChance += -10; break; + case SNIPER: iChance += -10; break; + } // modify chance of patrol (and whether it's a sneaky one) by attitude switch (pSoldier->bAttitude) - { - case DEFENSIVE: iChance += -10; break; - case BRAVESOLO: iChance += 5; break; - case BRAVEAID: break; - case CUNNINGSOLO: iChance += 5; iSneaky += 10; break; - case CUNNINGAID: iSneaky += 5; break; - case AGGRESSIVE: iChance += 10; iSneaky += -5; break; - case ATTACKSLAYONLY: iChance += 10; iSneaky += -5; break; - } + { + case DEFENSIVE: iChance += -10; break; + case BRAVESOLO: iChance += 5; break; + case BRAVEAID: break; + case CUNNINGSOLO: iChance += 5; iSneaky += 10; break; + case CUNNINGAID: iSneaky += 5; break; + case AGGRESSIVE: iChance += 10; iSneaky += -5; break; + case ATTACKSLAYONLY: iChance += 10; iSneaky += -5; break; + } // reduce chance for any injury, less likely to wander around when hurt iChance -= (pSoldier->bLifeMax - pSoldier->bLife); @@ -1050,34 +1054,34 @@ BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP // if we're in water with land miles (> 25 tiles) away, // OR if we roll under the chance calculated if (bInWater || ((INT16) PreRandom(100) < iChance)) - { + { pSoldier->usActionData = RandDestWithinRange(pSoldier); if (pSoldier->usActionData != NOWHERE) - { + { pSoldier->usActionData = GoAsFarAsPossibleTowards( pSoldier, pSoldier->usActionData, AI_ACTION_RANDOM_PATROL ); } if (pSoldier->usActionData != NOWHERE) - { - #ifdef DEBUGDECISIONS + { +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - RANDOM PATROL to grid %d",pSoldier->name,pSoldier->usActionData); AIPopMessage(tempstr); - #endif - - if (!gfTurnBasedAI) - { - // wait after this... - pSoldier->bNextAction = AI_ACTION_WAIT; - pSoldier->usNextActionData = RealtimeDelay( pSoldier ); - } - return(AI_ACTION_RANDOM_PATROL); +#endif + + if (!gfTurnBasedAI) + { + // wait after this... + pSoldier->bNextAction = AI_ACTION_WAIT; + pSoldier->usNextActionData = RealtimeDelay( pSoldier ); } + return(AI_ACTION_RANDOM_PATROL); } } + } - if (!gubNPCPathCount) // try to limit pathing in Green AI - { + if (!gubNPCPathCount) // try to limit pathing in Green AI + { //////////////////////////////////////////////////////////////////////////// // SEEK FRIEND: determine %chance for man to pay a friendly visit //////////////////////////////////////////////////////////////////////////// @@ -1086,29 +1090,29 @@ BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP // set base chance and maximum seeking distance according to orders switch (pSoldier->bOrders) - { - case STATIONARY: iChance += -20; break; - case ONGUARD: iChance += -15; break; - case ONCALL: break; - case CLOSEPATROL: iChance += +10; break; - case RNDPTPATROL: - case POINTPATROL: iChance = -10; break; - case FARPATROL: iChance += +20; break; - case SEEKENEMY: iChance += -10; break; - case SNIPER: iChance += -10; break; - } + { + case STATIONARY: iChance += -20; break; + case ONGUARD: iChance += -15; break; + case ONCALL: break; + case CLOSEPATROL: iChance += +10; break; + case RNDPTPATROL: + case POINTPATROL: iChance = -10; break; + case FARPATROL: iChance += +20; break; + case SEEKENEMY: iChance += -10; break; + case SNIPER: iChance += -10; break; + } // modify for attitude switch (pSoldier->bAttitude) - { - case DEFENSIVE: break; - case BRAVESOLO: iChance /= 2; break; // loners - case BRAVEAID: iChance += 10; break; // friendly - case CUNNINGSOLO: iChance /= 2; break; // loners - case CUNNINGAID: iChance += 10; break; // friendly - case AGGRESSIVE: break; - case ATTACKSLAYONLY: break; - } + { + case DEFENSIVE: break; + case BRAVESOLO: iChance /= 2; break; // loners + case BRAVEAID: iChance += 10; break; // friendly + case CUNNINGSOLO: iChance /= 2; break; // loners + case CUNNINGAID: iChance += 10; break; // friendly + case AGGRESSIVE: break; + case ATTACKSLAYONLY: break; + } // reduce chance for any injury, less likely to wander around when hurt iChance -= (pSoldier->bLifeMax - pSoldier->bLife); @@ -1118,101 +1122,101 @@ BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP if ((INT16) PreRandom(100) < iChance) - { + { if (RandomFriendWithin(pSoldier)) + { + if ( pSoldier->usActionData == GoAsFarAsPossibleTowards( pSoldier, pSoldier->usActionData, AI_ACTION_SEEK_FRIEND ) ) { - if ( pSoldier->usActionData == GoAsFarAsPossibleTowards( pSoldier, pSoldier->usActionData, AI_ACTION_SEEK_FRIEND ) ) - { - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - SEEK FRIEND at grid %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); - #endif + AIPopMessage(tempstr); +#endif - if (fCivilianOrMilitia && !gfTurnBasedAI) - { - // pause at the end of the walk! - pSoldier->bNextAction = AI_ACTION_WAIT; - pSoldier->usNextActionData = (UINT16) REALTIME_CIV_AI_DELAY; - } + if (fCivilianOrMilitia && !gfTurnBasedAI) + { + // pause at the end of the walk! + pSoldier->bNextAction = AI_ACTION_WAIT; + pSoldier->usNextActionData = (UINT16) REALTIME_CIV_AI_DELAY; + } return(AI_ACTION_SEEK_FRIEND); - } } } } + } - -//////////////////////////////////////////////////////////////////////////// - // SNIPERS LIKE TO CROUCH (on roofs) - //////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////// + // SNIPERS LIKE TO CROUCH (on roofs) + //////////////////////////////////////////////////////////////////////////// DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Snipers like to crouch, sniper = %d",pSoldier->sniper)); - // if not in water and not already crouched, try to crouch down first - if (pSoldier->bOrders == SNIPER && !PTR_CROUCHED && IsValidStance( pSoldier, ANIM_CROUCH ) && pSoldier->bLevel == 1 ) - { - if (!gfTurnBasedAI || (GetAPsToChangeStance( pSoldier, ANIM_CROUCH ) <= pSoldier->bActionPoints)) + // if not in water and not already crouched, try to crouch down first + if (pSoldier->bOrders == SNIPER && !PTR_CROUCHED && IsValidStance( pSoldier, ANIM_CROUCH ) && pSoldier->bLevel == 1 ) { - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Sniper is crouching")); - pSoldier->usActionData = ANIM_CROUCH; - pSoldier->sniper = 0; - return(AI_ACTION_CHANGE_STANCE); + if (!gfTurnBasedAI || (GetAPsToChangeStance( pSoldier, ANIM_CROUCH ) <= pSoldier->bActionPoints)) + { + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Sniper is crouching")); + pSoldier->usActionData = ANIM_CROUCH; + pSoldier->sniper = 0; + return(AI_ACTION_CHANGE_STANCE); + } } - } - //////////////////////////////////////////////////////////////////////////// - // SNIPER - RAISE WEAPON TO SCAN AREA - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // SNIPER - RAISE WEAPON TO SCAN AREA + //////////////////////////////////////////////////////////////////////////// -DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Snipers like to raise weapons, sniper = %d",pSoldier->sniper)); - if ( pSoldier->bOrders == SNIPER && pSoldier->sniper == 0 && ( pSoldier->bLevel == 1 || Random(100) < 40 ) ) - { - if (!gfTurnBasedAI || GetAPsToReadyWeapon( pSoldier, READY_RIFLE_CROUCH ) <= pSoldier->bActionPoints) + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Snipers like to raise weapons, sniper = %d",pSoldier->sniper)); + if ( pSoldier->bOrders == SNIPER && pSoldier->sniper == 0 && ( pSoldier->bLevel == 1 || Random(100) < 40 ) ) { - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Sniper is raising weapon, soldier = %d, sniper = %d",pSoldier->ubID,pSoldier->sniper)); - pSoldier->sniper = 1; - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Sniper = %d",pSoldier->sniper)); - return(AI_ACTION_RAISE_GUN); + if (!gfTurnBasedAI || GetAPsToReadyWeapon( pSoldier, READY_RIFLE_CROUCH ) <= pSoldier->bActionPoints) + { + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Sniper is raising weapon, soldier = %d, sniper = %d",pSoldier->ubID,pSoldier->sniper)); + pSoldier->sniper = 1; + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Sniper = %d",pSoldier->sniper)); + return(AI_ACTION_RAISE_GUN); + } } - } - //else if ( pSoldier->sniper == 1 ) - //{ + //else if ( pSoldier->sniper == 1 ) + //{ // DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Sniper is lowering weapon, sniper = %d",pSoldier->sniper)); // pSoldier->sniper = 0; // DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Sniper = %d",pSoldier->sniper)); // return(AI_ACTION_LOWER_GUN); - //} + //} - //////////////////////////////////////////////////////////////////////////// - // LOOK AROUND: determine %chance for man to turn in place - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // LOOK AROUND: determine %chance for man to turn in place + //////////////////////////////////////////////////////////////////////////// DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Soldier deciding to turn")); if (!gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints) { - // avoid 2 consecutive random turns in a row + // avoid 2 consecutive random turns in a row if (pSoldier->bLastAction != AI_ACTION_CHANGE_FACING) { - iChance = 25 + pSoldier->bBypassToGreen; + iChance = 25 + pSoldier->bBypassToGreen; - // set base chance according to orders - if (pSoldier->bOrders == STATIONARY || pSoldier->bOrders == SNIPER) - iChance += 25; + // set base chance according to orders + if (pSoldier->bOrders == STATIONARY || pSoldier->bOrders == SNIPER) + iChance += 25; - if (pSoldier->bOrders == ONGUARD) - iChance += 20; + if (pSoldier->bOrders == ONGUARD) + iChance += 20; - if (pSoldier->bAttitude == DEFENSIVE) - iChance += 25; + if (pSoldier->bAttitude == DEFENSIVE) + iChance += 25; - if ( pSoldier->bOrders == SNIPER && pSoldier->bLevel == 1) - iChance += 35; + if ( pSoldier->bOrders == SNIPER && pSoldier->bLevel == 1) + iChance += 35; - if ((INT16)PreRandom(100) < iChance) + if ((INT16)PreRandom(100) < iChance) { - // roll random directions (stored in actionData) until different from current - do + // roll random directions (stored in actionData) until different from current + do { // if man has a LEGAL dominant facing, and isn't facing it, he will turn // back towards that facing 50% of the time here (normally just enemies) @@ -1221,7 +1225,7 @@ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Snipers like to raise { pSoldier->usActionData = pSoldier->bDominantDir; } - else + else { INT32 iNoiseValue; BOOLEAN fClimb; @@ -1231,24 +1235,24 @@ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Snipers like to raise if (sNoiseGridNo != NOWHERE) ubNoiseDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sNoiseGridNo),CenterY(sNoiseGridNo)); - + if ( sNoiseGridNo != NOWHERE && pSoldier->bDirection != ubNoiseDir ) - pSoldier->usActionData = ubNoiseDir; + pSoldier->usActionData = ubNoiseDir; else - pSoldier->usActionData = (UINT16)PreRandom(8); + pSoldier->usActionData = (UINT16)PreRandom(8); } } while (pSoldier->usActionData == pSoldier->bDirection); - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - TURNS to face direction %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); - #endif + AIPopMessage(tempstr); +#endif DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Trying to turn - checking stance validity, sniper = %d",pSoldier->sniper)); if ( InternalIsValidStance( pSoldier, (INT8) pSoldier->usActionData, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) ) { - + if ( !gfTurnBasedAI ) { // wait after this... @@ -1262,7 +1266,7 @@ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Snipers like to raise } } } - + //////////////////////////////////////////////////////////////////////////// // NONE: @@ -1276,18 +1280,18 @@ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: Snipers like to raise INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) { - INT32 iDummy; - UINT8 ubNoiseDir; - INT16 sNoiseGridNo; - INT32 iNoiseValue; - INT32 iChance, iSneaky; - INT16 sClosestFriend; - BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP || pSoldier->bNeutral || (pSoldier->ubBodyType >= FATCIV && pSoldier->ubBodyType <= CRIPPLECIV) ) ); - BOOLEAN fClimb; - BOOLEAN fReachable; - #ifdef DEBUGDECISIONS - STR16 tempstr; - #endif + INT32 iDummy; + UINT8 ubNoiseDir; + INT16 sNoiseGridNo; + INT32 iNoiseValue; + INT32 iChance, iSneaky; + INT16 sClosestFriend; + BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP || pSoldier->bNeutral || (pSoldier->ubBodyType >= FATCIV && pSoldier->ubBodyType <= CRIPPLECIV) ) ); + BOOLEAN fClimb; + BOOLEAN fReachable; +#ifdef DEBUGDECISIONS + STR16 tempstr; +#endif if (fCivilian) @@ -1317,150 +1321,150 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) } - // determine the most important noise heard, and its relative value - sNoiseGridNo = MostImportantNoiseHeard(pSoldier,&iNoiseValue, &fClimb, &fReachable); - //NumMessage("iNoiseValue = ",iNoiseValue); + // determine the most important noise heard, and its relative value + sNoiseGridNo = MostImportantNoiseHeard(pSoldier,&iNoiseValue, &fClimb, &fReachable); + //NumMessage("iNoiseValue = ",iNoiseValue); if (sNoiseGridNo == NOWHERE) { - // then we have no business being under YELLOW status any more! + // then we have no business being under YELLOW status any more! #ifdef RECORDNET - fprintf(NetDebugFile,"\nDecideActionYellow: ERROR - No important noise known by guynum %d\n\n",pSoldier->ubID); + fprintf(NetDebugFile,"\nDecideActionYellow: ERROR - No important noise known by guynum %d\n\n",pSoldier->ubID); #endif #ifdef BETAVERSION - NumMessage("DecideActionYellow: ERROR - No important noise known by guynum ",pSoldier->ubID); + NumMessage("DecideActionYellow: ERROR - No important noise known by guynum ",pSoldier->ubID); #endif - + return(AI_ACTION_NONE); } - //////////////////////////////////////////////////////////////////////////// - // LOOK AROUND TOWARD NOISE: determine %chance for man to turn towards noise - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // LOOK AROUND TOWARD NOISE: determine %chance for man to turn towards noise + //////////////////////////////////////////////////////////////////////////// - // determine direction from this soldier in which the noise lies - ubNoiseDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sNoiseGridNo),CenterY(sNoiseGridNo)); + // determine direction from this soldier in which the noise lies + ubNoiseDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sNoiseGridNo),CenterY(sNoiseGridNo)); - // if soldier is not already facing in that direction, - // and the noise source is close enough that it could possibly be seen - if ( !gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints ) - { - if ((pSoldier->bDirection != ubNoiseDir) && PythSpacesAway(pSoldier->sGridNo,sNoiseGridNo) <= MaxDistanceVisible() ) + // if soldier is not already facing in that direction, + // and the noise source is close enough that it could possibly be seen + if ( !gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints ) + { + if ((pSoldier->bDirection != ubNoiseDir) && PythSpacesAway(pSoldier->sGridNo,sNoiseGridNo) <= MaxDistanceVisible() ) { - // set base chance according to orders - if ((pSoldier->bOrders == STATIONARY) || (pSoldier->bOrders == ONGUARD) ) - iChance = 50; - else // all other orders - iChance = 25; + // set base chance according to orders + if ((pSoldier->bOrders == STATIONARY) || (pSoldier->bOrders == ONGUARD) ) + iChance = 50; + else // all other orders + iChance = 25; - if (pSoldier->bAttitude == DEFENSIVE) - iChance += 15; + if (pSoldier->bAttitude == DEFENSIVE) + iChance += 15; - if ((INT16)PreRandom(100) < iChance && InternalIsValidStance( pSoldier, ubNoiseDir, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) ) + if ((INT16)PreRandom(100) < iChance && InternalIsValidStance( pSoldier, ubNoiseDir, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) ) { - pSoldier->usActionData = ubNoiseDir; - #ifdef DEBUGDECISIONS + pSoldier->usActionData = ubNoiseDir; +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - TURNS TOWARDS NOISE to face direction %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); - #endif - if ( pSoldier->bOrders == SNIPER ) - { - if (!gfTurnBasedAI || GetAPsToReadyWeapon( pSoldier, READY_RIFLE_CROUCH ) <= pSoldier->bActionPoints) + AIPopMessage(tempstr); +#endif + if ( pSoldier->bOrders == SNIPER ) { - pSoldier->bNextAction = AI_ACTION_RAISE_GUN; + if (!gfTurnBasedAI || GetAPsToReadyWeapon( pSoldier, READY_RIFLE_CROUCH ) <= pSoldier->bActionPoints) + { + pSoldier->bNextAction = AI_ACTION_RAISE_GUN; + } } - } - return(AI_ACTION_CHANGE_FACING); + return(AI_ACTION_CHANGE_FACING); } } } - //////////////////////////////////////////////////////////////////////////// - // RADIO YELLOW ALERT: determine %chance to call others and report noise - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // RADIO YELLOW ALERT: determine %chance to call others and report noise + //////////////////////////////////////////////////////////////////////////// - // if we have the action points remaining to RADIO - // (we never want NPCs to choose to radio if they would have to wait a turn) - if ( !fCivilian && (pSoldier->bActionPoints >= AP_RADIO) && - (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) ) - { - // base chance depends on how much new info we have to radio to the others - iChance = 5 * WhatIKnowThatPublicDont(pSoldier,FALSE); // use 5 * for YELLOW alert + // if we have the action points remaining to RADIO + // (we never want NPCs to choose to radio if they would have to wait a turn) + if ( !fCivilian && (pSoldier->bActionPoints >= AP_RADIO) && + (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) ) + { + // base chance depends on how much new info we have to radio to the others + iChance = 5 * WhatIKnowThatPublicDont(pSoldier,FALSE); // use 5 * for YELLOW alert - // if I actually know something they don't and I ain't swimming (deep water) - if (iChance && !DeepWater( pSoldier->sGridNo )) - { + // if I actually know something they don't and I ain't swimming (deep water) + if (iChance && !DeepWater( pSoldier->sGridNo )) + { - // CJC: this addition allows for varying difficulty levels for soldier types - iChance += gbDiff[ DIFF_RADIO_RED_ALERT ][ SoldierDifficultyLevel( pSoldier ) ] / 2; + // CJC: this addition allows for varying difficulty levels for soldier types + iChance += gbDiff[ DIFF_RADIO_RED_ALERT ][ SoldierDifficultyLevel( pSoldier ) ] / 2; - // Alex: this addition replaces the sectorValue/2 in original JA - //iChance += gsDiff[DIFF_RADIO_RED_ALERT][GameOption[ENEMYDIFFICULTY]] / 2; + // Alex: this addition replaces the sectorValue/2 in original JA + //iChance += gsDiff[DIFF_RADIO_RED_ALERT][GameOption[ENEMYDIFFICULTY]] / 2; - // modify base chance according to orders - switch (pSoldier->bOrders) - { - case STATIONARY: iChance += 20; break; - case ONGUARD: iChance += 15; break; - case ONCALL: iChance += 10; break; - case CLOSEPATROL: break; - case RNDPTPATROL: - case POINTPATROL: break; - case FARPATROL: iChance += -10; break; - case SEEKENEMY: iChance += -20; break; - case SNIPER: iChance += -10; break; //Madd: sniper contacts are supposed to be automatically reported - } + // modify base chance according to orders + switch (pSoldier->bOrders) + { + case STATIONARY: iChance += 20; break; + case ONGUARD: iChance += 15; break; + case ONCALL: iChance += 10; break; + case CLOSEPATROL: break; + case RNDPTPATROL: + case POINTPATROL: break; + case FARPATROL: iChance += -10; break; + case SEEKENEMY: iChance += -20; break; + case SNIPER: iChance += -10; break; //Madd: sniper contacts are supposed to be automatically reported + } - // modify base chance according to attitude - switch (pSoldier->bAttitude) - { - case DEFENSIVE: iChance += 20; break; - case BRAVESOLO: iChance += -10; break; - case BRAVEAID: break; - case CUNNINGSOLO:iChance += -5; break; - case CUNNINGAID: break; - case AGGRESSIVE: iChance += -20; break; - case ATTACKSLAYONLY: iChance = 0; break; - } + // modify base chance according to attitude + switch (pSoldier->bAttitude) + { + case DEFENSIVE: iChance += 20; break; + case BRAVESOLO: iChance += -10; break; + case BRAVEAID: break; + case CUNNINGSOLO:iChance += -5; break; + case CUNNINGAID: break; + case AGGRESSIVE: iChance += -20; break; + case ATTACKSLAYONLY: iChance = 0; break; + } #ifdef DEBUGDECISIONS - AINumMessage("Chance to radio yellow alert = ",iChance); + AINumMessage("Chance to radio yellow alert = ",iChance); #endif - if ((INT16)PreRandom(100) < iChance) - { + if ((INT16)PreRandom(100) < iChance) + { #ifdef DEBUGDECISIONS - AINameMessage(pSoldier,"decides to radio a YELLOW alert!",1000); + AINameMessage(pSoldier,"decides to radio a YELLOW alert!",1000); #endif - return(AI_ACTION_YELLOW_ALERT); - } - } - } + return(AI_ACTION_YELLOW_ALERT); + } + } + } if ( TANK( pSoldier ) ) { return( AI_ACTION_NONE ); } - //////////////////////////////////////////////////////////////////////// - // REST IF RUNNING OUT OF BREATH - //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + // REST IF RUNNING OUT OF BREATH + //////////////////////////////////////////////////////////////////////// - // if our breath is running a bit low, and we're not in water - if ((pSoldier->bBreath < 25) && !MercInWater(pSoldier)) - { - // take a breather for gods sake! - pSoldier->usActionData = NOWHERE; - return(AI_ACTION_NONE); - } + // if our breath is running a bit low, and we're not in water + if ((pSoldier->bBreath < 25) && !MercInWater(pSoldier)) + { + // take a breather for gods sake! + pSoldier->usActionData = NOWHERE; + return(AI_ACTION_NONE); + } -//continue flanking + //continue flanking INT16 tempGridNo; if ( sNoiseGridNo == NOWHERE ) tempGridNo = pSoldier->lastFlankSpot; @@ -1517,12 +1521,12 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) return AI_ACTION_SEEK_NOISE ; } - - if ( !( pSoldier->bTeam == CIV_TEAM && pSoldier->ubProfile != NO_PROFILE && pSoldier->ubProfile != ELDIN ) ) - { - // IF WE ARE MILITIA/CIV IN REALTIME, CLOSE TO NOISE, AND CAN SEE THE SPOT WHERE THE NOISE CAME FROM, FORGET IT - if ( fReachable && !fClimb && !gfTurnBasedAI && (pSoldier->bTeam == MILITIA_TEAM || pSoldier->bTeam == CIV_TEAM )&& PythSpacesAway( pSoldier->sGridNo, sNoiseGridNo ) < 5 ) - { + + if ( !( pSoldier->bTeam == CIV_TEAM && pSoldier->ubProfile != NO_PROFILE && pSoldier->ubProfile != ELDIN ) ) + { + // IF WE ARE MILITIA/CIV IN REALTIME, CLOSE TO NOISE, AND CAN SEE THE SPOT WHERE THE NOISE CAME FROM, FORGET IT + if ( fReachable && !fClimb && !gfTurnBasedAI && (pSoldier->bTeam == MILITIA_TEAM || pSoldier->bTeam == CIV_TEAM )&& PythSpacesAway( pSoldier->sGridNo, sNoiseGridNo ) < 5 ) + { if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sNoiseGridNo, pSoldier->bLevel, 0, 6, TRUE ) ) { // set reachable to false so we don't investigate @@ -1531,66 +1535,66 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) pSoldier->sNoiseGridno = NOWHERE; pSoldier->ubNoiseVolume = 0; } - } + } - //////////////////////////////////////////////////////////////////////////// - // SEEK NOISE - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // SEEK NOISE + //////////////////////////////////////////////////////////////////////////// - if ( fReachable ) - { - // remember that noise value is negative, and closer to 0 => more important! - iChance = 95 + (iNoiseValue / 3); - iSneaky = 30; + if ( fReachable ) + { + // remember that noise value is negative, and closer to 0 => more important! + iChance = 95 + (iNoiseValue / 3); + iSneaky = 30; - // increase + // increase - // set base chance according to orders - switch (pSoldier->bOrders) + // set base chance according to orders + switch (pSoldier->bOrders) { - case STATIONARY: iChance += -20; break; - case ONGUARD: iChance += -15; break; - case ONCALL: break; - case CLOSEPATROL: iChance += -10; break; - case RNDPTPATROL: - case POINTPATROL: break; - case FARPATROL: iChance += 10; break; - case SEEKENEMY: iChance += 25; break; - case SNIPER: iChance += -10; break; + case STATIONARY: iChance += -20; break; + case ONGUARD: iChance += -15; break; + case ONCALL: break; + case CLOSEPATROL: iChance += -10; break; + case RNDPTPATROL: + case POINTPATROL: break; + case FARPATROL: iChance += 10; break; + case SEEKENEMY: iChance += 25; break; + case SNIPER: iChance += -10; break; } - // modify chance of patrol (and whether it's a sneaky one) by attitude - switch (pSoldier->bAttitude) + // modify chance of patrol (and whether it's a sneaky one) by attitude + switch (pSoldier->bAttitude) { - case DEFENSIVE: iChance += -10; iSneaky += 15; break; - case BRAVESOLO: iChance += 10; break; - case BRAVEAID: iChance += 5; break; - case CUNNINGSOLO: iChance += 5; iSneaky += 30; break; - case CUNNINGAID: iSneaky += 30; break; - case AGGRESSIVE: iChance += 20; iSneaky += -10; break; - case ATTACKSLAYONLY: iChance += 20; iSneaky += -10; break; + case DEFENSIVE: iChance += -10; iSneaky += 15; break; + case BRAVESOLO: iChance += 10; break; + case BRAVEAID: iChance += 5; break; + case CUNNINGSOLO: iChance += 5; iSneaky += 30; break; + case CUNNINGAID: iSneaky += 30; break; + case AGGRESSIVE: iChance += 20; iSneaky += -10; break; + case ATTACKSLAYONLY: iChance += 20; iSneaky += -10; break; } - // reduce chance if breath is down, less likely to wander around when tired - iChance -= (100 - pSoldier->bBreath); + // reduce chance if breath is down, less likely to wander around when tired + iChance -= (100 - pSoldier->bBreath); - //Madd: make militia less likely to go running headlong into trouble - if ( pSoldier->bTeam == MILITIA_TEAM ) - iChance -= 30; + //Madd: make militia less likely to go running headlong into trouble + if ( pSoldier->bTeam == MILITIA_TEAM ) + iChance -= 30; - if ((INT16) PreRandom(100) < iChance ) + if ((INT16) PreRandom(100) < iChance ) { - pSoldier->usActionData = GoAsFarAsPossibleTowards(pSoldier,sNoiseGridNo,AI_ACTION_SEEK_NOISE); + pSoldier->usActionData = GoAsFarAsPossibleTowards(pSoldier,sNoiseGridNo,AI_ACTION_SEEK_NOISE); - if (pSoldier->usActionData != NOWHERE) + if (pSoldier->usActionData != NOWHERE) { - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - INVESTIGATING NOISE at grid %d, moving to %d", - pSoldier->name,sNoiseGridNo,pSoldier->usActionData); - AIPopMessage(tempstr); - #endif + pSoldier->name,sNoiseGridNo,pSoldier->usActionData); + AIPopMessage(tempstr); +#endif if ( fClimb )//&& pSoldier->usActionData == sNoiseGridNo) { @@ -1598,7 +1602,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) BOOLEAN fUp = TRUE; if (pSoldier->bLevel > 0 ) fUp = FALSE; - + if (!fUp) DebugMsg ( TOPIC_JA2AI , DBG_LEVEL_3 , String("Soldier %d, is climbing down",pSoldier->ubID) ); @@ -1621,7 +1625,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) if ( ( pSoldier->bAttitude == CUNNINGAID || pSoldier->bAttitude == CUNNINGSOLO || pSoldier->bAttitude == BRAVESOLO ) ) { - INT8 action = AI_ACTION_SEEK_NOISE; + INT8 action = AI_ACTION_SEEK_NOISE; INT16 dist = PythSpacesAway ( pSoldier->sGridNo, sNoiseGridNo ); if ( dist > MIN_FLANK_DIST_YELLOW && dist < MAX_FLANK_DIST_YELLOW ) { @@ -1629,17 +1633,17 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) switch (rdm) { - case 1: - case 2: - case 3: - if ( pSoldier->bLastAction != AI_ACTION_FLANK_LEFT && pSoldier->bLastAction != AI_ACTION_FLANK_RIGHT ) - action = AI_ACTION_FLANK_LEFT ; - break; - default: - if ( pSoldier->bLastAction != AI_ACTION_FLANK_LEFT && pSoldier->bLastAction != AI_ACTION_FLANK_RIGHT ) - action = AI_ACTION_FLANK_RIGHT ; - break; - } + case 1: + case 2: + case 3: + if ( pSoldier->bLastAction != AI_ACTION_FLANK_LEFT && pSoldier->bLastAction != AI_ACTION_FLANK_RIGHT ) + action = AI_ACTION_FLANK_LEFT ; + break; + default: + if ( pSoldier->bLastAction != AI_ACTION_FLANK_LEFT && pSoldier->bLastAction != AI_ACTION_FLANK_RIGHT ) + action = AI_ACTION_FLANK_RIGHT ; + break; + } } else return AI_ACTION_SEEK_NOISE ; @@ -1648,7 +1652,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) if ( pSoldier->usActionData == NOWHERE || pSoldier->numFlanks >= MAX_FLANKS_YELLOW ) { - pSoldier->usActionData = GoAsFarAsPossibleTowards(pSoldier,sNoiseGridNo,AI_ACTION_SEEK_NOISE); + pSoldier->usActionData = GoAsFarAsPossibleTowards(pSoldier,sNoiseGridNo,AI_ACTION_SEEK_NOISE); //pSoldier->numFlanks = 0; return(AI_ACTION_SEEK_NOISE); } @@ -1658,10 +1662,10 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) pSoldier->lastFlankLeft = TRUE; else pSoldier->lastFlankLeft = FALSE; - + if ( pSoldier->lastFlankSpot != sNoiseGridNo) pSoldier->numFlanks = 0; - + pSoldier->origDir = GetDirectionFromGridNo ( sNoiseGridNo, pSoldier); pSoldier->lastFlankSpot = sNoiseGridNo; pSoldier->numFlanks++; @@ -1678,59 +1682,59 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) } - //////////////////////////////////////////////////////////////////////////// - // SEEK FRIEND WHO LAST RADIOED IN TO REPORT NOISE - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // SEEK FRIEND WHO LAST RADIOED IN TO REPORT NOISE + //////////////////////////////////////////////////////////////////////////// - sClosestFriend = ClosestReachableFriendInTrouble(pSoldier, &fClimb); + sClosestFriend = ClosestReachableFriendInTrouble(pSoldier, &fClimb); - // if there is a friend alive & reachable who last radioed in - if (sClosestFriend != NOWHERE) + // if there is a friend alive & reachable who last radioed in + if (sClosestFriend != NOWHERE) { - // there a chance enemy soldier choose to go "help" his friend - iChance = 50 - SpacesAway(pSoldier->sGridNo,sClosestFriend); - iSneaky = 10; + // there a chance enemy soldier choose to go "help" his friend + iChance = 50 - SpacesAway(pSoldier->sGridNo,sClosestFriend); + iSneaky = 10; - // set base chance according to orders - switch (pSoldier->bOrders) + // set base chance according to orders + switch (pSoldier->bOrders) { - case STATIONARY: iChance += -20; break; - case ONGUARD: iChance += -15; break; - case ONCALL: iChance += 20; break; - case CLOSEPATROL: iChance += -10; break; - case RNDPTPATROL: - case POINTPATROL: iChance += -10; break; - case FARPATROL: break; - case SEEKENEMY: iChance += 10; break; - case SNIPER: iChance += -10; break; + case STATIONARY: iChance += -20; break; + case ONGUARD: iChance += -15; break; + case ONCALL: iChance += 20; break; + case CLOSEPATROL: iChance += -10; break; + case RNDPTPATROL: + case POINTPATROL: iChance += -10; break; + case FARPATROL: break; + case SEEKENEMY: iChance += 10; break; + case SNIPER: iChance += -10; break; } - // modify chance of patrol (and whether it's a sneaky one) by attitude - switch (pSoldier->bAttitude) + // modify chance of patrol (and whether it's a sneaky one) by attitude + switch (pSoldier->bAttitude) { - case DEFENSIVE: iChance += -10; iSneaky += 15; break; - case BRAVESOLO: break; - case BRAVEAID: iChance += 20; iSneaky += -10; break; - case CUNNINGSOLO: iSneaky += 30; break; - case CUNNINGAID: iChance += 20; iSneaky += 20; break; - case AGGRESSIVE: iChance += -20; iSneaky += -20; break; - case ATTACKSLAYONLY: iChance += -20; iSneaky += -20; break; + case DEFENSIVE: iChance += -10; iSneaky += 15; break; + case BRAVESOLO: break; + case BRAVEAID: iChance += 20; iSneaky += -10; break; + case CUNNINGSOLO: iSneaky += 30; break; + case CUNNINGAID: iChance += 20; iSneaky += 20; break; + case AGGRESSIVE: iChance += -20; iSneaky += -20; break; + case ATTACKSLAYONLY: iChance += -20; iSneaky += -20; break; } - // reduce chance if breath is down, less likely to wander around when tired - iChance -= (100 - pSoldier->bBreath); + // reduce chance if breath is down, less likely to wander around when tired + iChance -= (100 - pSoldier->bBreath); - if ((INT16)PreRandom(100) < iChance) + if ((INT16)PreRandom(100) < iChance) { - pSoldier->usActionData = GoAsFarAsPossibleTowards(pSoldier,sClosestFriend,AI_ACTION_SEEK_FRIEND); + pSoldier->usActionData = GoAsFarAsPossibleTowards(pSoldier,sClosestFriend,AI_ACTION_SEEK_FRIEND); - if (pSoldier->usActionData != NOWHERE) + if (pSoldier->usActionData != NOWHERE) { - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - SEEKING FRIEND at %d, MOVING to %d", - pSoldier->name,sClosestFriend,pSoldier->usActionData); - AIPopMessage(tempstr); - #endif + pSoldier->name,sClosestFriend,pSoldier->usActionData); + AIPopMessage(tempstr); +#endif if ( fClimb )//&& pSoldier->usActionData == sClosestFriend) { @@ -1760,72 +1764,72 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) } //if (fClimb && pSoldier->usActionData == sClosestFriend) - //{ + //{ //// need to climb AND have enough APs to get there this turn //return( AI_ACTION_CLIMB_ROOF ); - //} + //} - return(AI_ACTION_SEEK_FRIEND); + return(AI_ACTION_SEEK_FRIEND); } } } - //////////////////////////////////////////////////////////////////////////// - // TAKE BEST NEARBY COVER FROM THE NOISE GENERATING GRIDNO - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // TAKE BEST NEARBY COVER FROM THE NOISE GENERATING GRIDNO + //////////////////////////////////////////////////////////////////////////// - if (!SkipCoverCheck ) // && gfTurnBasedAI) // only do in turnbased + if (!SkipCoverCheck ) // && gfTurnBasedAI) // only do in turnbased { - // remember that noise value is negative, and closer to 0 => more important! - iChance = 25; - iSneaky = 30; + // remember that noise value is negative, and closer to 0 => more important! + iChance = 25; + iSneaky = 30; - // set base chance according to orders - switch (pSoldier->bOrders) + // set base chance according to orders + switch (pSoldier->bOrders) { - case STATIONARY: iChance += 20; break; - case ONGUARD: iChance += 15; break; - case ONCALL: break; - case CLOSEPATROL: iChance += 10; break; - case RNDPTPATROL: - case POINTPATROL: break; - case FARPATROL: iChance += -5; break; - case SEEKENEMY: iChance += -20; break; - case SNIPER: iChance += 20; break; + case STATIONARY: iChance += 20; break; + case ONGUARD: iChance += 15; break; + case ONCALL: break; + case CLOSEPATROL: iChance += 10; break; + case RNDPTPATROL: + case POINTPATROL: break; + case FARPATROL: iChance += -5; break; + case SEEKENEMY: iChance += -20; break; + case SNIPER: iChance += 20; break; } - // modify chance (and whether it's sneaky) by attitude - switch (pSoldier->bAttitude) + // modify chance (and whether it's sneaky) by attitude + switch (pSoldier->bAttitude) { - case DEFENSIVE: iChance += 10; iSneaky += 15; break; - case BRAVESOLO: iChance += -15; iSneaky += -20; break; - case BRAVEAID: iChance += -20; iSneaky += -20; break; - case CUNNINGSOLO: iChance += 20; iSneaky += 30; break; - case CUNNINGAID: iChance += 15; iSneaky += 30; break; - case AGGRESSIVE: iChance += -10; iSneaky += -10; break; - case ATTACKSLAYONLY: iChance += -10; iSneaky += -10; break; + case DEFENSIVE: iChance += 10; iSneaky += 15; break; + case BRAVESOLO: iChance += -15; iSneaky += -20; break; + case BRAVEAID: iChance += -20; iSneaky += -20; break; + case CUNNINGSOLO: iChance += 20; iSneaky += 30; break; + case CUNNINGAID: iChance += 15; iSneaky += 30; break; + case AGGRESSIVE: iChance += -10; iSneaky += -10; break; + case ATTACKSLAYONLY: iChance += -10; iSneaky += -10; break; } - //Madd: make militia more likely to take cover - if ( pSoldier->bTeam == MILITIA_TEAM ) - iChance += 20; + //Madd: make militia more likely to take cover + if ( pSoldier->bTeam == MILITIA_TEAM ) + iChance += 20; - // reduce chance if breath is down, less likely to wander around when tired - iChance -= (100 - pSoldier->bBreath); + // reduce chance if breath is down, less likely to wander around when tired + iChance -= (100 - pSoldier->bBreath); - if ((INT16)PreRandom(100) < iChance) + if ((INT16)PreRandom(100) < iChance) { pSoldier->bAIMorale = CalcMorale( pSoldier ); pSoldier->usActionData = FindBestNearbyCover(pSoldier,pSoldier->bAIMorale,&iDummy); if (pSoldier->usActionData != NOWHERE) { - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - TAKING COVER at grid %d",pSoldier->name,pSoldier->usActionData); AIPopMessage(tempstr); - #endif +#endif return(AI_ACTION_TAKE_COVER); } @@ -1833,109 +1837,109 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) } } - //////////////////////////////////////////////////////////////////////////// - // SWITCH TO GREEN: determine if soldier acts as if nothing at all was wrong - //////////////////////////////////////////////////////////////////////////// - if ((INT16)PreRandom(100) < 50 ) - { + //////////////////////////////////////////////////////////////////////////// + // SWITCH TO GREEN: determine if soldier acts as if nothing at all was wrong + //////////////////////////////////////////////////////////////////////////// + if ((INT16)PreRandom(100) < 50 ) + { #ifdef RECORDNET - fprintf(NetDebugFile,"\tDecideActionYellow: guynum %d ignores noise, switching to GREEN AI...\n",pSoldier->ubID); + fprintf(NetDebugFile,"\tDecideActionYellow: guynum %d ignores noise, switching to GREEN AI...\n",pSoldier->ubID); #endif #ifdef DEBUGDECISIONS - AINameMessage(pSoldier,"ignores noise completely and BYPASSES to GREEN!",1000); + AINameMessage(pSoldier,"ignores noise completely and BYPASSES to GREEN!",1000); #endif - // Skip YELLOW until new situation, 15% extra chance to do GREEN actions - pSoldier->bBypassToGreen = 15; - return(DecideActionGreen(pSoldier)); - } + // Skip YELLOW until new situation, 15% extra chance to do GREEN actions + pSoldier->bBypassToGreen = 15; + return(DecideActionGreen(pSoldier)); + } - //////////////////////////////////////////////////////////////////////////// - // CROUCH IF NOT CROUCHING ALREADY - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // CROUCH IF NOT CROUCHING ALREADY + //////////////////////////////////////////////////////////////////////////// - // if not in water and not already crouched, try to crouch down first - if (!fCivilian && !PTR_CROUCHED && IsValidStance( pSoldier, ANIM_CROUCH ) ) - { + // if not in water and not already crouched, try to crouch down first + if (!fCivilian && !PTR_CROUCHED && IsValidStance( pSoldier, ANIM_CROUCH ) ) + { #ifdef DEBUGDECISIONS sprintf(tempstr,"%s CROUCHES (STATUS YELLOW)",pSoldier->name); - AIPopMessage(tempstr); + AIPopMessage(tempstr); #endif if (!gfTurnBasedAI || GetAPsToChangeStance( pSoldier, ANIM_CROUCH ) <= pSoldier->bActionPoints) { - pSoldier->usActionData = ANIM_CROUCH; - return(AI_ACTION_CHANGE_STANCE); + pSoldier->usActionData = ANIM_CROUCH; + return(AI_ACTION_CHANGE_STANCE); } - } + } - //////////////////////////////////////////////////////////////////////////// - // DO NOTHING: Not enough points left to move, so save them for next turn - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // DO NOTHING: Not enough points left to move, so save them for next turn + //////////////////////////////////////////////////////////////////////////// #ifdef DEBUGDECISIONS - AINameMessage(pSoldier,"- DOES NOTHING (YELLOW)",1000); + AINameMessage(pSoldier,"- DOES NOTHING (YELLOW)",1000); #endif - // by default, if everything else fails, just stands in place without turning - pSoldier->usActionData = NOWHERE; - return(AI_ACTION_NONE); + // by default, if everything else fails, just stands in place without turning + pSoldier->usActionData = NOWHERE; + return(AI_ACTION_NONE); } INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) { - INT8 bActionReturned; - INT32 iDummy; - INT16 iChance,sClosestOpponent,sClosestFriend; - INT16 sClosestDisturbance, sDistVisible, sCheckGridNo; - UINT8 ubCanMove,ubOpponentDir; - INT8 bInWater, bInDeepWater, bInGas; - INT8 bSeekPts = 0, bHelpPts = 0, bHidePts = 0, bWatchPts = 0; - INT8 bHighestWatchLoc; - ATTACKTYPE BestThrow, BestShot; + INT8 bActionReturned; + INT32 iDummy; + INT16 iChance,sClosestOpponent,sClosestFriend; + INT16 sClosestDisturbance, sDistVisible, sCheckGridNo; + UINT8 ubCanMove,ubOpponentDir; + INT8 bInWater, bInDeepWater, bInGas; + INT8 bSeekPts = 0, bHelpPts = 0, bHidePts = 0, bWatchPts = 0; + INT8 bHighestWatchLoc; + ATTACKTYPE BestThrow, BestShot; #ifdef AI_TIMING_TEST - UINT32 uiStartTime, uiEndTime; - #endif - #ifdef DEBUGDECISIONS - STR16 tempstr; - #endif - BOOLEAN fClimb; - BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP || - (pSoldier->bNeutral && gTacticalStatus.fCivGroupHostile[pSoldier->ubCivilianGroup] == CIV_GROUP_NEUTRAL) || + UINT32 uiStartTime, uiEndTime; +#endif +#ifdef DEBUGDECISIONS + STR16 tempstr; +#endif + BOOLEAN fClimb; + BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP || + (pSoldier->bNeutral && gTacticalStatus.fCivGroupHostile[pSoldier->ubCivilianGroup] == CIV_GROUP_NEUTRAL) || (pSoldier->ubBodyType >= FATCIV && pSoldier->ubBodyType <= CRIPPLECIV) ) ); - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("DecideActionRed: soldier orders = %d",pSoldier->bOrders)); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("DecideActionRed: soldier orders = %d",pSoldier->bOrders)); - // if we have absolutely no action points, we can't do a thing under RED! - if (!pSoldier->bActionPoints) - { - pSoldier->usActionData = NOWHERE; - return(AI_ACTION_NONE); - } + // if we have absolutely no action points, we can't do a thing under RED! + if (!pSoldier->bActionPoints) + { + pSoldier->usActionData = NOWHERE; + return(AI_ACTION_NONE); + } - // can this guy move to any of the neighbouring squares ? (sets TRUE/FALSE) - ubCanMove = (pSoldier->bActionPoints >= MinPtsToMove(pSoldier)); + // can this guy move to any of the neighbouring squares ? (sets TRUE/FALSE) + ubCanMove = (pSoldier->bActionPoints >= MinPtsToMove(pSoldier)); - // if we're an alerted enemy, and there are panic bombs or a trigger around - if ( (!PTR_CIVILIAN || pSoldier->ubProfile == WARDEN) && ( ( gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition || (pSoldier->ubID == gTacticalStatus.ubTheChosenOne) || (pSoldier->ubProfile == WARDEN) ) && - (gTacticalStatus.fPanicFlags & (PANIC_BOMBS_HERE | PANIC_TRIGGERS_HERE ) ) ) ) - { + // if we're an alerted enemy, and there are panic bombs or a trigger around + if ( (!PTR_CIVILIAN || pSoldier->ubProfile == WARDEN) && ( ( gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition || (pSoldier->ubID == gTacticalStatus.ubTheChosenOne) || (pSoldier->ubProfile == WARDEN) ) && + (gTacticalStatus.fPanicFlags & (PANIC_BOMBS_HERE | PANIC_TRIGGERS_HERE ) ) ) ) + { if ( pSoldier->ubProfile == WARDEN && gTacticalStatus.ubTheChosenOne == NOBODY ) { PossiblyMakeThisEnemyChosenOne( pSoldier ); } - // do some special panic AI decision making - bActionReturned = PanicAI(pSoldier,ubCanMove); + // do some special panic AI decision making + bActionReturned = PanicAI(pSoldier,ubCanMove); - // if we decided on an action while in there, we're done - if (bActionReturned != -1) - return(bActionReturned); - } + // if we decided on an action while in there, we're done + if (bActionReturned != -1) + return(bActionReturned); + } if ( pSoldier->ubProfile != NO_PROFILE ) { @@ -1953,16 +1957,16 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) } - // determine if we happen to be in water (in which case we're in BIG trouble!) - bInWater = Water( pSoldier->sGridNo ); - bInDeepWater = Water( pSoldier->sGridNo ); + // determine if we happen to be in water (in which case we're in BIG trouble!) + bInWater = Water( pSoldier->sGridNo ); + bInDeepWater = Water( pSoldier->sGridNo ); - // check if standing in tear gas without a gas mask on - bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); + // check if standing in tear gas without a gas mask on + bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); - //////////////////////////////////////////////////////////////////////////// - // WHEN LEFT IN GAS, WEAR GAS MASK IF AVAILABLE AND NOT WORN - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // WHEN LEFT IN GAS, WEAR GAS MASK IF AVAILABLE AND NOT WORN + //////////////////////////////////////////////////////////////////////////// if ( !bInGas && (gWorldSectorX == TIXA_SECTOR_X && gWorldSectorY == TIXA_SECTOR_Y) ) { @@ -1974,24 +1978,24 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) } } - //////////////////////////////////////////////////////////////////////////// - // WHEN IN GAS, GO TO NEAREST REACHABLE SPOT OF UNGASSED LAND - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // WHEN IN GAS, GO TO NEAREST REACHABLE SPOT OF UNGASSED LAND + //////////////////////////////////////////////////////////////////////////// - if (bInGas && ubCanMove) - { - pSoldier->usActionData = FindNearestUngassedLand(pSoldier); + if (bInGas && ubCanMove) + { + pSoldier->usActionData = FindNearestUngassedLand(pSoldier); - if (pSoldier->usActionData != NOWHERE) - { + if (pSoldier->usActionData != NOWHERE) + { #ifdef DEBUGDECISIONS sprintf(tempstr,"%s - SEEKING NEAREST UNGASSED LAND at grid %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); + AIPopMessage(tempstr); #endif - return(AI_ACTION_LEAVE_WATER_GAS); - } - } + return(AI_ACTION_LEAVE_WATER_GAS); + } + } if ( fCivilian && !( pSoldier->ubBodyType == COW || pSoldier->ubBodyType == CRIPPLECIV ) ) { @@ -1999,7 +2003,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) { // cower in fear!! if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) - { + { if ( gfTurnBasedAI || gTacticalStatus.fEnemyInSector ) // battle! { // in battle! @@ -2053,7 +2057,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) pSoldier->bNextAction = AI_ACTION_WAIT; pSoldier->usNextActionData = (UINT16) REALTIME_CIV_AI_DELAY; pSoldier->usActionData = ANIM_CROUCH; - return( AI_ACTION_COWER ); + return( AI_ACTION_COWER ); } } } @@ -2066,7 +2070,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) { // cower in fear!! if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) - { + { if ( gfTurnBasedAI || gTacticalStatus.fEnemyInSector ) // battle! { // in battle! @@ -2120,26 +2124,26 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) pSoldier->bNextAction = AI_ACTION_WAIT; pSoldier->usNextActionData = (UINT16) REALTIME_CIV_AI_DELAY; pSoldier->usActionData = ANIM_CROUCH; - return( AI_ACTION_COWER ); + return( AI_ACTION_COWER ); } } } } - //////////////////////////////////////////////////////////////////////// - // IF POSSIBLE, FIRE LONG RANGE WEAPONS AT TARGETS REPORTED BY RADIO - //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + // IF POSSIBLE, FIRE LONG RANGE WEAPONS AT TARGETS REPORTED BY RADIO + //////////////////////////////////////////////////////////////////////// // can't do this in realtime, because the player could be shooting a gun or whatever at the same time! - if (gfTurnBasedAI && !fCivilian && !bInWater && !bInGas && !(pSoldier->uiStatusFlags & SOLDIER_BOXER) && (CanNPCAttack(pSoldier) == TRUE)) - { - BestThrow.ubPossible = FALSE; // by default, assume Throwing isn't possible + if (gfTurnBasedAI && !fCivilian && !bInWater && !bInGas && !(pSoldier->uiStatusFlags & SOLDIER_BOXER) && (CanNPCAttack(pSoldier) == TRUE)) + { + BestThrow.ubPossible = FALSE; // by default, assume Throwing isn't possible - CheckIfTossPossible(pSoldier,&BestThrow); + CheckIfTossPossible(pSoldier,&BestThrow); - if (BestThrow.ubPossible) - { + if (BestThrow.ubPossible) + { // if firing mortar make sure we have room if ( Item[pSoldier->inv[ BestThrow.bWeaponIn ].usItem].mortar ) { @@ -2153,97 +2157,97 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) // can't fire! BestThrow.ubPossible = FALSE; - // try behind us, see if there's room to move back + // try behind us, see if there's room to move back sCheckGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc( gOppositeDirection[ ubOpponentDir ] ) ); if ( OKFallDirection( pSoldier, sCheckGridNo, pSoldier->bLevel, gOppositeDirection[ ubOpponentDir ], pSoldier->usAnimState ) ) { - pSoldier->usActionData = sCheckGridNo; + pSoldier->usActionData = sCheckGridNo; - return( AI_ACTION_GET_CLOSER ); + return( AI_ACTION_GET_CLOSER ); } } } - // then do it! The functions have already made sure that we have a - // pair of worthy opponents, etc., so we're not just wasting our time + // then do it! The functions have already made sure that we have a + // pair of worthy opponents, etc., so we're not just wasting our time - // if necessary, swap the usItem from holster into the hand position - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: if necessary, swap the usItem from holster into the hand position"); - if (BestThrow.bWeaponIn != HANDPOS) - RearrangePocket(pSoldier,HANDPOS,BestThrow.bWeaponIn,FOREVER); + // if necessary, swap the usItem from holster into the hand position + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: if necessary, swap the usItem from holster into the hand position"); + if (BestThrow.bWeaponIn != HANDPOS) + RearrangePocket(pSoldier,HANDPOS,BestThrow.bWeaponIn,FOREVER); - pSoldier->usActionData = BestThrow.sTarget; - pSoldier->bAimTime = BestThrow.ubAimTime; + pSoldier->usActionData = BestThrow.sTarget; + pSoldier->bAimTime = BestThrow.ubAimTime; - return(AI_ACTION_TOSS_PROJECTILE); - } - else // toss/throw/launch not possible - { + return(AI_ACTION_TOSS_PROJECTILE); + } + else // toss/throw/launch not possible + { // WDS - Fix problem when there is no "best thrown" weapon (i.e., BestThrow.bWeaponIn == NO_SLOT) - // if this dude has a longe-range weapon on him (longer than normal - // sight range), and there's at least one other team-mate around, and - // spotters haven't already been called for, then DO SO! - + // if this dude has a longe-range weapon on him (longer than normal + // sight range), and there's at least one other team-mate around, and + // spotters haven't already been called for, then DO SO! + if ( (BestThrow.bWeaponIn != NO_SLOT) && (CalcMaxTossRange( pSoldier, pSoldier->inv[BestThrow.bWeaponIn].usItem, TRUE ) > MaxDistanceVisible() ) && - (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) && - (gTacticalStatus.ubSpottersCalledForBy == NOBODY)) - { - // then call for spotters! Uses up the rest of his turn (whatever - // that may be), but from now on, BLACK AI NPC may radio sightings! - gTacticalStatus.ubSpottersCalledForBy = pSoldier->ubID; - pSoldier->bActionPoints = 0; + (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) && + (gTacticalStatus.ubSpottersCalledForBy == NOBODY)) + { + // then call for spotters! Uses up the rest of his turn (whatever + // that may be), but from now on, BLACK AI NPC may radio sightings! + gTacticalStatus.ubSpottersCalledForBy = pSoldier->ubID; + pSoldier->bActionPoints = 0; #ifdef DEBUGDECISIONS - AINameMessage(pSoldier,"calls for spotters!",1000); + AINameMessage(pSoldier,"calls for spotters!",1000); #endif - pSoldier->usActionData = NOWHERE; - return(AI_ACTION_NONE); - } - } + pSoldier->usActionData = NOWHERE; + return(AI_ACTION_NONE); + } + } - // SNIPER! - CheckIfShotPossible(pSoldier,&BestShot,FALSE); - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: is sniper shot possible? = %d, CTH = %d",BestShot.ubPossible,BestShot.ubChanceToReallyHit)); + // SNIPER! + CheckIfShotPossible(pSoldier,&BestShot,FALSE); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: is sniper shot possible? = %d, CTH = %d",BestShot.ubPossible,BestShot.ubChanceToReallyHit)); - if (BestShot.ubPossible && BestShot.ubChanceToReallyHit > 50 ) - { - // then do it! The functions have already made sure that we have a - // pair of worthy opponents, etc., so we're not just wasting our time + if (BestShot.ubPossible && BestShot.ubChanceToReallyHit > 50 ) + { + // then do it! The functions have already made sure that we have a + // pair of worthy opponents, etc., so we're not just wasting our time - // if necessary, swap the usItem from holster into the hand position - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: sniper shot possible!"); - if (BestShot.bWeaponIn != HANDPOS) - RearrangePocket(pSoldier,HANDPOS,BestShot.bWeaponIn,FOREVER); + // if necessary, swap the usItem from holster into the hand position + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: sniper shot possible!"); + if (BestShot.bWeaponIn != HANDPOS) + RearrangePocket(pSoldier,HANDPOS,BestShot.bWeaponIn,FOREVER); - pSoldier->usActionData = BestShot.sTarget; - pSoldier->bAimTime = BestShot.ubAimTime; - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Sniper!" ); - return(AI_ACTION_FIRE_GUN ); - } - else // snipe not possible - { - // if this dude has a longe-range weapon on him (longer than normal - // sight range), and there's at least one other team-mate around, and - // spotters haven't already been called for, then DO SO! - - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: sniper shot not possible"); - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: weapon in slot #%d",BestShot.bWeaponIn)); + pSoldier->usActionData = BestShot.sTarget; + pSoldier->bAimTime = BestShot.ubAimTime; + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Sniper!" ); + return(AI_ACTION_FIRE_GUN ); + } + else // snipe not possible + { + // if this dude has a longe-range weapon on him (longer than normal + // sight range), and there's at least one other team-mate around, and + // spotters haven't already been called for, then DO SO! + + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: sniper shot not possible"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: weapon in slot #%d",BestShot.bWeaponIn)); // WDS - Fix problem when there is no "best shot" weapon (i.e., BestShot.bWeaponIn == NO_SLOT) if (BestShot.bWeaponIn != NO_SLOT) { OBJECTTYPE * gun = &pSoldier->inv[BestShot.bWeaponIn]; DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: men in sector %d, ubspotters called by %d, nobody %d",gTacticalStatus.Team[pSoldier->bTeam].bMenInSector,gTacticalStatus.ubSpottersCalledForBy,NOBODY )); if ( ( ( IsScoped(gun) && GunRange(gun) > MaxDistanceVisible() ) || pSoldier->bOrders == SNIPER ) && - (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) && - (gTacticalStatus.ubSpottersCalledForBy == NOBODY)) + (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) && + (gTacticalStatus.ubSpottersCalledForBy == NOBODY)) { - // then call for spotters! Uses up the rest of his turn (whatever - // that may be), but from now on, BLACK AI NPC may radio sightings! + // then call for spotters! Uses up the rest of his turn (whatever + // that may be), but from now on, BLACK AI NPC may radio sightings! gTacticalStatus.ubSpottersCalledForBy = pSoldier->ubID; pSoldier->bActionPoints = 0; @@ -2255,21 +2259,21 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) } } - //SUPPRESSION FIRE + //SUPPRESSION FIRE - CheckIfShotPossible(pSoldier,&BestShot,TRUE); + CheckIfShotPossible(pSoldier,&BestShot,TRUE); - //must have a small chance to hit and the opponent must be on the ground (can't suppress guys on the roof) - if ( BestShot.ubPossible && BestShot.ubChanceToReallyHit < 50 && Menptr[BestShot.ubOpponent].bLevel == 0 && pSoldier->bOrders != SNIPER ) - { - // then do it! + //must have a small chance to hit and the opponent must be on the ground (can't suppress guys on the roof) + if ( BestShot.ubPossible && BestShot.ubChanceToReallyHit < 50 && Menptr[BestShot.ubOpponent].bLevel == 0 && pSoldier->bOrders != SNIPER ) + { + // then do it! - // if necessary, swap the usItem from holster into the hand position - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: suppression fire possible!"); + // if necessary, swap the usItem from holster into the hand position + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: suppression fire possible!"); if (BestShot.bWeaponIn != HANDPOS) RearrangePocket(pSoldier,HANDPOS,BestShot.bWeaponIn,FOREVER); - + pSoldier->usActionData = BestShot.sTarget; //pSoldier->bAimTime = BestShot.ubAimTime; UINT8 ubBurstAPs = 0; @@ -2280,16 +2284,19 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) pSoldier->bDoAutofire++; ubBurstAPs = CalcAPsToAutofire( CalcActionPoints( pSoldier ), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire ); } - while( pSoldier->bActionPoints - (BestShot.ubAPCost - BestShot.ubAimTime) > ubBurstAPs && - pSoldier->inv[ pSoldier->ubAttackingHand ].ubGunShotsLeft >= pSoldier->bDoAutofire && - GetAutoPenalty(&pSoldier->inv[ pSoldier->ubAttackingHand ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80 ); - - + while( pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs && + pSoldier->inv[ pSoldier->ubAttackingHand ].ubGunShotsLeft >= pSoldier->bDoAutofire && + GetAutoPenalty(&pSoldier->inv[ pSoldier->ubAttackingHand ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80 ); + + pSoldier->bDoAutofire--; + + // Make sure we decided to fire at least one shot! ubBurstAPs = CalcAPsToAutofire( CalcActionPoints( pSoldier ), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire ); // minimum 10 bullets - if (pSoldier->bDoAutofire >= 10 && pSoldier->bActionPoints - (BestShot.ubAPCost - BestShot.ubAimTime) >= ubBurstAPs ) + // Hmmm, automatic suppression? Howcome we don't get this? + if (pSoldier->bDoAutofire >= 10 && pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs ) { pSoldier->bAimTime = 0; pSoldier->bDoBurst = 1; @@ -2306,72 +2313,72 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) pSoldier->bDoAutofire = 0; // not enough aps - do somthing else } + } + // suppression not possible, do something else } - // suppression not possible, do something else - } -/* -// CALL IN AIR STRIKE & RADIO RED ALERT -if ( !fCivilian && pSoldier->bTeam != MILITIA_TEAM && gGameOptions.fAirStrikes && airstrikeavailable && (pSoldier->bActionPoints >= AP_RADIO) && !WillAirRaidBeStopped(pSoldier->sSectorX,pSoldier->sSectorY)) - { + /* + // CALL IN AIR STRIKE & RADIO RED ALERT + if ( !fCivilian && pSoldier->bTeam != MILITIA_TEAM && gGameOptions.fAirStrikes && airstrikeavailable && (pSoldier->bActionPoints >= AP_RADIO) && !WillAirRaidBeStopped(pSoldier->sSectorX,pSoldier->sSectorY)) + { DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: checking to call in an air strike"); iChance = Random(50); - // if I ain't swimming (deep water) - if ( !bInDeepWater ) - { - // modify base chance according to orders - switch (pSoldier->bOrders) - { - case STATIONARY: iChance += 20; break; - case ONGUARD: iChance += 15; break; - case ONCALL: iChance += 10; break; - case CLOSEPATROL: break; - case RNDPTPATROL: - case POINTPATROL: iChance += -5; break; - case FARPATROL: iChance += -10; break; - case SEEKENEMY: iChance += -20; break; - } + // if I ain't swimming (deep water) + if ( !bInDeepWater ) + { + // modify base chance according to orders + switch (pSoldier->bOrders) + { + case STATIONARY: iChance += 20; break; + case ONGUARD: iChance += 15; break; + case ONCALL: iChance += 10; break; + case CLOSEPATROL: break; + case RNDPTPATROL: + case POINTPATROL: iChance += -5; break; + case FARPATROL: iChance += -10; break; + case SEEKENEMY: iChance += -20; break; + } - // modify base chance according to attitude - switch (pSoldier->bAttitude) - { - case DEFENSIVE: iChance += 20; break; - case BRAVESOLO: iChance += -10; break; - case BRAVEAID: break; - case CUNNINGSOLO: iChance += -5; break; - case CUNNINGAID: break; - case AGGRESSIVE: iChance += -20; break; - case ATTACKSLAYONLY: iChance = 0; - } + // modify base chance according to attitude + switch (pSoldier->bAttitude) + { + case DEFENSIVE: iChance += 20; break; + case BRAVESOLO: iChance += -10; break; + case BRAVEAID: break; + case CUNNINGSOLO: iChance += -5; break; + case CUNNINGAID: break; + case AGGRESSIVE: iChance += -20; break; + case ATTACKSLAYONLY: iChance = 0; + } - // modify base chance according to morale - switch (pSoldier->bAIMorale) - { - case MORALE_HOPELESS: iChance *= 3; break; - case MORALE_WORRIED: iChance *= 2; break; - case MORALE_NORMAL: break; - case MORALE_CONFIDENT: iChance /= 2; break; - case MORALE_FEARLESS: iChance /= 3; break; - } + // modify base chance according to morale + switch (pSoldier->bAIMorale) + { + case MORALE_HOPELESS: iChance *= 3; break; + case MORALE_WORRIED: iChance *= 2; break; + case MORALE_NORMAL: break; + case MORALE_CONFIDENT: iChance /= 2; break; + case MORALE_FEARLESS: iChance /= 3; break; + } - if ((INT16) Random(100) < iChance) - { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: decided to call in an air strike!"); - SayQuoteFromAnyBodyInSector( QUOTE_WEARY_SLASH_SUSPUCIOUS ); - EnemyCallInAirStrike ( pSoldier->sSectorX, pSoldier->sSectorY ); - airstrikeavailable = FALSE; + if ((INT16) Random(100) < iChance) + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: decided to call in an air strike!"); + SayQuoteFromAnyBodyInSector( QUOTE_WEARY_SLASH_SUSPUCIOUS ); + EnemyCallInAirStrike ( pSoldier->sSectorX, pSoldier->sSectorY ); + airstrikeavailable = FALSE; - return(AI_ACTION_RED_ALERT); - } - } - } -*/ + return(AI_ACTION_RED_ALERT); + } + } + } + */ - //////////////////////////////////////////////////////////////////////////// - // WHEN IN THE LIGHT, GET OUT OF THERE! - //////////////////////////////////////////////////////////////////////////// - if ( ubCanMove && InLightAtNight( pSoldier->sGridNo, pSoldier->bLevel ) && pSoldier->bOrders != STATIONARY ) + //////////////////////////////////////////////////////////////////////////// + // WHEN IN THE LIGHT, GET OUT OF THERE! + //////////////////////////////////////////////////////////////////////////// + if ( ubCanMove && InLightAtNight( pSoldier->sGridNo, pSoldier->bLevel ) && pSoldier->bOrders != STATIONARY ) { pSoldier->usActionData = FindNearbyDarkerSpot( pSoldier ); if ( pSoldier->usActionData != NOWHERE ) @@ -2381,470 +2388,433 @@ if ( !fCivilian && pSoldier->bTeam != MILITIA_TEAM && gGameOptions.fAirStrikes & } } -DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: crouch and rest if running out of breath"); - //////////////////////////////////////////////////////////////////////// - // CROUCH & REST IF RUNNING OUT OF BREATH - //////////////////////////////////////////////////////////////////////// + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: crouch and rest if running out of breath"); + //////////////////////////////////////////////////////////////////////// + // CROUCH & REST IF RUNNING OUT OF BREATH + //////////////////////////////////////////////////////////////////////// - // if our breath is running a bit low, and we're not in water or under fire - if ((pSoldier->bBreath < 25) && !bInWater && !pSoldier->bUnderFire) - { - // if not already crouched, try to crouch down first - if (!fCivilian && !PTR_CROUCHED && IsValidStance( pSoldier, ANIM_CROUCH ) && gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE) - { + // if our breath is running a bit low, and we're not in water or under fire + if ((pSoldier->bBreath < 25) && !bInWater && !pSoldier->bUnderFire) + { + // if not already crouched, try to crouch down first + if (!fCivilian && !PTR_CROUCHED && IsValidStance( pSoldier, ANIM_CROUCH ) && gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE) + { #ifdef DEBUGDECISIONS sprintf(tempstr,"%s CROUCHES, NEEDING REST (STATUS RED), breath = %d",pSoldier->name,pSoldier->bBreath); - AIPopMessage(tempstr); + AIPopMessage(tempstr); #endif - if (!gfTurnBasedAI || GetAPsToChangeStance( pSoldier, ANIM_CROUCH ) <= pSoldier->bActionPoints) - { - pSoldier->usActionData = ANIM_CROUCH; + if (!gfTurnBasedAI || GetAPsToChangeStance( pSoldier, ANIM_CROUCH ) <= pSoldier->bActionPoints) + { + pSoldier->usActionData = ANIM_CROUCH; - return(AI_ACTION_CHANGE_STANCE); - } - } + return(AI_ACTION_CHANGE_STANCE); + } + } #ifdef DEBUGDECISIONS sprintf(tempstr,"%s RESTS (STATUS RED), breath = %d",pSoldier->name,pSoldier->bBreath); - AIPopMessage(tempstr); + AIPopMessage(tempstr); #endif - pSoldier->usActionData = NOWHERE; - return(AI_ACTION_NONE); - } + pSoldier->usActionData = NOWHERE; + return(AI_ACTION_NONE); + } -DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: calculate morale"); - // calculate our morale - pSoldier->bAIMorale = CalcMorale(pSoldier); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: calculate morale"); + // calculate our morale + pSoldier->bAIMorale = CalcMorale(pSoldier); - // if a guy is feeling REALLY discouraged, he may continue to run like hell - if ((pSoldier->bAIMorale == MORALE_HOPELESS) && ubCanMove) - { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: run away"); - //////////////////////////////////////////////////////////////////////// - // RUN AWAY TO SPOT FARTHEST FROM KNOWN THREATS (ONLY IF MORALE HOPELESS) - //////////////////////////////////////////////////////////////////////// + // if a guy is feeling REALLY discouraged, he may continue to run like hell + if ((pSoldier->bAIMorale == MORALE_HOPELESS) && ubCanMove) + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: run away"); + //////////////////////////////////////////////////////////////////////// + // RUN AWAY TO SPOT FARTHEST FROM KNOWN THREATS (ONLY IF MORALE HOPELESS) + //////////////////////////////////////////////////////////////////////// - // look for best place to RUN AWAY to (farthest from the closest threat) - pSoldier->usActionData = FindSpotMaxDistFromOpponents(pSoldier); + // look for best place to RUN AWAY to (farthest from the closest threat) + pSoldier->usActionData = FindSpotMaxDistFromOpponents(pSoldier); - if (pSoldier->usActionData != NOWHERE) - { + if (pSoldier->usActionData != NOWHERE) + { #ifdef DEBUGDECISIONS sprintf(tempstr,"%s RUNNING AWAY to grid %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); + AIPopMessage(tempstr); #endif - return(AI_ACTION_RUN_AWAY); - } - } + return(AI_ACTION_RUN_AWAY); + } + } -DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); - //////////////////////////////////////////////////////////////////////////// - // RADIO RED ALERT: determine %chance to call others and report contact - //////////////////////////////////////////////////////////////////////////// + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); + //////////////////////////////////////////////////////////////////////////// + // RADIO RED ALERT: determine %chance to call others and report contact + //////////////////////////////////////////////////////////////////////////// - // if we're a computer merc, and we have the action points remaining to RADIO - // (we never want NPCs to choose to radio if they would have to wait a turn) - if ( !fCivilian && (pSoldier->bActionPoints >= AP_RADIO) && (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) ) - { + // if we're a computer merc, and we have the action points remaining to RADIO + // (we never want NPCs to choose to radio if they would have to wait a turn) + if ( !fCivilian && (pSoldier->bActionPoints >= AP_RADIO) && (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) ) + { DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: checking to radio red alert"); - // if there hasn't been an initial RED ALERT yet in this sector - if ( !(gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition) || NeedToRadioAboutPanicTrigger() ) - // since I'm at STATUS RED, I obviously know we're being invaded! - iChance = gbDiff[DIFF_RADIO_RED_ALERT][ SoldierDifficultyLevel( pSoldier ) ]; - else // subsequent radioing (only to update enemy positions, request help) - // base chance depends on how much new info we have to radio to the others - iChance = 10 * WhatIKnowThatPublicDont(pSoldier,FALSE); // use 10 * for RED alert + // if there hasn't been an initial RED ALERT yet in this sector + if ( !(gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition) || NeedToRadioAboutPanicTrigger() ) + // since I'm at STATUS RED, I obviously know we're being invaded! + iChance = gbDiff[DIFF_RADIO_RED_ALERT][ SoldierDifficultyLevel( pSoldier ) ]; + else // subsequent radioing (only to update enemy positions, request help) + // base chance depends on how much new info we have to radio to the others + iChance = 10 * WhatIKnowThatPublicDont(pSoldier,FALSE); // use 10 * for RED alert - // if I actually know something they don't and I ain't swimming (deep water) - if (iChance && !bInDeepWater) - { - // modify base chance according to orders - switch (pSoldier->bOrders) - { - case STATIONARY: iChance += 20; break; - case ONGUARD: iChance += 15; break; - case ONCALL: iChance += 10; break; - case CLOSEPATROL: break; - case RNDPTPATROL: - case POINTPATROL: iChance += -5; break; - case FARPATROL: iChance += -10; break; - case SEEKENEMY: iChance += -20; break; - case SNIPER: iChance += -10; break; // Sniper contacts should be reported automatically - } + // if I actually know something they don't and I ain't swimming (deep water) + if (iChance && !bInDeepWater) + { + // modify base chance according to orders + switch (pSoldier->bOrders) + { + case STATIONARY: iChance += 20; break; + case ONGUARD: iChance += 15; break; + case ONCALL: iChance += 10; break; + case CLOSEPATROL: break; + case RNDPTPATROL: + case POINTPATROL: iChance += -5; break; + case FARPATROL: iChance += -10; break; + case SEEKENEMY: iChance += -20; break; + case SNIPER: iChance += -10; break; // Sniper contacts should be reported automatically + } - // modify base chance according to attitude - switch (pSoldier->bAttitude) - { - case DEFENSIVE: iChance += 20; break; - case BRAVESOLO: iChance += -10; break; - case BRAVEAID: break; - case CUNNINGSOLO: iChance += -5; break; - case CUNNINGAID: break; - case AGGRESSIVE: iChance += -20; break; - case ATTACKSLAYONLY: iChance = 0; - } + // modify base chance according to attitude + switch (pSoldier->bAttitude) + { + case DEFENSIVE: iChance += 20; break; + case BRAVESOLO: iChance += -10; break; + case BRAVEAID: break; + case CUNNINGSOLO: iChance += -5; break; + case CUNNINGAID: break; + case AGGRESSIVE: iChance += -20; break; + case ATTACKSLAYONLY: iChance = 0; + } if ( (gTacticalStatus.fPanicFlags & PANIC_TRIGGERS_HERE) && !gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition) { - // ignore morale (which could be really high + // ignore morale (which could be really high } else { - // modify base chance according to morale - switch (pSoldier->bAIMorale) + // modify base chance according to morale + switch (pSoldier->bAIMorale) { - case MORALE_HOPELESS: iChance *= 3; break; - case MORALE_WORRIED: iChance *= 2; break; - case MORALE_NORMAL: break; - case MORALE_CONFIDENT: iChance /= 2; break; - case MORALE_FEARLESS: iChance /= 3; break; + case MORALE_HOPELESS: iChance *= 3; break; + case MORALE_WORRIED: iChance *= 2; break; + case MORALE_NORMAL: break; + case MORALE_CONFIDENT: iChance /= 2; break; + case MORALE_FEARLESS: iChance /= 3; break; } } #ifdef DEBUGDECISIONS - AINumMessage("Chance to radio RED alert = ",iChance); + AINumMessage("Chance to radio RED alert = ",iChance); #endif - if ((INT16) PreRandom(100) < iChance) - { + if ((INT16) PreRandom(100) < iChance) + { #ifdef DEBUGDECISIONS - AINameMessage(pSoldier,"decides to radio a RED alert!",1000); + AINameMessage(pSoldier,"decides to radio a RED alert!",1000); #endif - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: decided to radio red alert"); - return(AI_ACTION_RED_ALERT); - } - } - } + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: decided to radio red alert"); + return(AI_ACTION_RED_ALERT); + } + } + } if ( !TANK( pSoldier ) ) { DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: main red ai"); - //////////////////////////////////////////////////////////////////////////// - // MAIN RED AI: Decide soldier's preference between SEEKING,HELPING & HIDING - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // MAIN RED AI: Decide soldier's preference between SEEKING,HELPING & HIDING + //////////////////////////////////////////////////////////////////////////// - // get the location of the closest reachable opponent - sClosestDisturbance = ClosestReachableDisturbance(pSoldier,ubUnconsciousOK, &fClimb); + // get the location of the closest reachable opponent + sClosestDisturbance = ClosestReachableDisturbance(pSoldier,ubUnconsciousOK, &fClimb); - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: check to continue flanking"); - // continue flanking - INT16 tempGridNo; - if ( sClosestDisturbance == NOWHERE ) - tempGridNo = pSoldier->lastFlankSpot; - else - tempGridNo = sClosestDisturbance; + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: check to continue flanking"); + // continue flanking + INT16 tempGridNo; + if ( sClosestDisturbance == NOWHERE ) + tempGridNo = pSoldier->lastFlankSpot; + else + tempGridNo = sClosestDisturbance; - if ( pSoldier->numFlanks > 0 && pSoldier->numFlanks < MAX_FLANKS_RED && gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE ) + if ( pSoldier->numFlanks > 0 && pSoldier->numFlanks < MAX_FLANKS_RED && gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE ) + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: continue flanking"); + INT16 currDir = GetDirectionFromGridNo ( tempGridNo, pSoldier ); + INT16 origDir = pSoldier->origDir; + pSoldier->numFlanks += 1; + if ( pSoldier->lastFlankLeft ) { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: continue flanking"); - INT16 currDir = GetDirectionFromGridNo ( tempGridNo, pSoldier ); - INT16 origDir = pSoldier->origDir; - pSoldier->numFlanks += 1; - if ( pSoldier->lastFlankLeft ) - { - if ( origDir > currDir ) - origDir -= 8; + if ( origDir > currDir ) + origDir -= 8; - if ( (currDir - origDir) >= 4 ) - { - pSoldier->numFlanks = MAX_FLANKS_RED; - } - else - { - pSoldier->usActionData = FindFlankingSpot (pSoldier, tempGridNo , AI_ACTION_FLANK_LEFT); - if ( pSoldier->usActionData != NOWHERE ) //&& (currDir - origDir) < 2 ) - return AI_ACTION_FLANK_LEFT ; - else - pSoldier->numFlanks = MAX_FLANKS_RED; - } + if ( (currDir - origDir) >= 4 ) + { + pSoldier->numFlanks = MAX_FLANKS_RED; } else { - if ( origDir < currDir ) - origDir += 8; - - if ( (origDir - currDir) >= 4 ) - { - pSoldier->numFlanks = MAX_FLANKS_RED; - } + pSoldier->usActionData = FindFlankingSpot (pSoldier, tempGridNo , AI_ACTION_FLANK_LEFT); + if ( pSoldier->usActionData != NOWHERE ) //&& (currDir - origDir) < 2 ) + return AI_ACTION_FLANK_LEFT ; else - { - pSoldier->usActionData = FindFlankingSpot (pSoldier, tempGridNo , AI_ACTION_FLANK_RIGHT); - if ( pSoldier->usActionData != NOWHERE )//&& (origDir - currDir) < 2 ) - return AI_ACTION_FLANK_RIGHT ; - else - pSoldier->numFlanks = MAX_FLANKS_RED; - } + pSoldier->numFlanks = MAX_FLANKS_RED; } } - if ( pSoldier->numFlanks == MAX_FLANKS_RED ) + else { - pSoldier->numFlanks += 1; - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: stop flanking"); - if (PythSpacesAway ( pSoldier->sGridNo, tempGridNo ) > MIN_FLANK_DIST_RED * 2 ) - { - pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,tempGridNo,AP_PRONE,AI_ACTION_SEEK_OPPONENT,0); + if ( origDir < currDir ) + origDir += 8; - if ( LocationToLocationLineOfSightTest( pSoldier->usActionData, pSoldier->bLevel, tempGridNo, pSoldier->bLevel, (UINT8) MaxDistanceVisible(), TRUE ) ) - { - // reserve APs for a possible crouch plus a shot - pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, tempGridNo, (INT8) (MinAPsToAttack( pSoldier, tempGridNo, ADDTURNCOST) + AP_CROUCH), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS ); - if ( pSoldier->usActionData != NOWHERE ) - { - pSoldier->fAIFlags |= AI_CAUTIOUS; - pSoldier->bNextAction = AI_ACTION_END_TURN; - return(AI_ACTION_SEEK_OPPONENT); - } - } + if ( (origDir - currDir) >= 4 ) + { + pSoldier->numFlanks = MAX_FLANKS_RED; + } + else + { + pSoldier->usActionData = FindFlankingSpot (pSoldier, tempGridNo , AI_ACTION_FLANK_RIGHT); + if ( pSoldier->usActionData != NOWHERE )//&& (origDir - currDir) < 2 ) + return AI_ACTION_FLANK_RIGHT ; else + pSoldier->numFlanks = MAX_FLANKS_RED; + } + } + } + if ( pSoldier->numFlanks == MAX_FLANKS_RED ) + { + pSoldier->numFlanks += 1; + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: stop flanking"); + if (PythSpacesAway ( pSoldier->sGridNo, tempGridNo ) > MIN_FLANK_DIST_RED * 2 ) + { + pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,tempGridNo,AP_PRONE,AI_ACTION_SEEK_OPPONENT,0); + + if ( LocationToLocationLineOfSightTest( pSoldier->usActionData, pSoldier->bLevel, tempGridNo, pSoldier->bLevel, (UINT8) MaxDistanceVisible(), TRUE ) ) + { + // reserve APs for a possible crouch plus a shot + pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, tempGridNo, (INT8) (MinAPsToAttack( pSoldier, tempGridNo, ADDTURNCOST) + AP_CROUCH), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS ); + if ( pSoldier->usActionData != NOWHERE ) { + pSoldier->fAIFlags |= AI_CAUTIOUS; + pSoldier->bNextAction = AI_ACTION_END_TURN; return(AI_ACTION_SEEK_OPPONENT); } } else { - pSoldier->usActionData = FindBestNearbyCover(pSoldier,pSoldier->bAIMorale,&iDummy); - return AI_ACTION_TAKE_COVER ; + return(AI_ACTION_SEEK_OPPONENT); + } + } + else + { + pSoldier->usActionData = FindBestNearbyCover(pSoldier,pSoldier->bAIMorale,&iDummy); + return AI_ACTION_TAKE_COVER ; + } + } + + + // if we can move at least 1 square's worth + // and have more APs than we want to reserve + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: can we move? = %d, APs = %d",ubCanMove,pSoldier->bActionPoints)); + + if (ubCanMove && pSoldier->bActionPoints > MAX_AP_CARRIED) + { + if (fCivilian) + { + // only interested in hiding out... + bSeekPts = -99; + bHelpPts = -99; + bHidePts = +1; + } + else + { + + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: checking hide/seek/help/watch points... orders = %d, attitude = %d",pSoldier->bOrders,pSoldier->bAttitude)); + // calculate initial points for watch based on highest watch loc + + bWatchPts = GetHighestWatchedLocPoints( pSoldier->ubID ); + if ( bWatchPts <= 0 ) + { + // no watching + bWatchPts = -99; + } + + // modify RED movement tendencies according to morale + switch (pSoldier->bAIMorale) + { + case MORALE_HOPELESS: bSeekPts = -99; bHelpPts = -99; bHidePts = +2; bWatchPts = -99; break; + case MORALE_WORRIED: bSeekPts += -2; bHelpPts += 0; bHidePts += +2; bWatchPts += 1; break; + case MORALE_NORMAL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; + case MORALE_CONFIDENT: bSeekPts += +1; bHelpPts += 0; bHidePts += -1; bWatchPts += 0; break; + case MORALE_FEARLESS: bSeekPts += +1; bHelpPts += 0; bHidePts = -1; bWatchPts += 0; break; + } + + // modify tendencies according to orders + switch (pSoldier->bOrders) + { + case STATIONARY: bSeekPts += -1; bHelpPts += -1; bHidePts += +1; bWatchPts += +1; break; + case ONGUARD: bSeekPts += -1; bHelpPts += 0; bHidePts += +1; bWatchPts += +1; break; + case CLOSEPATROL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; + case RNDPTPATROL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; + case POINTPATROL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; + case FARPATROL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; + case ONCALL: bSeekPts += 0; bHelpPts += +1; bHidePts += -1; bWatchPts += 0; break; + case SEEKENEMY: bSeekPts += +1; bHelpPts += 0; bHidePts += -1; bWatchPts += -1; break; + case SNIPER: bSeekPts += -1; bHelpPts += 0; bHidePts += +1; bWatchPts += +1; break; + } + + // modify tendencies according to attitude + switch (pSoldier->bAttitude) + { + case DEFENSIVE: bSeekPts += -1; bHelpPts += 0; bHidePts += +2; bWatchPts += +1; break; + case BRAVESOLO: bSeekPts += +1; bHelpPts += -1; bHidePts += -1; bWatchPts += -1; break; + case BRAVEAID: bSeekPts += +1; bHelpPts += +1; bHidePts += -1; bWatchPts += -1; break; + case CUNNINGSOLO: bSeekPts += 1; bHelpPts += -1; bHidePts += +1; bWatchPts += 0; break; + case CUNNINGAID: bSeekPts += 1; bHelpPts += +1; bHidePts += +1; bWatchPts += 0; break; + case AGGRESSIVE: bSeekPts += +1; bHelpPts += 0; bHidePts += -1; bWatchPts += 0; break; + case ATTACKSLAYONLY:bSeekPts += +1; bHelpPts += 0; bHidePts += -1; bWatchPts += 0; break; + } + + //Madd: make militia less likely to go running headlong into trouble + if ( pSoldier->bTeam == MILITIA_TEAM ) + { + bSeekPts += -1; bHelpPts += 0; bHidePts += +1; bWatchPts += +0; } } - - // if we can move at least 1 square's worth - // and have more APs than we want to reserve - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: can we move? = %d, APs = %d",ubCanMove,pSoldier->bActionPoints)); - - if (ubCanMove && pSoldier->bActionPoints > MAX_AP_CARRIED) + if (!gfTurnBasedAI) { - if (fCivilian) - { - // only interested in hiding out... - bSeekPts = -99; - bHelpPts = -99; - bHidePts = +1; - } - else + // don't search for cover + bHidePts = -99; + } + + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: hide = %d, seek = %d, watch = %d, help = %d",bHidePts,bSeekPts,bWatchPts,bHelpPts)); + // while one of the three main RED REACTIONS remains viable + while ((bSeekPts > -90) || (bHelpPts > -90) || (bHidePts > -90) ) + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: checking to seek"); + // if SEEKING is possible and at least as desirable as helping or hiding + if ( ((bSeekPts > -90) && (bSeekPts >= bHelpPts) && (bSeekPts >= bHidePts) && (bSeekPts >= bWatchPts )) ) { +#ifdef AI_TIMING_TESTS + uiStartTime = GetJA2Clock(); +#endif - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: checking hide/seek/help/watch points... orders = %d, attitude = %d",pSoldier->bOrders,pSoldier->bAttitude)); - // calculate initial points for watch based on highest watch loc - - bWatchPts = GetHighestWatchedLocPoints( pSoldier->ubID ); - if ( bWatchPts <= 0 ) - { - // no watching - bWatchPts = -99; - } - - // modify RED movement tendencies according to morale - switch (pSoldier->bAIMorale) +#ifdef AI_TIMING_TESTS + uiEndTime = GetJA2Clock(); + guiRedSeekTimeTotal += (uiEndTime - uiStartTime); + guiRedSeekCounter++; +#endif + // if there is an opponent reachable + if (sClosestDisturbance != NOWHERE && gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE ) { - case MORALE_HOPELESS: bSeekPts = -99; bHelpPts = -99; bHidePts = +2; bWatchPts = -99; break; - case MORALE_WORRIED: bSeekPts += -2; bHelpPts += 0; bHidePts += +2; bWatchPts += 1; break; - case MORALE_NORMAL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; - case MORALE_CONFIDENT: bSeekPts += +1; bHelpPts += 0; bHidePts += -1; bWatchPts += 0; break; - case MORALE_FEARLESS: bSeekPts += +1; bHelpPts += 0; bHidePts = -1; bWatchPts += 0; break; - } + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: seek opponent"); + ////////////////////////////////////////////////////////////////////// + // SEEK CLOSEST DISTURBANCE: GO DIRECTLY TOWARDS CLOSEST KNOWN OPPONENT + ////////////////////////////////////////////////////////////////////// - // modify tendencies according to orders - switch (pSoldier->bOrders) - { - case STATIONARY: bSeekPts += -1; bHelpPts += -1; bHidePts += +1; bWatchPts += +1; break; - case ONGUARD: bSeekPts += -1; bHelpPts += 0; bHidePts += +1; bWatchPts += +1; break; - case CLOSEPATROL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; - case RNDPTPATROL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; - case POINTPATROL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; - case FARPATROL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; - case ONCALL: bSeekPts += 0; bHelpPts += +1; bHidePts += -1; bWatchPts += 0; break; - case SEEKENEMY: bSeekPts += +1; bHelpPts += 0; bHidePts += -1; bWatchPts += -1; break; - case SNIPER: bSeekPts += -1; bHelpPts += 0; bHidePts += +1; bWatchPts += +1; break; - } + // try to move towards him + pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestDisturbance,AP_CROUCH,AI_ACTION_SEEK_OPPONENT,0); - // modify tendencies according to attitude - switch (pSoldier->bAttitude) - { - case DEFENSIVE: bSeekPts += -1; bHelpPts += 0; bHidePts += +2; bWatchPts += +1; break; - case BRAVESOLO: bSeekPts += +1; bHelpPts += -1; bHidePts += -1; bWatchPts += -1; break; - case BRAVEAID: bSeekPts += +1; bHelpPts += +1; bHidePts += -1; bWatchPts += -1; break; - case CUNNINGSOLO: bSeekPts += 1; bHelpPts += -1; bHidePts += +1; bWatchPts += 0; break; - case CUNNINGAID: bSeekPts += 1; bHelpPts += +1; bHidePts += +1; bWatchPts += 0; break; - case AGGRESSIVE: bSeekPts += +1; bHelpPts += 0; bHidePts += -1; bWatchPts += 0; break; - case ATTACKSLAYONLY:bSeekPts += +1; bHelpPts += 0; bHidePts += -1; bWatchPts += 0; break; - } - - //Madd: make militia less likely to go running headlong into trouble - if ( pSoldier->bTeam == MILITIA_TEAM ) - { - bSeekPts += -1; bHelpPts += 0; bHidePts += +1; bWatchPts += +0; - } - } - - if (!gfTurnBasedAI) - { - // don't search for cover - bHidePts = -99; - } - - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: hide = %d, seek = %d, watch = %d, help = %d",bHidePts,bSeekPts,bWatchPts,bHelpPts)); - // while one of the three main RED REACTIONS remains viable - while ((bSeekPts > -90) || (bHelpPts > -90) || (bHidePts > -90) ) - { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: checking to seek"); - // if SEEKING is possible and at least as desirable as helping or hiding - if ( ((bSeekPts > -90) && (bSeekPts >= bHelpPts) && (bSeekPts >= bHidePts) && (bSeekPts >= bWatchPts )) ) - { - #ifdef AI_TIMING_TESTS - uiStartTime = GetJA2Clock(); - #endif - - #ifdef AI_TIMING_TESTS - uiEndTime = GetJA2Clock(); - guiRedSeekTimeTotal += (uiEndTime - uiStartTime); - guiRedSeekCounter++; - #endif - // if there is an opponent reachable - if (sClosestDisturbance != NOWHERE && gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE ) + if (pSoldier->usActionData != NOWHERE) { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: seek opponent"); - ////////////////////////////////////////////////////////////////////// - // SEEK CLOSEST DISTURBANCE: GO DIRECTLY TOWARDS CLOSEST KNOWN OPPONENT - ////////////////////////////////////////////////////////////////////// - - // try to move towards him - pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestDisturbance,AP_CROUCH,AI_ACTION_SEEK_OPPONENT,0); - - if (pSoldier->usActionData != NOWHERE) + // Check for a trap + if ( !ArmySeesOpponents() ) { - // Check for a trap - if ( !ArmySeesOpponents() ) + if ( GetNearestRottingCorpseAIWarning( pSoldier->usActionData ) > 0 ) { - if ( GetNearestRottingCorpseAIWarning( pSoldier->usActionData ) > 0 ) - { - // abort! abort! - pSoldier->usActionData = NOWHERE; - } + // abort! abort! + pSoldier->usActionData = NOWHERE; } } + } - // if it's possible - if (pSoldier->usActionData != NOWHERE) - { - #ifdef DEBUGDECISIONS - // do it! + // if it's possible + if (pSoldier->usActionData != NOWHERE) + { +#ifdef DEBUGDECISIONS + // do it! sprintf(tempstr,"%s - SEEKING OPPONENT at grid %d, MOVING to %d", pSoldier->name,sClosestDisturbance,pSoldier->usActionData); - AIPopMessage(tempstr); - #endif + AIPopMessage(tempstr); +#endif - if (fClimb)//&& pSoldier->usActionData == sClosestDisturbance) + if (fClimb)//&& pSoldier->usActionData == sClosestDisturbance) + { + // need to climb AND have enough APs to get there this turn + BOOLEAN fUp = TRUE; + if (pSoldier->bLevel > 0 ) + fUp = FALSE; + + if (!fUp) + DebugMsg ( TOPIC_JA2AI , DBG_LEVEL_3 , String("Soldier %d is climbing down",pSoldier->ubID) ); + + if ( CanClimbFromHere ( pSoldier, fUp ) ) { - // need to climb AND have enough APs to get there this turn - BOOLEAN fUp = TRUE; - if (pSoldier->bLevel > 0 ) - fUp = FALSE; - - if (!fUp) - DebugMsg ( TOPIC_JA2AI , DBG_LEVEL_3 , String("Soldier %d is climbing down",pSoldier->ubID) ); - - if ( CanClimbFromHere ( pSoldier, fUp ) ) + if (IsActionAffordable(pSoldier) && pSoldier->bActionPoints >= ( AP_CLIMBROOF + MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST))) { - if (IsActionAffordable(pSoldier) && pSoldier->bActionPoints >= ( AP_CLIMBROOF + MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST))) - { - return( AI_ACTION_CLIMB_ROOF ); - } - } - else - { - pSoldier->usActionData = FindClosestClimbPoint(pSoldier->sGridNo , sClosestDisturbance , fUp ); - if ( pSoldier->usActionData != NOWHERE ) - { - return( AI_ACTION_MOVE_TO_CLIMB ); - } - } - } - //if ( fClimb && pSoldier->usActionData == sClosestDisturbance) - //{ - // return( AI_ACTION_CLIMB_ROOF ); - //} - - - if ( ( pSoldier->bAttitude == CUNNINGAID || pSoldier->bAttitude == CUNNINGSOLO || pSoldier->bAttitude == BRAVESOLO ) && gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE ) - { - INT8 action = AI_ACTION_SEEK_OPPONENT; - INT16 dist = PythSpacesAway ( pSoldier->sGridNo, sClosestDisturbance ); - if ( dist > MIN_FLANK_DIST_RED && dist < MAX_FLANK_DIST_RED ) - { - INT16 rdm = Random(6); - - switch (rdm) - { - case 1: - case 2: - case 3: - if ( pSoldier->bLastAction != AI_ACTION_FLANK_LEFT && pSoldier->bLastAction != AI_ACTION_FLANK_RIGHT ) - action = AI_ACTION_FLANK_LEFT ; - break; - default: - if ( pSoldier->bLastAction != AI_ACTION_FLANK_LEFT && pSoldier->bLastAction != AI_ACTION_FLANK_RIGHT ) - action = AI_ACTION_FLANK_RIGHT ; - break; - } - } - else - return AI_ACTION_SEEK_OPPONENT ; - - pSoldier->usActionData = FindFlankingSpot (pSoldier, sClosestDisturbance, action ); - - if ( pSoldier->usActionData == NOWHERE || pSoldier->numFlanks >= MAX_FLANKS_RED ) - { - pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestDisturbance,AP_CROUCH, AI_ACTION_SEEK_OPPONENT,0); - //pSoldier->numFlanks = 0; - if ( PythSpacesAway( pSoldier->usActionData, sClosestDisturbance ) < 5 || LocationToLocationLineOfSightTest( pSoldier->usActionData, pSoldier->bLevel, sClosestDisturbance, pSoldier->bLevel, (UINT8) MaxDistanceVisible(), TRUE ) ) - { - // reserve APs for a possible crouch plus a shot - pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, sClosestDisturbance, (INT8) (MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST) + AP_CROUCH), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS ); - if ( pSoldier->usActionData != NOWHERE ) - { - pSoldier->fAIFlags |= AI_CAUTIOUS; - pSoldier->bNextAction = AI_ACTION_END_TURN; - return(AI_ACTION_SEEK_OPPONENT); - } - } - - else - { - return(AI_ACTION_SEEK_OPPONENT); - } - } - else - { - if ( action == AI_ACTION_FLANK_LEFT ) - pSoldier->lastFlankLeft = TRUE; - else - pSoldier->lastFlankLeft = FALSE; - - if ( pSoldier->lastFlankSpot != sClosestDisturbance) - pSoldier->numFlanks=0; - - - pSoldier->origDir = GetDirectionFromGridNo ( sClosestDisturbance, pSoldier); - pSoldier->lastFlankSpot = sClosestDisturbance; - pSoldier->numFlanks++; - return(action); + return( AI_ACTION_CLIMB_ROOF ); } } else { - // let's be a bit cautious about going right up to a location without enough APs to shoot + pSoldier->usActionData = FindClosestClimbPoint(pSoldier->sGridNo , sClosestDisturbance , fUp ); + if ( pSoldier->usActionData != NOWHERE ) + { + return( AI_ACTION_MOVE_TO_CLIMB ); + } + } + } + //if ( fClimb && pSoldier->usActionData == sClosestDisturbance) + //{ + // return( AI_ACTION_CLIMB_ROOF ); + //} + + + if ( ( pSoldier->bAttitude == CUNNINGAID || pSoldier->bAttitude == CUNNINGSOLO || pSoldier->bAttitude == BRAVESOLO ) && gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE ) + { + INT8 action = AI_ACTION_SEEK_OPPONENT; + INT16 dist = PythSpacesAway ( pSoldier->sGridNo, sClosestDisturbance ); + if ( dist > MIN_FLANK_DIST_RED && dist < MAX_FLANK_DIST_RED ) + { + INT16 rdm = Random(6); + + switch (rdm) + { + case 1: + case 2: + case 3: + if ( pSoldier->bLastAction != AI_ACTION_FLANK_LEFT && pSoldier->bLastAction != AI_ACTION_FLANK_RIGHT ) + action = AI_ACTION_FLANK_LEFT ; + break; + default: + if ( pSoldier->bLastAction != AI_ACTION_FLANK_LEFT && pSoldier->bLastAction != AI_ACTION_FLANK_RIGHT ) + action = AI_ACTION_FLANK_RIGHT ; + break; + } + } + else + return AI_ACTION_SEEK_OPPONENT ; + + pSoldier->usActionData = FindFlankingSpot (pSoldier, sClosestDisturbance, action ); + + if ( pSoldier->usActionData == NOWHERE || pSoldier->numFlanks >= MAX_FLANKS_RED ) + { + pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestDisturbance,AP_CROUCH, AI_ACTION_SEEK_OPPONENT,0); + //pSoldier->numFlanks = 0; if ( PythSpacesAway( pSoldier->usActionData, sClosestDisturbance ) < 5 || LocationToLocationLineOfSightTest( pSoldier->usActionData, pSoldier->bLevel, sClosestDisturbance, pSoldier->bLevel, (UINT8) MaxDistanceVisible(), TRUE ) ) { // reserve APs for a possible crouch plus a shot @@ -2856,252 +2826,289 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); return(AI_ACTION_SEEK_OPPONENT); } } + else { return(AI_ACTION_SEEK_OPPONENT); } - break; } - } - } - - // mark SEEKING as impossible for next time through while loop - #ifdef DEBUGDECISIONS - AINameMessage(pSoldier,"couldn't SEEK...",1000); - #endif - bSeekPts = -99; - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: couldn't seek"); - } - - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: checking to watch"); - // if WATCHING is possible and at least as desirable as anything else - if ((bWatchPts > -90) && (bWatchPts >= bSeekPts) && (bWatchPts >= bHelpPts) && (bWatchPts >= bHidePts )) - { - // take a look at our highest watch point... if it's still visible, turn to face it and then wait - bHighestWatchLoc = GetHighestVisibleWatchedLoc( pSoldier->ubID ); - //sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, gsWatchedLoc[ pSoldier->ubID ][ bHighestWatchLoc ], gbWatchedLocLevel[ pSoldier->ubID ][ bHighestWatchLoc ] ); - if ( bHighestWatchLoc != -1 ) - { - // see if we need turn to face that location - ubOpponentDir = atan8( CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX( gsWatchedLoc[ pSoldier->ubID ][ bHighestWatchLoc ] ),CenterY( gsWatchedLoc[ pSoldier->ubID ][ bHighestWatchLoc ] ) ); - - // if soldier is not already facing in that direction, - // and the opponent is close enough that he could possibly be seen - if ( pSoldier->bDirection != ubOpponentDir && InternalIsValidStance( pSoldier, ubOpponentDir, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) ) - { - // turn - pSoldier->usActionData = ubOpponentDir; - pSoldier->bNextAction = AI_ACTION_END_TURN; - return(AI_ACTION_CHANGE_FACING); - } - else - { - // consider at least crouching - if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND && InternalIsValidStance( pSoldier, ubOpponentDir, ANIM_CROUCH ) ) + else { - pSoldier->usActionData = ANIM_CROUCH; - pSoldier->bNextAction = AI_ACTION_END_TURN; - return(AI_ACTION_CHANGE_STANCE); - } - else if ( gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE ) - { - // maybe go prone - if ( PreRandom( 2 ) == 0 && InternalIsValidStance( pSoldier, ubOpponentDir, ANIM_PRONE ) ) - { - pSoldier->usActionData = ANIM_PRONE; - pSoldier->bNextAction = AI_ACTION_END_TURN; - return( AI_ACTION_CHANGE_STANCE ); - } - // end turn - return( AI_ACTION_END_TURN ); - } - } - - } - - bWatchPts = -99; - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: couldn't watch"); - - } - - - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: checking to help"); - // if HELPING is possible and at least as desirable as seeking or hiding - if ((bHelpPts > -90) && (bHelpPts >= bSeekPts) && (bHelpPts >= bHidePts) && (bHelpPts >= bWatchPts )) - { - #ifdef AI_TIMING_TESTS - uiStartTime = GetJA2Clock(); - #endif - sClosestFriend = ClosestReachableFriendInTrouble(pSoldier, &fClimb ); - #ifdef AI_TIMING_TESTS - uiEndTime = GetJA2Clock(); - - guiRedHelpTimeTotal += (uiEndTime - uiStartTime); - guiRedHelpCounter++; - #endif - - if (sClosestFriend != NOWHERE) - { - ////////////////////////////////////////////////////////////////////// - // GO DIRECTLY TOWARDS CLOSEST FRIEND UNDER FIRE OR WHO LAST RADIOED - ////////////////////////////////////////////////////////////////////// - pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestFriend,AP_CROUCH, AI_ACTION_SEEK_OPPONENT,0); - - if (pSoldier->usActionData != NOWHERE) - { - #ifdef DEBUGDECISIONS - sprintf(tempstr,"%s - SEEKING FRIEND at %d, MOVING to %d", - pSoldier->name,sClosestFriend,pSoldier->usActionData); - AIPopMessage(tempstr); - #endif - - if ( fClimb )//&& pSoldier->usActionData == sClosestFriend) - { - // need to climb AND have enough APs to get there this turn - BOOLEAN fUp = TRUE; - if (pSoldier->bLevel > 0 ) - fUp = FALSE; - - if (!fUp) - DebugMsg ( TOPIC_JA2AI , DBG_LEVEL_3 , String("Soldier %d is climbing down",pSoldier->ubID) ); - - if ( CanClimbFromHere ( pSoldier, fUp ) ) - { - if (IsActionAffordable(pSoldier) && pSoldier->bActionPoints >= ( AP_CLIMBROOF + MinAPsToAttack( pSoldier, sClosestFriend, ADDTURNCOST))) - { - return( AI_ACTION_CLIMB_ROOF ); - } - } + if ( action == AI_ACTION_FLANK_LEFT ) + pSoldier->lastFlankLeft = TRUE; else - { - pSoldier->usActionData = FindClosestClimbPoint(pSoldier->sGridNo , sClosestFriend , fUp ); - if ( pSoldier->usActionData != NOWHERE ) - { - return( AI_ACTION_MOVE_TO_CLIMB ); - } - } + pSoldier->lastFlankLeft = FALSE; + + if ( pSoldier->lastFlankSpot != sClosestDisturbance) + pSoldier->numFlanks=0; + + + pSoldier->origDir = GetDirectionFromGridNo ( sClosestDisturbance, pSoldier); + pSoldier->lastFlankSpot = sClosestDisturbance; + pSoldier->numFlanks++; + return(action); } - //if (fClimb && pSoldier->usActionData == sClosestFriend) - //{ - // return( AI_ACTION_CLIMB_ROOF ); - //} - return(AI_ACTION_SEEK_FRIEND); } - } - - // mark SEEKING as impossible for next time through while loop - #ifdef DEBUGDECISIONS - AINameMessage(pSoldier,"couldn't HELP...",1000); - #endif - - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: couldn't help"); - bHelpPts = -99; - } - - - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: checking to hide"); - // if HIDING is possible and at least as desirable as seeking or helping - if ((bHidePts > -90) && (bHidePts >= bSeekPts) && (bHidePts >= bHelpPts) && (bHidePts >= bWatchPts )) - { - sClosestOpponent = ClosestKnownOpponent( pSoldier, NULL, NULL ); - // if an opponent is known (not necessarily reachable or conscious) - if (!SkipCoverCheck && sClosestOpponent != NOWHERE ) - { - ////////////////////////////////////////////////////////////////////// - // TAKE BEST NEARBY COVER FROM ALL KNOWN OPPONENTS - ////////////////////////////////////////////////////////////////////// - #ifdef AI_TIMING_TESTS - uiStartTime = GetJA2Clock(); - #endif - - pSoldier->usActionData = FindBestNearbyCover(pSoldier,pSoldier->bAIMorale,&iDummy); - #ifdef AI_TIMING_TESTS - uiEndTime = GetJA2Clock(); - - guiRedHideTimeTotal += (uiEndTime - uiStartTime); - guiRedHideCounter++; - #endif - - // let's be a bit cautious about going right up to a location without enough APs to shoot - if ( pSoldier->usActionData != NOWHERE ) + else { - sClosestDisturbance = ClosestReachableDisturbance(pSoldier, ubUnconsciousOK, &fClimb); - if ( sClosestDisturbance != NOWHERE && ( SpacesAway( pSoldier->usActionData, sClosestDisturbance ) < 5 || SpacesAway( pSoldier->usActionData, sClosestDisturbance ) + 5 < SpacesAway( pSoldier->sGridNo, sClosestDisturbance ) ) ) + // let's be a bit cautious about going right up to a location without enough APs to shoot + if ( PythSpacesAway( pSoldier->usActionData, sClosestDisturbance ) < 5 || LocationToLocationLineOfSightTest( pSoldier->usActionData, pSoldier->bLevel, sClosestDisturbance, pSoldier->bLevel, (UINT8) MaxDistanceVisible(), TRUE ) ) { - // either moving significantly closer or into very close range - // ensure will we have enough APs for a possible crouch plus a shot - if ( InternalGoAsFarAsPossibleTowards( pSoldier, pSoldier->usActionData, (INT8) (MinAPsToAttack( pSoldier, sClosestOpponent, ADDTURNCOST) + AP_CROUCH), AI_ACTION_TAKE_COVER, 0 ) == pSoldier->usActionData ) + // reserve APs for a possible crouch plus a shot + pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, sClosestDisturbance, (INT8) (MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST) + AP_CROUCH), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS ); + if ( pSoldier->usActionData != NOWHERE ) { - return(AI_ACTION_TAKE_COVER); + pSoldier->fAIFlags |= AI_CAUTIOUS; + pSoldier->bNextAction = AI_ACTION_END_TURN; + return(AI_ACTION_SEEK_OPPONENT); } } else + { + return(AI_ACTION_SEEK_OPPONENT); + } + break; + } + } + } + + // mark SEEKING as impossible for next time through while loop +#ifdef DEBUGDECISIONS + AINameMessage(pSoldier,"couldn't SEEK...",1000); +#endif + bSeekPts = -99; + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: couldn't seek"); + } + + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: checking to watch"); + // if WATCHING is possible and at least as desirable as anything else + if ((bWatchPts > -90) && (bWatchPts >= bSeekPts) && (bWatchPts >= bHelpPts) && (bWatchPts >= bHidePts )) + { + // take a look at our highest watch point... if it's still visible, turn to face it and then wait + bHighestWatchLoc = GetHighestVisibleWatchedLoc( pSoldier->ubID ); + //sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, gsWatchedLoc[ pSoldier->ubID ][ bHighestWatchLoc ], gbWatchedLocLevel[ pSoldier->ubID ][ bHighestWatchLoc ] ); + if ( bHighestWatchLoc != -1 ) + { + // see if we need turn to face that location + ubOpponentDir = atan8( CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX( gsWatchedLoc[ pSoldier->ubID ][ bHighestWatchLoc ] ),CenterY( gsWatchedLoc[ pSoldier->ubID ][ bHighestWatchLoc ] ) ); + + // if soldier is not already facing in that direction, + // and the opponent is close enough that he could possibly be seen + if ( pSoldier->bDirection != ubOpponentDir && InternalIsValidStance( pSoldier, ubOpponentDir, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) ) + { + // turn + pSoldier->usActionData = ubOpponentDir; + pSoldier->bNextAction = AI_ACTION_END_TURN; + return(AI_ACTION_CHANGE_FACING); + } + else + { + // consider at least crouching + if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND && InternalIsValidStance( pSoldier, ubOpponentDir, ANIM_CROUCH ) ) + { + pSoldier->usActionData = ANIM_CROUCH; + pSoldier->bNextAction = AI_ACTION_END_TURN; + return(AI_ACTION_CHANGE_STANCE); + } + else if ( gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE ) + { + // maybe go prone + if ( PreRandom( 2 ) == 0 && InternalIsValidStance( pSoldier, ubOpponentDir, ANIM_PRONE ) ) + { + pSoldier->usActionData = ANIM_PRONE; + pSoldier->bNextAction = AI_ACTION_END_TURN; + return( AI_ACTION_CHANGE_STANCE ); + } + // end turn + return( AI_ACTION_END_TURN ); + } + } + + } + + bWatchPts = -99; + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: couldn't watch"); + + } + + + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: checking to help"); + // if HELPING is possible and at least as desirable as seeking or hiding + if ((bHelpPts > -90) && (bHelpPts >= bSeekPts) && (bHelpPts >= bHidePts) && (bHelpPts >= bWatchPts )) + { +#ifdef AI_TIMING_TESTS + uiStartTime = GetJA2Clock(); +#endif + sClosestFriend = ClosestReachableFriendInTrouble(pSoldier, &fClimb ); +#ifdef AI_TIMING_TESTS + uiEndTime = GetJA2Clock(); + + guiRedHelpTimeTotal += (uiEndTime - uiStartTime); + guiRedHelpCounter++; +#endif + + if (sClosestFriend != NOWHERE) + { + ////////////////////////////////////////////////////////////////////// + // GO DIRECTLY TOWARDS CLOSEST FRIEND UNDER FIRE OR WHO LAST RADIOED + ////////////////////////////////////////////////////////////////////// + pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestFriend,AP_CROUCH, AI_ACTION_SEEK_OPPONENT,0); + + if (pSoldier->usActionData != NOWHERE) + { +#ifdef DEBUGDECISIONS + sprintf(tempstr,"%s - SEEKING FRIEND at %d, MOVING to %d", + pSoldier->name,sClosestFriend,pSoldier->usActionData); + AIPopMessage(tempstr); +#endif + + if ( fClimb )//&& pSoldier->usActionData == sClosestFriend) + { + // need to climb AND have enough APs to get there this turn + BOOLEAN fUp = TRUE; + if (pSoldier->bLevel > 0 ) + fUp = FALSE; + + if (!fUp) + DebugMsg ( TOPIC_JA2AI , DBG_LEVEL_3 , String("Soldier %d is climbing down",pSoldier->ubID) ); + + if ( CanClimbFromHere ( pSoldier, fUp ) ) + { + if (IsActionAffordable(pSoldier) && pSoldier->bActionPoints >= ( AP_CLIMBROOF + MinAPsToAttack( pSoldier, sClosestFriend, ADDTURNCOST))) + { + return( AI_ACTION_CLIMB_ROOF ); + } + } + else + { + pSoldier->usActionData = FindClosestClimbPoint(pSoldier->sGridNo , sClosestFriend , fUp ); + if ( pSoldier->usActionData != NOWHERE ) + { + return( AI_ACTION_MOVE_TO_CLIMB ); + } + } + } + //if (fClimb && pSoldier->usActionData == sClosestFriend) + //{ + // return( AI_ACTION_CLIMB_ROOF ); + //} + return(AI_ACTION_SEEK_FRIEND); + } + } + + // mark SEEKING as impossible for next time through while loop +#ifdef DEBUGDECISIONS + AINameMessage(pSoldier,"couldn't HELP...",1000); +#endif + + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: couldn't help"); + bHelpPts = -99; + } + + + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: checking to hide"); + // if HIDING is possible and at least as desirable as seeking or helping + if ((bHidePts > -90) && (bHidePts >= bSeekPts) && (bHidePts >= bHelpPts) && (bHidePts >= bWatchPts )) + { + sClosestOpponent = ClosestKnownOpponent( pSoldier, NULL, NULL ); + // if an opponent is known (not necessarily reachable or conscious) + if (!SkipCoverCheck && sClosestOpponent != NOWHERE ) + { + ////////////////////////////////////////////////////////////////////// + // TAKE BEST NEARBY COVER FROM ALL KNOWN OPPONENTS + ////////////////////////////////////////////////////////////////////// +#ifdef AI_TIMING_TESTS + uiStartTime = GetJA2Clock(); +#endif + + pSoldier->usActionData = FindBestNearbyCover(pSoldier,pSoldier->bAIMorale,&iDummy); +#ifdef AI_TIMING_TESTS + uiEndTime = GetJA2Clock(); + + guiRedHideTimeTotal += (uiEndTime - uiStartTime); + guiRedHideCounter++; +#endif + + // let's be a bit cautious about going right up to a location without enough APs to shoot + if ( pSoldier->usActionData != NOWHERE ) + { + sClosestDisturbance = ClosestReachableDisturbance(pSoldier, ubUnconsciousOK, &fClimb); + if ( sClosestDisturbance != NOWHERE && ( SpacesAway( pSoldier->usActionData, sClosestDisturbance ) < 5 || SpacesAway( pSoldier->usActionData, sClosestDisturbance ) + 5 < SpacesAway( pSoldier->sGridNo, sClosestDisturbance ) ) ) + { + // either moving significantly closer or into very close range + // ensure will we have enough APs for a possible crouch plus a shot + if ( InternalGoAsFarAsPossibleTowards( pSoldier, pSoldier->usActionData, (INT8) (MinAPsToAttack( pSoldier, sClosestOpponent, ADDTURNCOST) + AP_CROUCH), AI_ACTION_TAKE_COVER, 0 ) == pSoldier->usActionData ) { return(AI_ACTION_TAKE_COVER); } } - + else + { + return(AI_ACTION_TAKE_COVER); + } } - // mark HIDING as impossible for next time through while loop - #ifdef DEBUGDECISIONS - AINameMessage(pSoldier,"couldn't HIDE...",1000); - #endif - - bHidePts = -99; - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: couldn't hide"); } + + // mark HIDING as impossible for next time through while loop +#ifdef DEBUGDECISIONS + AINameMessage(pSoldier,"couldn't HIDE...",1000); +#endif + + bHidePts = -99; + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: couldn't hide"); } } + } DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: nothing to do!"); - //////////////////////////////////////////////////////////////////////////// - // NOTHING USEFUL POSSIBLE! IF NPC IS CURRENTLY UNDER FIRE, TRY TO RUN AWAY - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // NOTHING USEFUL POSSIBLE! IF NPC IS CURRENTLY UNDER FIRE, TRY TO RUN AWAY + //////////////////////////////////////////////////////////////////////////// - // if we're currently under fire (presumably, attacker is hidden) - if (pSoldier->bUnderFire || fCivilian) + // if we're currently under fire (presumably, attacker is hidden) + if (pSoldier->bUnderFire || fCivilian) + { + // only try to run if we've actually been hit recently & noticably so + // otherwise, presumably our current cover is pretty good & sufficient + if (pSoldier->bShock > 0 || fCivilian) { - // only try to run if we've actually been hit recently & noticably so - // otherwise, presumably our current cover is pretty good & sufficient - if (pSoldier->bShock > 0 || fCivilian) - { - // look for best place to RUN AWAY to (farthest from the closest threat) - pSoldier->usActionData = FindSpotMaxDistFromOpponents(pSoldier); + // look for best place to RUN AWAY to (farthest from the closest threat) + pSoldier->usActionData = FindSpotMaxDistFromOpponents(pSoldier); - if (pSoldier->usActionData != NOWHERE) - { - #ifdef DEBUGDECISIONS + if (pSoldier->usActionData != NOWHERE) + { +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s RUNNING AWAY to grid %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); - #endif + AIPopMessage(tempstr); +#endif DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: run away!"); - return(AI_ACTION_RUN_AWAY); - } + return(AI_ACTION_RUN_AWAY); } + } - //////////////////////////////////////////////////////////////////////////// - // UNDER FIRE, DON'T WANNA/CAN'T RUN AWAY, SO CROUCH - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // UNDER FIRE, DON'T WANNA/CAN'T RUN AWAY, SO CROUCH + //////////////////////////////////////////////////////////////////////////// DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: crouch or go prone"); - // if not in water and not already crouched - if (!fCivilian ) - { + // if not in water and not already crouched + if (!fCivilian ) + { if ( gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_STAND && IsValidStance( pSoldier, ANIM_CROUCH ) ) { if (!gfTurnBasedAI || GetAPsToChangeStance( pSoldier, ANIM_CROUCH ) <= pSoldier->bActionPoints) { - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s CROUCHES (STATUS RED)",pSoldier->name); - AIPopMessage(tempstr); - #endif + AIPopMessage(tempstr); +#endif - pSoldier->usActionData = ANIM_CROUCH; - return(AI_ACTION_CHANGE_STANCE); + pSoldier->usActionData = ANIM_CROUCH; + return(AI_ACTION_CHANGE_STANCE); } } else if ( gAnimControl[ pSoldier->usAnimState ].ubHeight != ANIM_PRONE ) @@ -3114,74 +3121,74 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); } } - } } + } } DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: look around towards opponent"); - //////////////////////////////////////////////////////////////////////////// - // LOOK AROUND TOWARD CLOSEST KNOWN OPPONENT, IF KNOWN - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // LOOK AROUND TOWARD CLOSEST KNOWN OPPONENT, IF KNOWN + //////////////////////////////////////////////////////////////////////////// if (!gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints) { - // determine the location of the known closest opponent - // (don't care if he's conscious, don't care if he's reachable at all) - sClosestOpponent = ClosestKnownOpponent(pSoldier, NULL, NULL); + // determine the location of the known closest opponent + // (don't care if he's conscious, don't care if he's reachable at all) + sClosestOpponent = ClosestKnownOpponent(pSoldier, NULL, NULL); - if (sClosestOpponent != NOWHERE) + if (sClosestOpponent != NOWHERE) { - // determine direction from this soldier to the closest opponent - ubOpponentDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent)); + // determine direction from this soldier to the closest opponent + ubOpponentDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent)); - // if soldier is not already facing in that direction, - // and the opponent is close enough that he could possibly be seen - // note, have to change this to use the level returned from ClosestKnownOpponent - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sClosestOpponent, 0, pSoldier ); + // if soldier is not already facing in that direction, + // and the opponent is close enough that he could possibly be seen + // note, have to change this to use the level returned from ClosestKnownOpponent + sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sClosestOpponent, 0, pSoldier ); - if ((pSoldier->bDirection != ubOpponentDir) && (PythSpacesAway(pSoldier->sGridNo,sClosestOpponent) <= sDistVisible)) + if ((pSoldier->bDirection != ubOpponentDir) && (PythSpacesAway(pSoldier->sGridNo,sClosestOpponent) <= sDistVisible)) { - // set base chance according to orders - if ((pSoldier->bOrders == STATIONARY) || (pSoldier->bOrders == ONGUARD)) - iChance = 50; - else // all other orders - iChance = 25; + // set base chance according to orders + if ((pSoldier->bOrders == STATIONARY) || (pSoldier->bOrders == ONGUARD)) + iChance = 50; + else // all other orders + iChance = 25; - if (pSoldier->bAttitude == DEFENSIVE) - iChance += 25; + if (pSoldier->bAttitude == DEFENSIVE) + iChance += 25; - if ( TANK( pSoldier ) ) - { - iChance += 50; - } - - if ((INT16)PreRandom(100) < iChance && InternalIsValidStance( pSoldier, ubOpponentDir, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) ) + if ( TANK( pSoldier ) ) { - pSoldier->usActionData = ubOpponentDir; + iChance += 50; + } - #ifdef DEBUGDECISIONS + if ((INT16)PreRandom(100) < iChance && InternalIsValidStance( pSoldier, ubOpponentDir, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) ) + { + pSoldier->usActionData = ubOpponentDir; + +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - TURNS TOWARDS CLOSEST ENEMY to face direction %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); - #endif - if ( pSoldier->bOrders == SNIPER ) - { - if (!gfTurnBasedAI || GetAPsToReadyWeapon( pSoldier, READY_RIFLE_CROUCH ) <= pSoldier->bActionPoints) + AIPopMessage(tempstr); +#endif + if ( pSoldier->bOrders == SNIPER ) { - pSoldier->bNextAction = AI_ACTION_RAISE_GUN; + if (!gfTurnBasedAI || GetAPsToReadyWeapon( pSoldier, READY_RIFLE_CROUCH ) <= pSoldier->bActionPoints) + { + pSoldier->bNextAction = AI_ACTION_RAISE_GUN; + } } - } - return(AI_ACTION_CHANGE_FACING); + return(AI_ACTION_CHANGE_FACING); } } - else if ( pSoldier->bDirection == ubOpponentDir && pSoldier->bOrders == SNIPER ) - { - if (!gfTurnBasedAI || GetAPsToReadyWeapon( pSoldier, READY_RIFLE_CROUCH ) <= pSoldier->bActionPoints) + else if ( pSoldier->bDirection == ubOpponentDir && pSoldier->bOrders == SNIPER ) { - return AI_ACTION_RAISE_GUN; + if (!gfTurnBasedAI || GetAPsToReadyWeapon( pSoldier, READY_RIFLE_CROUCH ) <= pSoldier->bActionPoints) + { + return AI_ACTION_RAISE_GUN; + } } - } } } @@ -3210,10 +3217,10 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); { pSoldier->usActionData = ubOpponentDir; - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - TURNS TOWARDS CLOSEST ENEMY to face direction %d",pSoldier->name,pSoldier->usActionData); AIPopMessage(tempstr); - #endif +#endif // limit turning a bit... if the last thing we did was also a turn, add a 60% chance of this being our last turn if ( pSoldier->bLastAction == AI_ACTION_CHANGE_FACING && PreRandom( 100 ) < 60 ) @@ -3226,7 +3233,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); { pSoldier->bNextAction = AI_ACTION_WAIT; pSoldier->usNextActionData = (UINT16) REALTIME_AI_DELAY; - } + } } return(AI_ACTION_CHANGE_FACING); @@ -3276,8 +3283,8 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); // NOT IMPLEMENTED -/* JULY 29, 1996 - Decided that this was a bad idea, after watching a civilian - start a random patrol while 2 steps away from a hidden armed opponent...*/ + /* JULY 29, 1996 - Decided that this was a bad idea, after watching a civilian + start a random patrol while 2 steps away from a hidden armed opponent...*/ //////////////////////////////////////////////////////////////////////////// // SWITCH TO GREEN: soldier does ordinary regular patrol, seeks friends @@ -3320,11 +3327,11 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); { if (!gfTurnBasedAI || GetAPsToChangeStance( pSoldier, ANIM_CROUCH ) <= pSoldier->bActionPoints) { - - #ifdef DEBUGDECISIONS + +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s CROUCHES (STATUS RED)",pSoldier->name ); AIPopMessage(tempstr); - #endif +#endif pSoldier->usActionData = ANIM_CROUCH; return(AI_ACTION_CHANGE_STANCE); @@ -3341,7 +3348,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); sClosestDisturbance = MostImportantNoiseHeard( pSoldier, NULL, NULL, NULL ); if ( sClosestDisturbance != NOWHERE ) { - ubOpponentDir = atan8( CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), CenterX( sClosestDisturbance ), CenterY( sClosestDisturbance ) ); + ubOpponentDir = atan8( CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), CenterX( sClosestDisturbance ), CenterY( sClosestDisturbance ) ); if ( pSoldier->bDirection != ubOpponentDir ) { if ( !gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints ) @@ -3361,9 +3368,9 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); } - //////////////////////////////////////////////////////////////////////////// - // If sniper and nothing else to do then raise gun, and if that doesn't find somebody then goto yellow - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // If sniper and nothing else to do then raise gun, and if that doesn't find somebody then goto yellow + //////////////////////////////////////////////////////////////////////////// if ( pSoldier->bOrders == SNIPER ) { if ( pSoldier->sniper == 0 ) @@ -3371,24 +3378,24 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionRed: sniper raising gun...")); if (!gfTurnBasedAI || GetAPsToReadyWeapon( pSoldier, READY_RIFLE_CROUCH ) <= pSoldier->bActionPoints) { - pSoldier->sniper = 1; + pSoldier->sniper = 1; return AI_ACTION_RAISE_GUN; } } - else + else { pSoldier->sniper = 0; return(DecideActionYellow(pSoldier)); } } - -//////////////////////////////////////////////////////////////////////////// - // DO NOTHING: Not enough points left to move, so save them for next turn - //////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////// + // DO NOTHING: Not enough points left to move, so save them for next turn + //////////////////////////////////////////////////////////////////////////// DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionRed: do nothing at all...")); - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS AINameMessage(pSoldier,"- DOES NOTHING (RED)",1000); - #endif +#endif pSoldier->usActionData = NOWHERE; return(AI_ACTION_NONE); @@ -3396,47 +3403,47 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: radio red alert?"); INT8 DecideActionBlack(SOLDIERTYPE *pSoldier) { - INT32 iCoverPercentBetter, iOffense, iDefense, iChance; - INT16 sClosestOpponent,sBestCover = NOWHERE; - INT16 sClosestDisturbance; - UINT8 ubMinAPCost,ubCanMove; - INT8 bInWater,bInDeepWater,bInGas; - INT8 bDirection; - UINT8 ubBestAttackAction = AI_ACTION_NONE; - INT8 bCanAttack,bActionReturned; - INT8 bWeaponIn; - BOOLEAN fTryPunching = FALSE; - #ifdef DEBUGDECISIONS - STR16 tempstr; - #endif + INT32 iCoverPercentBetter, iOffense, iDefense, iChance; + INT16 sClosestOpponent,sBestCover = NOWHERE; + INT16 sClosestDisturbance; + UINT8 ubMinAPCost,ubCanMove; + INT8 bInWater,bInDeepWater,bInGas; + INT8 bDirection; + UINT8 ubBestAttackAction = AI_ACTION_NONE; + INT8 bCanAttack,bActionReturned; + INT8 bWeaponIn; + BOOLEAN fTryPunching = FALSE; +#ifdef DEBUGDECISIONS + STR16 tempstr; +#endif DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionBlack: soldier = %d, orders = %d, attitude = %d",pSoldier->ubID,pSoldier->bOrders,pSoldier->bAttitude)); - ATTACKTYPE BestShot,BestThrow,BestStab,BestAttack; - BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP || pSoldier->bNeutral || (pSoldier->ubBodyType >= FATCIV && pSoldier->ubBodyType <= CRIPPLECIV) ) ); - UINT8 ubBestStance, ubStanceCost; - BOOLEAN fChangeStanceFirst; // before firing - BOOLEAN fClimb; - UINT8 ubBurstAPs; - UINT8 ubOpponentDir; - INT16 sCheckGridNo; + ATTACKTYPE BestShot,BestThrow,BestStab,BestAttack; + BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP || pSoldier->bNeutral || (pSoldier->ubBodyType >= FATCIV && pSoldier->ubBodyType <= CRIPPLECIV) ) ); + UINT8 ubBestStance, ubStanceCost; + BOOLEAN fChangeStanceFirst; // before firing + BOOLEAN fClimb; + UINT8 ubBurstAPs; + UINT8 ubOpponentDir; + INT16 sCheckGridNo; - BOOLEAN fAllowCoverCheck = FALSE; + BOOLEAN fAllowCoverCheck = FALSE; DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack"); // once we hit status black, reset flanking status -//pSoldier->numFlanks = 0; + //pSoldier->numFlanks = 0; - // if we have absolutely no action points, we can't do a thing under BLACK! - if (!pSoldier->bActionPoints) - { - pSoldier->usActionData = NOWHERE; - return(AI_ACTION_NONE); - } + // if we have absolutely no action points, we can't do a thing under BLACK! + if (!pSoldier->bActionPoints) + { + pSoldier->usActionData = NOWHERE; + return(AI_ACTION_NONE); + } - // can this guy move to any of the neighbouring squares ? (sets TRUE/FALSE) - ubCanMove = (pSoldier->bActionPoints >= MinPtsToMove(pSoldier)); + // can this guy move to any of the neighbouring squares ? (sets TRUE/FALSE) + ubCanMove = (pSoldier->bActionPoints >= MinPtsToMove(pSoldier)); if ( (pSoldier->bTeam == ENEMY_TEAM || pSoldier->ubProfile == WARDEN) && (gTacticalStatus.fPanicFlags & PANIC_TRIGGERS_HERE) && (gTacticalStatus.ubTheChosenOne == NOBODY) ) { @@ -3444,22 +3451,22 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier) bPanicTrigger = ClosestPanicTrigger( pSoldier ); // if it's an alarm trigger and team is alerted, ignore it - if ( !(gTacticalStatus.bPanicTriggerIsAlarm[ bPanicTrigger ] && gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition) && PythSpacesAway( pSoldier->sGridNo, gTacticalStatus.sPanicTriggerGridNo[ bPanicTrigger ] ) < 10) + if ( !(gTacticalStatus.bPanicTriggerIsAlarm[ bPanicTrigger ] && gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition) && PythSpacesAway( pSoldier->sGridNo, gTacticalStatus.sPanicTriggerGridNo[ bPanicTrigger ] ) < 10) { PossiblyMakeThisEnemyChosenOne( pSoldier ); } } - // if this soldier is the "Chosen One" (enemies only) - if (pSoldier->ubID == gTacticalStatus.ubTheChosenOne) - { - // do some special panic AI decision making - bActionReturned = PanicAI(pSoldier,ubCanMove); + // if this soldier is the "Chosen One" (enemies only) + if (pSoldier->ubID == gTacticalStatus.ubTheChosenOne) + { + // do some special panic AI decision making + bActionReturned = PanicAI(pSoldier,ubCanMove); - // if we decided on an action while in there, we're done - if (bActionReturned != -1) - return(bActionReturned); - } + // if we decided on an action while in there, we're done + if (bActionReturned != -1) + return(bActionReturned); + } if ( pSoldier->ubProfile != NO_PROFILE ) { @@ -3508,7 +3515,7 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier) // check if standing in tear gas without a gas mask on bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); - + // calculate our morale pSoldier->bAIMorale = CalcMorale(pSoldier); @@ -3540,10 +3547,10 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier) if (pSoldier->usActionData != NOWHERE) { - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - GASSED or LOW ON BREATH (%d), RUNNING AWAY to grid %d",pSoldier->name,pSoldier->bBreath,pSoldier->usActionData); - AIPopMessage(tempstr); - #endif + AIPopMessage(tempstr); +#endif return(AI_ACTION_RUN_AWAY); } @@ -3553,7 +3560,7 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier) if ( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE ) { pSoldier->bBreath = pSoldier->bBreathMax; //Madd: backed into a corner, so go crazy like a wild animal... - pSoldier->bAIMorale = MORALE_FEARLESS; + pSoldier->bAIMorale = MORALE_FEARLESS; } else pSoldier->bAIMorale = MORALE_HOPELESS; @@ -3563,65 +3570,65 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier) - //////////////////////////////////////////////////////////////////////////// - // STUCK IN WATER OR GAS, NO COVER, GO TO NEAREST SPOT OF UNGASSED LAND - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // STUCK IN WATER OR GAS, NO COVER, GO TO NEAREST SPOT OF UNGASSED LAND + //////////////////////////////////////////////////////////////////////////// - // if soldier in water/gas has enough APs left to move at least 1 square - if ( ( bInDeepWater || bInGas ) && ubCanMove) - { - pSoldier->usActionData = FindNearestUngassedLand(pSoldier); + // if soldier in water/gas has enough APs left to move at least 1 square + if ( ( bInDeepWater || bInGas ) && ubCanMove) + { + pSoldier->usActionData = FindNearestUngassedLand(pSoldier); - if (pSoldier->usActionData != NOWHERE) - { + if (pSoldier->usActionData != NOWHERE) + { #ifdef DEBUGDECISIONS sprintf(tempstr,"%s - SEEKING NEAREST UNGASSED LAND at grid %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); + AIPopMessage(tempstr); #endif - return(AI_ACTION_LEAVE_WATER_GAS); - } + return(AI_ACTION_LEAVE_WATER_GAS); + } - // couldn't find ANY land within 25 tiles(!), this should never happen... + // couldn't find ANY land within 25 tiles(!), this should never happen... - // look for best place to RUN AWAY to (farthest from the closest threat) - pSoldier->usActionData = FindSpotMaxDistFromOpponents(pSoldier); + // look for best place to RUN AWAY to (farthest from the closest threat) + pSoldier->usActionData = FindSpotMaxDistFromOpponents(pSoldier); - if (pSoldier->usActionData != NOWHERE) - { + if (pSoldier->usActionData != NOWHERE) + { #ifdef DEBUGDECISIONS sprintf(tempstr,"%s - NO LAND NEAR, RUNNING AWAY to grid %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); + AIPopMessage(tempstr); #endif - return(AI_ACTION_RUN_AWAY); - } + return(AI_ACTION_RUN_AWAY); + } - // GIVE UP ON LIFE! MERCS MUST HAVE JUST CORNERED A HELPLESS ENEMY IN A - // GAS FILLED ROOM (OR IN WATER MORE THAN 25 TILES FROM NEAREST LAND...) - if ( bInGas && gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE ) - { - pSoldier->bBreath = pSoldier->bBreathMax; - pSoldier->bAIMorale = MORALE_FEARLESS; // Can't move, can't get away, go nuts instead... + // GIVE UP ON LIFE! MERCS MUST HAVE JUST CORNERED A HELPLESS ENEMY IN A + // GAS FILLED ROOM (OR IN WATER MORE THAN 25 TILES FROM NEAREST LAND...) + if ( bInGas && gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE ) + { + pSoldier->bBreath = pSoldier->bBreathMax; + pSoldier->bAIMorale = MORALE_FEARLESS; // Can't move, can't get away, go nuts instead... + } + else + pSoldier->bAIMorale = MORALE_HOPELESS; } - else - pSoldier->bAIMorale = MORALE_HOPELESS; - } // offer surrender? - + if ( pSoldier->bTeam == ENEMY_TEAM && pSoldier->bVisible == TRUE && !( gTacticalStatus.fEnemyFlags & ENEMY_OFFERED_SURRENDER ) && pSoldier->bLife >= pSoldier->bLifeMax / 2 ) - { + { if ( gTacticalStatus.Team[ MILITIA_TEAM ].bMenInSector == 0 && NumPCsInSector() < 4 && gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector >= NumPCsInSector() * 3 ) { //if( GetWorldDay() > STARTDAY_ALLOW_PLAYER_CAPTURE_FOR_RESCUE && !( gStrategicStatus.uiFlags & STRATEGIC_PLAYER_CAPTURED_FOR_RESCUE ) ) { if ( gubQuest[ QUEST_HELD_IN_ALMA ] == QUESTNOTSTARTED || ( gubQuest[ QUEST_HELD_IN_ALMA ] == QUESTDONE && gubQuest[ QUEST_INTERROGATION ] == QUESTNOTSTARTED ) ) { - gTacticalStatus.fEnemyFlags |= ENEMY_OFFERED_SURRENDER; - return( AI_ACTION_OFFER_SURRENDER ); - } - } + gTacticalStatus.fEnemyFlags |= ENEMY_OFFERED_SURRENDER; + return( AI_ACTION_OFFER_SURRENDER ); + } + } } } @@ -3652,37 +3659,37 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier) { if ( ( bCanAttack == NOSHOOT_NOWEAPON) && !(pSoldier->uiStatusFlags & SOLDIER_BOXER) && pSoldier->ubBodyType != COW && pSoldier->ubBodyType != CRIPPLECIV ) { - // cower in fear!! - if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) - { - if ( pSoldier->bLastAction == AI_ACTION_COWER ) - { - // do nothing - pSoldier->usActionData = NOWHERE; - return( AI_ACTION_NONE ); - } - else - { - // set up next action to run away - pSoldier->usNextActionData = FindSpotMaxDistFromOpponents( pSoldier ); - if ( pSoldier->usNextActionData != NOWHERE ) - { - pSoldier->bNextAction = AI_ACTION_RUN_AWAY; - pSoldier->usActionData = ANIM_STAND; - return( AI_ACTION_STOP_COWERING ); - } - else - { - return( AI_ACTION_NONE ); - } - } - } - else - { - // cower!!! - pSoldier->usActionData = ANIM_CROUCH; - return( AI_ACTION_COWER ); - } + // cower in fear!! + if ( pSoldier->uiStatusFlags & SOLDIER_COWERING ) + { + if ( pSoldier->bLastAction == AI_ACTION_COWER ) + { + // do nothing + pSoldier->usActionData = NOWHERE; + return( AI_ACTION_NONE ); + } + else + { + // set up next action to run away + pSoldier->usNextActionData = FindSpotMaxDistFromOpponents( pSoldier ); + if ( pSoldier->usNextActionData != NOWHERE ) + { + pSoldier->bNextAction = AI_ACTION_RUN_AWAY; + pSoldier->usActionData = ANIM_STAND; + return( AI_ACTION_STOP_COWERING ); + } + else + { + return( AI_ACTION_NONE ); + } + } + } + else + { + // cower!!! + pSoldier->usActionData = ANIM_CROUCH; + return( AI_ACTION_COWER ); + } } } else if (bCanAttack == NOSHOOT_NOAMMO && ubCanMove && !pSoldier->bNeutral) @@ -3697,7 +3704,11 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier) // is our gun) pSoldier->inv[HANDPOS].fFlags |= OBJECT_AI_UNUSABLE; // move the gun into another pocket... - AutoPlaceObject( pSoldier, &(pSoldier->inv[HANDPOS]), FALSE ); + if (!AutoPlaceObject( pSoldier, &(pSoldier->inv[HANDPOS]), FALSE ) ) + { + // If there's no room in his pockets for the useless gun, just throw it away + return AI_ACTION_DROP_ITEM; + } } else { @@ -3712,7 +3723,7 @@ INT8 DecideActionBlack(SOLDIERTYPE *pSoldier) } while( bCanAttack != TRUE && bCanAttack != FALSE ); #ifdef RETREAT_TESTING -bCanAttack = FALSE; + bCanAttack = FALSE; #endif if (!bCanAttack) @@ -3750,112 +3761,112 @@ bCanAttack = FALSE; BestAttack.ubChanceToReallyHit = 0; - // if we are able attack - if (bCanAttack) - { - pSoldier->bAimShotLocation = AIM_SHOT_RANDOM; + // if we are able attack + if (bCanAttack) + { + pSoldier->bAimShotLocation = AIM_SHOT_RANDOM; - ////////////////////////////////////////////////////////////////////////// - // FIRE A GUN AT AN OPPONENT - ////////////////////////////////////////////////////////////////////////// - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"FIRE A GUN AT AN OPPONENT"); + ////////////////////////////////////////////////////////////////////////// + // FIRE A GUN AT AN OPPONENT + ////////////////////////////////////////////////////////////////////////// + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"FIRE A GUN AT AN OPPONENT"); - bWeaponIn = FindAIUsableObjClass( pSoldier, IC_GUN ); + bWeaponIn = FindAIUsableObjClass( pSoldier, IC_GUN ); - if (bWeaponIn != NO_SLOT) - { - BestShot.bWeaponIn = bWeaponIn; - // if it's in another pocket, swap it into his hand temporarily - if (bWeaponIn != HANDPOS) - { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: swap gun into hand"); - RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY); - } + if (bWeaponIn != NO_SLOT) + { + BestShot.bWeaponIn = bWeaponIn; + // if it's in another pocket, swap it into his hand temporarily + if (bWeaponIn != HANDPOS) + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: swap gun into hand"); + RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY); + } - // now it better be a gun, or the guy can't shoot (but has other attack(s)) - if (Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_GUN && pSoldier->inv[HANDPOS].bGunStatus >= USABLE) - { - // get the minimum cost to attack the same target with this gun - ubMinAPCost = MinAPsToAttack(pSoldier,pSoldier->sLastTarget,DONTADDTURNCOST); + // now it better be a gun, or the guy can't shoot (but has other attack(s)) + if (Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_GUN && pSoldier->inv[HANDPOS].bGunStatus >= USABLE) + { + // get the minimum cost to attack the same target with this gun + ubMinAPCost = MinAPsToAttack(pSoldier,pSoldier->sLastTarget,ADDTURNCOST); - // if we have enough action points to shoot with this gun - if (pSoldier->bActionPoints >= ubMinAPCost) - { - // look around for a worthy target (which sets BestShot.ubPossible) - BOOLEAN shootUnseen = FALSE; - if (gGameOptions.ubDifficultyLevel > DIF_LEVEL_MEDIUM ) - shootUnseen = TRUE; - - CalcBestShot(pSoldier,&BestShot,shootUnseen); - - if (pSoldier->bTeam == gbPlayerNum && pSoldier->bRTPCombat == RTP_COMBAT_CONSERVE) + // if we have enough action points to shoot with this gun + if (pSoldier->bActionPoints >= ubMinAPCost) { - if (BestShot.ubChanceToReallyHit < 30) - { - // skip firing, our chance isn't good enough - BestShot.ubPossible = FALSE; - } - } + // look around for a worthy target (which sets BestShot.ubPossible) + BOOLEAN shootUnseen = FALSE; + if (gGameOptions.ubDifficultyLevel > DIF_LEVEL_MEDIUM ) + shootUnseen = TRUE; - if (BestShot.ubPossible) - { - // if the selected opponent is not a threat (unconscious & !serviced) - // (usually, this means all the guys we see are unconscious, but, on - // rare occasions, we may not be able to shoot a healthy guy, too) - if ((Menptr[BestShot.ubOpponent].bLife < OKLIFE) && - !Menptr[BestShot.ubOpponent].bService) + CalcBestShot(pSoldier,&BestShot,shootUnseen); + + if (pSoldier->bTeam == gbPlayerNum && pSoldier->bRTPCombat == RTP_COMBAT_CONSERVE) { - // if our attitude is NOT aggressive - if ( pSoldier->bAttitude != AGGRESSIVE || BestShot.ubChanceToReallyHit < 60 ) + if (BestShot.ubChanceToReallyHit < 30) { - // get the location of the closest CONSCIOUS reachable opponent - sClosestDisturbance = ClosestReachableDisturbance(pSoldier,FALSE, &fClimb); - - // if we found one - if (sClosestDisturbance != NOWHERE) - { - // don't bother checking GRENADES/KNIVES, he can't have conscious targets - #ifdef RECORDNET - fprintf(NetDebugFile,"\tDecideActionBlack: all visible opponents unconscious, switching to RED AI...\n"); - #endif - // then make decision as if at alert status RED, but make sure - // we don't try to SEEK OPPONENT the unconscious guy! - return(DecideActionRed(pSoldier,FALSE)); - } - // else kill the guy, he could be the last opponent alive in this sector + // skip firing, our chance isn't good enough + BestShot.ubPossible = FALSE; } - // else aggressive guys will ALWAYS finish off unconscious opponents } - // now we KNOW FOR SURE that we will do something (shoot, at least) - NPCDoesAct(pSoldier); - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"NPC decided to shoot (or something)"); + if (BestShot.ubPossible) + { + // if the selected opponent is not a threat (unconscious & !serviced) + // (usually, this means all the guys we see are unconscious, but, on + // rare occasions, we may not be able to shoot a healthy guy, too) + if ((Menptr[BestShot.ubOpponent].bLife < OKLIFE) && + !Menptr[BestShot.ubOpponent].bService) + { + // if our attitude is NOT aggressive + if ( pSoldier->bAttitude != AGGRESSIVE || BestShot.ubChanceToReallyHit < 60 ) + { + // get the location of the closest CONSCIOUS reachable opponent + sClosestDisturbance = ClosestReachableDisturbance(pSoldier,FALSE, &fClimb); + // if we found one + if (sClosestDisturbance != NOWHERE) + { + // don't bother checking GRENADES/KNIVES, he can't have conscious targets +#ifdef RECORDNET + fprintf(NetDebugFile,"\tDecideActionBlack: all visible opponents unconscious, switching to RED AI...\n"); +#endif + // then make decision as if at alert status RED, but make sure + // we don't try to SEEK OPPONENT the unconscious guy! + return(DecideActionRed(pSoldier,FALSE)); + } + // else kill the guy, he could be the last opponent alive in this sector + } + // else aggressive guys will ALWAYS finish off unconscious opponents + } + + // now we KNOW FOR SURE that we will do something (shoot, at least) + NPCDoesAct(pSoldier); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"NPC decided to shoot (or something)"); + + } } - } - - // if it was in his holster, swap it back into his holster for now - if (bWeaponIn != HANDPOS) - { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: swap gun into holster"); - RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY); - } - } - } + // if it was in his holster, swap it back into his holster for now + if (bWeaponIn != HANDPOS) + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: swap gun into holster"); + RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY); + } - ////////////////////////////////////////////////////////////////////////// - // THROW A TOSSABLE ITEM AT OPPONENT(S) - // - HTH: THIS NOW INCLUDES FIRING THE GRENADE LAUNCHAR AND MORTAR! - ////////////////////////////////////////////////////////////////////////// + } + } - // this looks for throwables, and sets BestThrow.ubPossible if it can be done - //if ( !gfHiddenInterrupt ) - // { - CheckIfTossPossible(pSoldier,&BestThrow); + ////////////////////////////////////////////////////////////////////////// + // THROW A TOSSABLE ITEM AT OPPONENT(S) + // - HTH: THIS NOW INCLUDES FIRING THE GRENADE LAUNCHAR AND MORTAR! + ////////////////////////////////////////////////////////////////////////// - if (BestThrow.ubPossible) - { + // this looks for throwables, and sets BestThrow.ubPossible if it can be done + //if ( !gfHiddenInterrupt ) + // { + CheckIfTossPossible(pSoldier,&BestThrow); + + if (BestThrow.ubPossible) + { DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"good throw possible"); if ( Item[pSoldier->inv[ BestThrow.bWeaponIn ].usItem].mortar ) { @@ -3869,63 +3880,63 @@ bCanAttack = FALSE; // can't fire! BestThrow.ubPossible = FALSE; - // try behind us, see if there's room to move back + // try behind us, see if there's room to move back sCheckGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, (UINT16)DirectionInc( gOppositeDirection[ ubOpponentDir ] ) ); if ( OKFallDirection( pSoldier, sCheckGridNo, pSoldier->bLevel, gOppositeDirection[ ubOpponentDir ], pSoldier->usAnimState ) ) { - pSoldier->usActionData = sCheckGridNo; + pSoldier->usActionData = sCheckGridNo; - return( AI_ACTION_GET_CLOSER ); + return( AI_ACTION_GET_CLOSER ); } } } - - if ( BestThrow.ubPossible ) - { - // now we KNOW FOR SURE that we will do something (throw, at least) - NPCDoesAct(pSoldier); - } - } - - - - - - //} + if ( BestThrow.ubPossible ) + { + // now we KNOW FOR SURE that we will do something (throw, at least) + NPCDoesAct(pSoldier); + } + } - ////////////////////////////////////////////////////////////////////////// - // GO STAB AN OPPONENT WITH A KNIFE - ////////////////////////////////////////////////////////////////////////// - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"GO STAB AN OPPONENT WITH A KNIFE"); - // if soldier has a knife in his hand - bWeaponIn = FindAIUsableObjClass( pSoldier, (IC_BLADE | IC_THROWING_KNIFE) ); - // if the soldier does have a usable knife somewhere - if (bWeaponIn != NO_SLOT) - { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"try to stab"); - BestStab.bWeaponIn = bWeaponIn; - // if it's in his holster, swap it into his hand temporarily - if (bWeaponIn != HANDPOS) - { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: about to rearrange pocket before stab check"); - RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY); - } - // get the minimum cost to attack with this knife - ubMinAPCost = MinAPsToAttack(pSoldier,pSoldier->sLastTarget,DONTADDTURNCOST); - // if we can afford the minimum AP cost to stab with/throw this knife weapon - if (pSoldier->bActionPoints >= ubMinAPCost) + + //} + + ////////////////////////////////////////////////////////////////////////// + // GO STAB AN OPPONENT WITH A KNIFE + ////////////////////////////////////////////////////////////////////////// + + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"GO STAB AN OPPONENT WITH A KNIFE"); + // if soldier has a knife in his hand + bWeaponIn = FindAIUsableObjClass( pSoldier, (IC_BLADE | IC_THROWING_KNIFE) ); + + // if the soldier does have a usable knife somewhere + if (bWeaponIn != NO_SLOT) + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"try to stab"); + BestStab.bWeaponIn = bWeaponIn; + // if it's in his holster, swap it into his hand temporarily + if (bWeaponIn != HANDPOS) + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: about to rearrange pocket before stab check"); + RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY); + } + + // get the minimum cost to attack with this knife + ubMinAPCost = MinAPsToAttack(pSoldier,pSoldier->sLastTarget,DONTADDTURNCOST); + + // if we can afford the minimum AP cost to stab with/throw this knife weapon + if (pSoldier->bActionPoints >= ubMinAPCost) { // NB throwing knife in hand now - if ( Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass & IC_THROWING_KNIFE ) - { - // throwing knife code works like shooting + if ( Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass & IC_THROWING_KNIFE ) + { + // throwing knife code works like shooting - // look around for a worthy target (which sets BestStab.ubPossible) + // look around for a worthy target (which sets BestStab.ubPossible) CalcBestShot(pSoldier,&BestStab,FALSE); if (BestStab.ubPossible) @@ -3934,7 +3945,7 @@ bCanAttack = FALSE; // (usually, this means all the guys we see are unconscious, but, on // rare occasions, we may not be able to shoot a healthy guy, too) if ((Menptr[BestStab.ubOpponent].bLife < OKLIFE) && - !Menptr[BestStab.ubOpponent].bService) + !Menptr[BestStab.ubOpponent].bService) { // don't throw a knife at him. BestStab.ubPossible = FALSE; @@ -3942,266 +3953,266 @@ bCanAttack = FALSE; // now we KNOW FOR SURE that we will do something (shoot, at least) NPCDoesAct(pSoldier); - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"NPC decided to shoot (2)"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"NPC decided to shoot (2)"); } - } - else - { - //sprintf((CHAR *)tempstr,"%s - ubMinAPCost = %d",pSoldier->name,ubMinAPCost); - //PopMessage(tempstr); - // then look around for a worthy target (which sets BestStab.ubPossible) - CalcBestStab(pSoldier,&BestStab, TRUE); + } + else + { + //sprintf((CHAR *)tempstr,"%s - ubMinAPCost = %d",pSoldier->name,ubMinAPCost); + //PopMessage(tempstr); + // then look around for a worthy target (which sets BestStab.ubPossible) + CalcBestStab(pSoldier,&BestStab, TRUE); - if (BestStab.ubPossible) - { - // now we KNOW FOR SURE that we will do something (stab, at least) - NPCDoesAct(pSoldier); - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"NPC decided to stab"); - } - } + if (BestStab.ubPossible) + { + // now we KNOW FOR SURE that we will do something (stab, at least) + NPCDoesAct(pSoldier); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"NPC decided to stab"); + } + } } - // if it was in his holster, swap it back into his holster for now - if (bWeaponIn != HANDPOS) - { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"about to rearrange pocket after stab check"); - RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY); - } - } + // if it was in his holster, swap it back into his holster for now + if (bWeaponIn != HANDPOS) + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"about to rearrange pocket after stab check"); + RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY); + } + } - ////////////////////////////////////////////////////////////////////////// - // CHOOSE THE BEST TYPE OF ATTACK OUT OF THOSE FOUND TO BE POSSIBLE - ////////////////////////////////////////////////////////////////////////// - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CHOOSE THE BEST TYPE OF ATTACK OUT OF THOSE FOUND TO BE POSSIBLE"); - if (BestShot.ubPossible) - { - BestAttack.iAttackValue = BestShot.iAttackValue; - ubBestAttackAction = AI_ACTION_FIRE_GUN; - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = fire gun"); - } - else - { - BestAttack.iAttackValue = 0; - } - if (BestStab.ubPossible && ((BestStab.iAttackValue > BestAttack.iAttackValue) || (ubBestAttackAction == AI_ACTION_NONE))) - { - BestAttack.iAttackValue = BestStab.iAttackValue; - if ( Item[ pSoldier->inv[BestStab.bWeaponIn].usItem ].usItemClass & IC_THROWING_KNIFE ) + ////////////////////////////////////////////////////////////////////////// + // CHOOSE THE BEST TYPE OF ATTACK OUT OF THOSE FOUND TO BE POSSIBLE + ////////////////////////////////////////////////////////////////////////// + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CHOOSE THE BEST TYPE OF ATTACK OUT OF THOSE FOUND TO BE POSSIBLE"); + if (BestShot.ubPossible) { - ubBestAttackAction = AI_ACTION_THROW_KNIFE; - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = throw knife"); + BestAttack.iAttackValue = BestShot.iAttackValue; + ubBestAttackAction = AI_ACTION_FIRE_GUN; + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = fire gun"); } else { - ubBestAttackAction = AI_ACTION_KNIFE_MOVE; - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = move to stab"); + BestAttack.iAttackValue = 0; + } + if (BestStab.ubPossible && ((BestStab.iAttackValue > BestAttack.iAttackValue) || (ubBestAttackAction == AI_ACTION_NONE))) + { + BestAttack.iAttackValue = BestStab.iAttackValue; + if ( Item[ pSoldier->inv[BestStab.bWeaponIn].usItem ].usItemClass & IC_THROWING_KNIFE ) + { + ubBestAttackAction = AI_ACTION_THROW_KNIFE; + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = throw knife"); + } + else + { + ubBestAttackAction = AI_ACTION_KNIFE_MOVE; + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = move to stab"); + } + } + if (BestThrow.ubPossible && ((BestThrow.iAttackValue > BestAttack.iAttackValue) || (ubBestAttackAction == AI_ACTION_NONE))) + { + ubBestAttackAction = AI_ACTION_TOSS_PROJECTILE; + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = throw something"); } - } - if (BestThrow.ubPossible && ((BestThrow.iAttackValue > BestAttack.iAttackValue) || (ubBestAttackAction == AI_ACTION_NONE))) - { - ubBestAttackAction = AI_ACTION_TOSS_PROJECTILE; - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = throw something"); - } - if ( ( ubBestAttackAction == AI_ACTION_NONE ) && fTryPunching ) - { - // nothing (else) to attack with so let's try hand-to-hand - bWeaponIn = FindObjWithin( pSoldier, NOTHING, HANDPOS, SMALLPOCK8POS ); + if ( ( ubBestAttackAction == AI_ACTION_NONE ) && fTryPunching ) + { + // nothing (else) to attack with so let's try hand-to-hand + bWeaponIn = FindObjWithin( pSoldier, NOTHING, HANDPOS, SMALLPOCK8POS ); - if (bWeaponIn != NO_SLOT) - { - BestStab.bWeaponIn = bWeaponIn; - // if it's in his holster, swap it into his hand temporarily - if (bWeaponIn != HANDPOS) - { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: swap knife into hand"); - RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY); - } - - // get the minimum cost to attack by HTH - ubMinAPCost = MinAPsToAttack(pSoldier,pSoldier->sLastTarget,DONTADDTURNCOST); - - // if we can afford the minimum AP cost to use HTH combat - if (pSoldier->bActionPoints >= ubMinAPCost) + if (bWeaponIn != NO_SLOT) + { + BestStab.bWeaponIn = bWeaponIn; + // if it's in his holster, swap it into his hand temporarily + if (bWeaponIn != HANDPOS) { - // then look around for a worthy target (which sets BestStab.ubPossible) - CalcBestStab(pSoldier,&BestStab, FALSE); - - if (BestStab.ubPossible) - { - // now we KNOW FOR SURE that we will do something (stab, at least) - NPCDoesAct(pSoldier); - ubBestAttackAction = AI_ACTION_KNIFE_MOVE; - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"NPC decided to move to stab"); - } + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: swap knife into hand"); + RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY); } - // if it was in his holster, swap it back into his holster for now - if (bWeaponIn != HANDPOS) - { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: about to put knife away"); - RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY); - } - } - } + // get the minimum cost to attack by HTH + ubMinAPCost = MinAPsToAttack(pSoldier,pSoldier->sLastTarget,DONTADDTURNCOST); + // if we can afford the minimum AP cost to use HTH combat + if (pSoldier->bActionPoints >= ubMinAPCost) + { + // then look around for a worthy target (which sets BestStab.ubPossible) + CalcBestStab(pSoldier,&BestStab, FALSE); + if (BestStab.ubPossible) + { + // now we KNOW FOR SURE that we will do something (stab, at least) + NPCDoesAct(pSoldier); + ubBestAttackAction = AI_ACTION_KNIFE_MOVE; + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"NPC decided to move to stab"); + } + } - // copy the information on the best action selected into BestAttack struct - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"copy the information on the best action selected into BestAttack struct"); - switch (ubBestAttackAction) - { - case AI_ACTION_FIRE_GUN: - memcpy(&BestAttack,&BestShot,sizeof(BestAttack)); - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: best attack = firing a gun"); - break; - - case AI_ACTION_TOSS_PROJECTILE: - memcpy(&BestAttack,&BestThrow,sizeof(BestAttack)); - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: best attack = tossing a grenade"); - break; - - case AI_ACTION_THROW_KNIFE: - case AI_ACTION_KNIFE_MOVE: - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: best attack = stab with a knife"); - memcpy(&BestAttack,&BestStab,sizeof(BestAttack)); - break; - - default: - // set to empty - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: best attack = no good attack"); - memset( &BestAttack, 0, sizeof( BestAttack ) ); - break; - } - } - - // NB a desire of 4 or more is only achievable by brave/aggressive guys with high morale - if ( pSoldier->bActionPoints == pSoldier->bInitialActionPoints && ubBestAttackAction == AI_ACTION_FIRE_GUN && (pSoldier->bShock == 0) && (pSoldier->bLife >= pSoldier->bLifeMax / 2) && BestAttack.ubChanceToReallyHit < 30 && ( PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) > Weapon[ pSoldier->inv[ BestAttack.bWeaponIn ].usItem ].usRange / CELL_X_SIZE ) && RangeChangeDesire( pSoldier ) >= 4 ) - { - // okay, really got to wonder about this... could taking cover be an option? - if (ubCanMove && pSoldier->bOrders != STATIONARY && !gfHiddenInterrupt && - !(pSoldier->uiStatusFlags & SOLDIER_BOXER) ) - { - // make militia a bit more cautious - if ( ( (pSoldier->bTeam == MILITIA_TEAM) && (PreRandom( 20 ) > BestAttack.ubChanceToReallyHit) ) - || ( (pSoldier->bTeam != MILITIA_TEAM) && (PreRandom( 40 ) > BestAttack.ubChanceToReallyHit) ) ) - { - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"AI %d allowing cover check, chance to hit is only %d, at range %d", BestAttack.ubChanceToReallyHit, PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) ); - // maybe taking cover would be better! - fAllowCoverCheck = TRUE; - if ( PreRandom( 10 ) > BestAttack.ubChanceToReallyHit ) - { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: can't hit so screw the attack"); - // screw the attack! - ubBestAttackAction = AI_ACTION_NONE; + // if it was in his holster, swap it back into his holster for now + if (bWeaponIn != HANDPOS) + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: about to put knife away"); + RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY); + } } - } - } - - } + } - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"LOOK FOR SOME KIND OF COVER BETTER THAN WHAT WE HAVE NOW"); - //////////////////////////////////////////////////////////////////////////// - // LOOK FOR SOME KIND OF COVER BETTER THAN WHAT WE HAVE NOW - //////////////////////////////////////////////////////////////////////////// - // if soldier has enough APs left to move at least 1 square's worth, - // and either he can't attack any more, or his attack did wound someone - if ( (ubCanMove && !SkipCoverCheck && !gfHiddenInterrupt && - ((ubBestAttackAction == AI_ACTION_NONE) || pSoldier->bLastAttackHit) && - (pSoldier->bTeam != gbPlayerNum || pSoldier->fAIFlags & AI_RTP_OPTION_CAN_SEEK_COVER) && - !(pSoldier->uiStatusFlags & SOLDIER_BOXER) ) - || fAllowCoverCheck ) - { - sBestCover = FindBestNearbyCover(pSoldier,pSoldier->bAIMorale,&iCoverPercentBetter); - } + // copy the information on the best action selected into BestAttack struct + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"copy the information on the best action selected into BestAttack struct"); + switch (ubBestAttackAction) + { + case AI_ACTION_FIRE_GUN: + memcpy(&BestAttack,&BestShot,sizeof(BestAttack)); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: best attack = firing a gun"); + break; + + case AI_ACTION_TOSS_PROJECTILE: + memcpy(&BestAttack,&BestThrow,sizeof(BestAttack)); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: best attack = tossing a grenade"); + break; + + case AI_ACTION_THROW_KNIFE: + case AI_ACTION_KNIFE_MOVE: + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: best attack = stab with a knife"); + memcpy(&BestAttack,&BestStab,sizeof(BestAttack)); + break; + + default: + // set to empty + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: best attack = no good attack"); + memset( &BestAttack, 0, sizeof( BestAttack ) ); + break; + } + } + + // NB a desire of 4 or more is only achievable by brave/aggressive guys with high morale + if ( pSoldier->bActionPoints == pSoldier->bInitialActionPoints && ubBestAttackAction == AI_ACTION_FIRE_GUN && (pSoldier->bShock == 0) && (pSoldier->bLife >= pSoldier->bLifeMax / 2) && BestAttack.ubChanceToReallyHit < 30 && ( PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) > Weapon[ pSoldier->inv[ BestAttack.bWeaponIn ].usItem ].usRange / CELL_X_SIZE ) && RangeChangeDesire( pSoldier ) >= 4 ) + { + // okay, really got to wonder about this... could taking cover be an option? + if (ubCanMove && pSoldier->bOrders != STATIONARY && !gfHiddenInterrupt && + !(pSoldier->uiStatusFlags & SOLDIER_BOXER) ) + { + // make militia a bit more cautious + if ( ( (pSoldier->bTeam == MILITIA_TEAM) && (PreRandom( 20 ) > BestAttack.ubChanceToReallyHit) ) + || ( (pSoldier->bTeam != MILITIA_TEAM) && (PreRandom( 40 ) > BestAttack.ubChanceToReallyHit) ) ) + { + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"AI %d allowing cover check, chance to hit is only %d, at range %d", BestAttack.ubChanceToReallyHit, PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) ); + // maybe taking cover would be better! + fAllowCoverCheck = TRUE; + if ( PreRandom( 10 ) > BestAttack.ubChanceToReallyHit ) + { + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: can't hit so screw the attack"); + // screw the attack! + ubBestAttackAction = AI_ACTION_NONE; + } + } + } + + } + + + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"LOOK FOR SOME KIND OF COVER BETTER THAN WHAT WE HAVE NOW"); + //////////////////////////////////////////////////////////////////////////// + // LOOK FOR SOME KIND OF COVER BETTER THAN WHAT WE HAVE NOW + //////////////////////////////////////////////////////////////////////////// + + // if soldier has enough APs left to move at least 1 square's worth, + // and either he can't attack any more, or his attack did wound someone + if ( (ubCanMove && !SkipCoverCheck && !gfHiddenInterrupt && + ((ubBestAttackAction == AI_ACTION_NONE) || pSoldier->bLastAttackHit) && + (pSoldier->bTeam != gbPlayerNum || pSoldier->fAIFlags & AI_RTP_OPTION_CAN_SEEK_COVER) && + !(pSoldier->uiStatusFlags & SOLDIER_BOXER) ) + || fAllowCoverCheck ) + { + sBestCover = FindBestNearbyCover(pSoldier,pSoldier->bAIMorale,&iCoverPercentBetter); + } #ifdef RETREAT_TESTING sBestCover = NOWHERE; #endif - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: DECIDE BETWEEN ATTACKING AND DEFENDING (TAKING COVER)"); - ////////////////////////////////////////////////////////////////////////// - // IF NECESSARY, DECIDE BETWEEN ATTACKING AND DEFENDING (TAKING COVER) - ////////////////////////////////////////////////////////////////////////// + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: DECIDE BETWEEN ATTACKING AND DEFENDING (TAKING COVER)"); + ////////////////////////////////////////////////////////////////////////// + // IF NECESSARY, DECIDE BETWEEN ATTACKING AND DEFENDING (TAKING COVER) + ////////////////////////////////////////////////////////////////////////// - // if both are possible - if ((ubBestAttackAction != AI_ACTION_NONE) && (sBestCover != NOWHERE)) - { - // gotta compare their merits and select the more desirable option - iOffense = BestAttack.ubChanceToReallyHit; - iDefense = iCoverPercentBetter; + // if both are possible + if ((ubBestAttackAction != AI_ACTION_NONE) && (sBestCover != NOWHERE)) + { + // gotta compare their merits and select the more desirable option + iOffense = BestAttack.ubChanceToReallyHit; + iDefense = iCoverPercentBetter; - // based on how we feel about the situation, decide whether to attack first - switch (pSoldier->bAIMorale) - { - case MORALE_FEARLESS: - iOffense += iOffense / 2; // increase 50% - break; + // based on how we feel about the situation, decide whether to attack first + switch (pSoldier->bAIMorale) + { + case MORALE_FEARLESS: + iOffense += iOffense / 2; // increase 50% + break; - case MORALE_CONFIDENT: - iOffense += iOffense / 4; // increase 25% - break; + case MORALE_CONFIDENT: + iOffense += iOffense / 4; // increase 25% + break; - case MORALE_NORMAL: - break; + case MORALE_NORMAL: + break; - case MORALE_WORRIED: - iDefense += iDefense / 4; // increase 25% - break; + case MORALE_WORRIED: + iDefense += iDefense / 4; // increase 25% + break; - case MORALE_HOPELESS: - iDefense += iDefense / 2; // increase 50% - break; - } + case MORALE_HOPELESS: + iDefense += iDefense / 2; // increase 50% + break; + } - // smart guys more likely to try to stay alive, dolts more likely to shoot! - if (pSoldier->bWisdom >= 50) //Madd: reduced the wisdom required to want to live... - iDefense += 10; - else if (pSoldier->bWisdom < 30) - iDefense -= 10; + // smart guys more likely to try to stay alive, dolts more likely to shoot! + if (pSoldier->bWisdom >= 50) //Madd: reduced the wisdom required to want to live... + iDefense += 10; + else if (pSoldier->bWisdom < 30) + iDefense -= 10; - // some orders are more offensive, others more defensive - if (pSoldier->bOrders == SEEKENEMY) - iOffense += 10; - else if ((pSoldier->bOrders == STATIONARY) || (pSoldier->bOrders == ONGUARD) || pSoldier->bOrders == SNIPER ) - iDefense += 10; + // some orders are more offensive, others more defensive + if (pSoldier->bOrders == SEEKENEMY) + iOffense += 10; + else if ((pSoldier->bOrders == STATIONARY) || (pSoldier->bOrders == ONGUARD) || pSoldier->bOrders == SNIPER ) + iDefense += 10; - switch (pSoldier->bAttitude) - { - case DEFENSIVE: iDefense += 30; break; - case BRAVESOLO: iDefense -= 0; break; - case BRAVEAID: iDefense -= 0; break; - case CUNNINGSOLO: iDefense += 20; break; - case CUNNINGAID: iDefense += 20; break; - case AGGRESSIVE: iOffense += 10; break; - case ATTACKSLAYONLY:iOffense += 30; break; - } + switch (pSoldier->bAttitude) + { + case DEFENSIVE: iDefense += 30; break; + case BRAVESOLO: iDefense -= 0; break; + case BRAVEAID: iDefense -= 0; break; + case CUNNINGSOLO: iDefense += 20; break; + case CUNNINGAID: iDefense += 20; break; + case AGGRESSIVE: iOffense += 10; break; + case ATTACKSLAYONLY:iOffense += 30; break; + } #ifdef DEBUGDECISIONS - STR tempstr=""; + STR tempstr=""; sprintf( tempstr, "%s - CHOICE: iOffense = %d, iDefense = %d\n", - pSoldier->name,iOffense,iDefense); - DebugAI( tempstr ); + pSoldier->name,iOffense,iDefense); + DebugAI( tempstr ); #endif - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: if his defensive instincts win out, forget all about the attack"); - // if his defensive instincts win out, forget all about the attack - if (iDefense > iOffense) - ubBestAttackAction = AI_ACTION_NONE; - } + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: if his defensive instincts win out, forget all about the attack"); + // if his defensive instincts win out, forget all about the attack + if (iDefense > iOffense) + ubBestAttackAction = AI_ACTION_NONE; + } - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("DecideActionBlack: is attack still desirable? ubBestAttackAction = %d",ubBestAttackAction)); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("DecideActionBlack: is attack still desirable? ubBestAttackAction = %d",ubBestAttackAction)); // if attack is still desirable (meaning it's also preferred to taking cover) if (ubBestAttackAction != AI_ACTION_NONE) { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: attack is still desirable (meaning it's also preferred to taking cover)"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: attack is still desirable (meaning it's also preferred to taking cover)"); // if we wanted to be REALLY mean, we could look at chance to hit and decide whether // to shoot at the head... @@ -4214,8 +4225,8 @@ bCanAttack = FALSE; if (ubBestAttackAction == AI_ACTION_FIRE_GUN) { // Do we need to change stance? NB We'll have to ready our gun again - if ( !TANK( pSoldier ) && ( pSoldier->bActionPoints - (BestAttack.ubAPCost - BestAttack.ubAimTime) ) >= (AP_CROUCH + GetAPsToReadyWeapon( pSoldier, pSoldier->usAnimState ) ) ) - { + if ( !TANK( pSoldier ) && ( pSoldier->bActionPoints >= BestAttack.ubAPCost + AP_CROUCH + MinAPsToAttack( pSoldier, BestAttack.sTarget, ADDTURNCOST, 1 ) ) ) + { // since the AI considers shooting chance from standing primarily, if we are not // standing we should always consider a stance change if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_STAND ) @@ -4227,13 +4238,13 @@ bCanAttack = FALSE; iChance = 50; switch (pSoldier->bAttitude) { - case DEFENSIVE: iChance += 20; break; - case BRAVESOLO: iChance -= 10; break; - case BRAVEAID: iChance -= 10; break; - case CUNNINGSOLO: iChance += 10; break; - case CUNNINGAID: iChance += 10; break; - case AGGRESSIVE: iChance -= 20; break; - case ATTACKSLAYONLY: iChance -= 30; break; + case DEFENSIVE: iChance += 20; break; + case BRAVESOLO: iChance -= 10; break; + case BRAVEAID: iChance -= 10; break; + case CUNNINGSOLO: iChance += 10; break; + case CUNNINGAID: iChance += 10; break; + case AGGRESSIVE: iChance -= 20; break; + case ATTACKSLAYONLY: iChance -= 30; break; } } @@ -4252,33 +4263,37 @@ bCanAttack = FALSE; // we're not facing towards him, so turn first! pSoldier->usActionData = bDirection; - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - TURNS to face CLOSEST OPPONENT in direction %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); - #endif + AIPopMessage(tempstr); +#endif return(AI_ACTION_CHANGE_FACING); } -// pSoldier->usActionData = ubBestStance; + // pSoldier->usActionData = ubBestStance; // attack after we change stance // we don't just return here because we want to check whether to // burst first fChangeStanceFirst = TRUE; - // account for increased AP cost + // account for increased AP cost and having to re-ready weapon ubStanceCost = (UINT8) GetAPsToChangeStance( pSoldier, ubBestStance ); - if ( BestAttack.ubAPCost + ubStanceCost > pSoldier->bActionPoints ) + BestAttack.ubAPCost = MinAPsToAttack( pSoldier, BestAttack.sTarget, ADDTURNCOST, 1) + ubStanceCost; + + // Clip the aim time if necessary + if ( BestAttack.ubAPCost + BestAttack.ubAimTime > pSoldier->bActionPoints ) { // AP cost would balance (plus X, minus X) but aim time is reduced - BestAttack.ubAimTime -= (BestAttack.ubAimTime - ubStanceCost); + BestAttack.ubAimTime = pSoldier->bActionPoints - BestAttack.ubAPCost - ubStanceCost; + if (BestAttack.ubAimTime < 0 ) + { + // This is actually a logic error situation. The ChangeStance section is supposed + // to not make a shot impossible after changing stance. + BestAttack.ubPossible = 0; + } } - else - { - BestAttack.ubAPCost += GetAPsToChangeStance( pSoldier, ubBestStance ); - } - } } } @@ -4286,17 +4301,17 @@ bCanAttack = FALSE; ////////////////////////////////////////////////////////////////////////// // IF ENOUGH APs TO BURST, RANDOM CHANCE OF DOING SO ////////////////////////////////////////////////////////////////////////// - + if (IsGunBurstCapable( pSoldier, BestAttack.bWeaponIn, FALSE ) && !(Menptr[BestShot.ubOpponent].bLife < OKLIFE) && // don't burst at downed targets pSoldier->inv[BestAttack.bWeaponIn].ubGunShotsLeft > 1 && (pSoldier->bTeam != gbPlayerNum || pSoldier->bRTPCombat == RTP_COMBAT_AGGRESSIVE) ) { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: ENOUGH APs TO BURST, RANDOM CHANCE OF DOING SO"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: ENOUGH APs TO BURST, RANDOM CHANCE OF DOING SO"); ubBurstAPs = CalcAPsToBurst( CalcActionPoints( pSoldier ), &(pSoldier->inv[BestAttack.bWeaponIn]) ); - if (pSoldier->bActionPoints - (BestAttack.ubAPCost - BestAttack.ubAimTime) >= ubBurstAPs ) + if (pSoldier->bActionPoints >= BestAttack.ubAPCost + BestAttack.ubAimTime + ubBurstAPs ) { // Base chance of bursting is 25% if best shot was +0 aim, down to 8% at +4 if ( TANK( pSoldier ) ) @@ -4308,13 +4323,13 @@ bCanAttack = FALSE; iChance = (25 / max((BestAttack.ubAimTime + 1),1)); switch (pSoldier->bAttitude) { - case DEFENSIVE: iChance += -5; break; - case BRAVESOLO: iChance += 5; break; - case BRAVEAID: iChance += 5; break; - case CUNNINGSOLO: iChance += 0; break; - case CUNNINGAID: iChance += 0; break; - case AGGRESSIVE: iChance += 10; break; - case ATTACKSLAYONLY:iChance += 30; break; + case DEFENSIVE: iChance += -5; break; + case BRAVESOLO: iChance += 5; break; + case BRAVEAID: iChance += 5; break; + case CUNNINGSOLO: iChance += 0; break; + case CUNNINGAID: iChance += 0; break; + case AGGRESSIVE: iChance += 10; break; + case ATTACKSLAYONLY:iChance += 30; break; } if ( pSoldier->inv[BestAttack.bWeaponIn].ubGunShotsLeft > 50 ) @@ -4340,7 +4355,7 @@ bCanAttack = FALSE; if ( (INT32) PreRandom( 100 ) < iChance) { BestAttack.ubAimTime = BURSTING; - BestAttack.ubAPCost = BestAttack.ubAPCost - BestAttack.ubAimTime + CalcAPsToBurst( CalcActionPoints( pSoldier ), &(pSoldier->inv[HANDPOS]) ); + BestAttack.ubAPCost = BestAttack.ubAPCost + ubBurstAPs; // check for spread burst possibilities if (pSoldier->bAttitude != ATTACKSLAYONLY) { @@ -4355,36 +4370,36 @@ bCanAttack = FALSE; (( pSoldier->inv[BestAttack.bWeaponIn].ubGunShotsLeft > 1 && BestAttack.ubAimTime != BURSTING ) || Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto) ) { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: ENOUGH APs TO AUTOFIRE, RANDOM CHANCE OF DOING SO"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: ENOUGH APs TO AUTOFIRE, RANDOM CHANCE OF DOING SO"); pSoldier->bDoAutofire = 0; do { pSoldier->bDoAutofire++; ubBurstAPs = CalcAPsToAutofire( CalcActionPoints( pSoldier ), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire ); } - while( pSoldier->bActionPoints - (BestAttack.ubAPCost - BestAttack.ubAimTime) > ubBurstAPs && - pSoldier->inv[ pSoldier->ubAttackingHand ].ubGunShotsLeft >= pSoldier->bDoAutofire && - GetAutoPenalty(&pSoldier->inv[ BestAttack.bWeaponIn ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80); - - - + while( pSoldier->bActionPoints >= BestAttack.ubAPCost + ubBurstAPs && + pSoldier->inv[ pSoldier->ubAttackingHand ].ubGunShotsLeft >= pSoldier->bDoAutofire && + GetAutoPenalty(&pSoldier->inv[ BestAttack.bWeaponIn ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80); + + + pSoldier->bDoAutofire--; if (pSoldier->bDoAutofire > 0) { - ubBurstAPs = CalcAPsToAutofire( CalcActionPoints( pSoldier ), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire ); + ubBurstAPs = CalcAPsToAutofire( CalcActionPoints( pSoldier ), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire ); - if (pSoldier->bActionPoints - (BestAttack.ubAPCost - BestAttack.ubAimTime) >= ubBurstAPs ) - { - // Base chance of bursting is 25% if best shot was +0 aim, down to 8% at +4 - if ( TANK( pSoldier ) ) + if (pSoldier->bActionPoints >= BestAttack.ubAPCost + ubBurstAPs ) { - iChance = 100; - } - else - { - iChance = (100 / max((BestAttack.ubAimTime + 1),1)); - switch (pSoldier->bAttitude) + // Base chance of bursting is 25% if best shot was +0 aim, down to 8% at +4 + if ( TANK( pSoldier ) ) { + iChance = 100; + } + else + { + iChance = (100 / max((BestAttack.ubAimTime + 1),1)); + switch (pSoldier->bAttitude) + { case DEFENSIVE: iChance += -5; break; case BRAVESOLO: iChance += 5; break; case BRAVEAID: iChance += 5; break; @@ -4392,35 +4407,35 @@ bCanAttack = FALSE; case CUNNINGAID: iChance += 0; break; case AGGRESSIVE: iChance += 10; break; case ATTACKSLAYONLY:iChance += 30; break; - } + } - if ( pSoldier->inv[BestAttack.bWeaponIn].ubGunShotsLeft > 50 ) - iChance += 30; + if ( pSoldier->inv[BestAttack.bWeaponIn].ubGunShotsLeft > 50 ) + iChance += 30; - if ( bInGas ) - iChance += 50; //Madd: extra chance of going nuts and autofiring if stuck in gas + if ( bInGas ) + iChance += 50; //Madd: extra chance of going nuts and autofiring if stuck in gas - // increase chance based on proximity and difficulty of enemy - if ( PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) < 15 ) - { - DebugMsg(TOPIC_JA2AI,DBG_LEVEL_3,String("DecideActionBlack: check chance to autofire")); - iChance += ( 15 - PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) ) * ( 1 + SoldierDifficultyLevel( pSoldier ) ); - if ( pSoldier->bAttitude == ATTACKSLAYONLY ) + // increase chance based on proximity and difficulty of enemy + if ( PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) < 15 ) { - // increase it more! - iChance += 5 * ( 15 - PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) ); + DebugMsg(TOPIC_JA2AI,DBG_LEVEL_3,String("DecideActionBlack: check chance to autofire")); + iChance += ( 15 - PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) ) * ( 1 + SoldierDifficultyLevel( pSoldier ) ); + if ( pSoldier->bAttitude == ATTACKSLAYONLY ) + { + // increase it more! + iChance += 5 * ( 15 - PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) ); + } } } - } - if ((INT32) PreRandom( 100 ) < iChance || Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto) - { - BestAttack.ubAimTime = AUTOFIRING + pSoldier->bDoAutofire; - BestAttack.ubAPCost = BestAttack.ubAPCost - BestAttack.ubAimTime + CalcAPsToAutofire( CalcActionPoints( pSoldier ), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire ); + if ((INT32) PreRandom( 100 ) < iChance || Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto) + { + BestAttack.ubAimTime = AUTOFIRING + pSoldier->bDoAutofire; + BestAttack.ubAPCost = BestAttack.ubAPCost + CalcAPsToAutofire( CalcActionPoints( pSoldier ), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire ); + } } } - } else { pSoldier->bAimTime = 0; @@ -4451,12 +4466,12 @@ bCanAttack = FALSE; BestAttack.ubAimTime = AUTOFIRING; } - + /* else // defaults already set { - pSoldier->bAimTime = BestAttack.ubAimTime; - pSoldier->bDoBurst = 0; + pSoldier->bAimTime = BestAttack.ubAimTime; + pSoldier->bDoBurst = 0; } */ @@ -4475,19 +4490,19 @@ bCanAttack = FALSE; pSoldier->usNextActionData = BestAttack.sTarget; pSoldier->bNextTargetLevel = BestAttack.bTargetLevel; } - + } - + ////////////////////////////////////////////////////////////////////////// // OTHERWISE, JUST GO AHEAD & ATTACK! ////////////////////////////////////////////////////////////////////////// - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"OTHERWISE, JUST GO AHEAD & ATTACK!"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"OTHERWISE, JUST GO AHEAD & ATTACK!"); // swap weapon to hand if necessary if (BestAttack.bWeaponIn != HANDPOS) { - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: swap weapon into hand"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: swap weapon into hand"); RearrangePocket(pSoldier,HANDPOS,BestAttack.bWeaponIn,FOREVER); } @@ -4505,16 +4520,16 @@ bCanAttack = FALSE; pSoldier->usActionData = BestAttack.sTarget; pSoldier->bTargetLevel = BestAttack.bTargetLevel; - #ifdef DEBUGDECISIONS - STR tempstr=""; +#ifdef DEBUGDECISIONS + STR tempstr=""; sprintf( tempstr, - "%d(%s) %s %d(%s) at gridno %d (%d APs aim)\n", - pSoldier->ubID,pSoldier->name, - (ubBestAttackAction == AI_ACTION_FIRE_GUN)?"SHOOTS":((ubBestAttackAction == AI_ACTION_TOSS_PROJECTILE)?"TOSSES AT":"STABS"), - BestAttack.ubOpponent,pSoldier->name , - BestAttack.sTarget,BestAttack.ubAimTime ); - DebugAI( tempstr); - #endif + "%d(%s) %s %d(%s) at gridno %d (%d APs aim)\n", + pSoldier->ubID,pSoldier->name, + (ubBestAttackAction == AI_ACTION_FIRE_GUN)?"SHOOTS":((ubBestAttackAction == AI_ACTION_TOSS_PROJECTILE)?"TOSSES AT":"STABS"), + BestAttack.ubOpponent,pSoldier->name , + BestAttack.sTarget,BestAttack.ubAimTime ); + DebugAI( tempstr); +#endif DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("DecideActionBlack: Check for GL Bursts, is launcher capable? = %d, rtpcombat? = %d, bestattackaction = %d",IsGunBurstCapable( pSoldier, BestAttack.bWeaponIn, FALSE ),pSoldier->bRTPCombat,ubBestAttackAction )); @@ -4537,13 +4552,13 @@ bCanAttack = FALSE; iChance = 50; switch (pSoldier->bAttitude) { - case DEFENSIVE: iChance += -5; break; - case BRAVESOLO: iChance += 5; break; - case BRAVEAID: iChance += 5; break; - case CUNNINGSOLO: iChance += 0; break; - case CUNNINGAID: iChance += 0; break; - case AGGRESSIVE: iChance += 10; break; - case ATTACKSLAYONLY:iChance += 30; break; + case DEFENSIVE: iChance += -5; break; + case BRAVESOLO: iChance += 5; break; + case BRAVEAID: iChance += 5; break; + case CUNNINGSOLO: iChance += 0; break; + case CUNNINGAID: iChance += 0; break; + case AGGRESSIVE: iChance += 10; break; + case ATTACKSLAYONLY:iChance += 30; break; } // increase chance based on proximity and difficulty of enemy DebugMsg(TOPIC_JA2AI,DBG_LEVEL_3,String("DecideActionBlack: check chance to gl burst")); @@ -4569,7 +4584,7 @@ bCanAttack = FALSE; return(ubBestAttackAction); } - + } // end of tank AI @@ -4583,7 +4598,7 @@ bCanAttack = FALSE; { if ( ubCanMove ) { - sClosestOpponent = ClosestSeenOpponent(pSoldier, NULL, NULL); + sClosestOpponent = ClosestSeenOpponent(pSoldier, NULL, NULL); if ( sClosestOpponent != NOWHERE ) { // temporarily make boxer have orders of CLOSEPATROL rather than STATIONARY @@ -4604,92 +4619,92 @@ bCanAttack = FALSE; // otherwise do nothing return( AI_ACTION_NONE ); } - - //////////////////////////////////////////////////////////////////////////// - // IF A LOCATION WITH BETTER COVER IS AVAILABLE & REACHABLE, GO FOR IT! - //////////////////////////////////////////////////////////////////////////// - if (sBestCover != NOWHERE) - { + //////////////////////////////////////////////////////////////////////////// + // IF A LOCATION WITH BETTER COVER IS AVAILABLE & REACHABLE, GO FOR IT! + //////////////////////////////////////////////////////////////////////////// + + if (sBestCover != NOWHERE) + { #ifdef DEBUGDECISIONS STR tempstr=""; sprintf ( tempstr,"%s - TAKING COVER at gridno %d (%d%% better)\n", - pSoldier->name,sBestCover,iCoverPercentBetter); + pSoldier->name,sBestCover,iCoverPercentBetter); DebugAI( tempstr ) ; #endif - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"AI %d taking cover, morale %d, from %d to %d", pSoldier->ubID, pSoldier->bAIMorale, pSoldier->sGridNo, sBestCover ); - pSoldier->usActionData = sBestCover; + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"AI %d taking cover, morale %d, from %d to %d", pSoldier->ubID, pSoldier->bAIMorale, pSoldier->sGridNo, sBestCover ); + pSoldier->usActionData = sBestCover; - return(AI_ACTION_TAKE_COVER); + return(AI_ACTION_TAKE_COVER); } - //////////////////////////////////////////////////////////////////////////// - // IF THINGS ARE REALLY HOPELESS, OR UNARMED, TRY TO RUN AWAY - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // IF THINGS ARE REALLY HOPELESS, OR UNARMED, TRY TO RUN AWAY + //////////////////////////////////////////////////////////////////////////// - // if soldier has enough APs left to move at least 1 square's worth - if ( ubCanMove && (pSoldier->bTeam != gbPlayerNum || pSoldier->fAIFlags & AI_RTP_OPTION_CAN_RETREAT) ) - { - if ((pSoldier->bAIMorale == MORALE_HOPELESS) || !bCanAttack) - { - // look for best place to RUN AWAY to (farthest from the closest threat) - //pSoldier->usActionData = RunAway( pSoldier ); - pSoldier->usActionData = FindSpotMaxDistFromOpponents(pSoldier); + // if soldier has enough APs left to move at least 1 square's worth + if ( ubCanMove && (pSoldier->bTeam != gbPlayerNum || pSoldier->fAIFlags & AI_RTP_OPTION_CAN_RETREAT) ) + { + if ((pSoldier->bAIMorale == MORALE_HOPELESS) || !bCanAttack) + { + // look for best place to RUN AWAY to (farthest from the closest threat) + //pSoldier->usActionData = RunAway( pSoldier ); + pSoldier->usActionData = FindSpotMaxDistFromOpponents(pSoldier); - if (pSoldier->usActionData != NOWHERE) - { + if (pSoldier->usActionData != NOWHERE) + { #ifdef DEBUGDECISIONS sprintf(tempstr,"%s - RUNNING AWAY to grid %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); + AIPopMessage(tempstr); #endif - return(AI_ACTION_RUN_AWAY); - } - } - } + return(AI_ACTION_RUN_AWAY); + } + } + } - //////////////////////////////////////////////////////////////////////////// - // IF SPOTTERS HAVE BEEN CALLED FOR, AND WE HAVE SOME NEW SIGHTINGS, RADIO! - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // IF SPOTTERS HAVE BEEN CALLED FOR, AND WE HAVE SOME NEW SIGHTINGS, RADIO! + //////////////////////////////////////////////////////////////////////////// - // if we're a computer merc, and we have the action points remaining to RADIO - // (we never want NPCs to choose to radio if they would have to wait a turn) - // and we're not swimming in deep water, and somebody has called for spotters - // and we see the location of at least 2 opponents - if ((gTacticalStatus.ubSpottersCalledForBy != NOBODY) && (pSoldier->bActionPoints >= AP_RADIO) && - (pSoldier->bOppCnt > 1) && !fCivilian && - (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) && !bInDeepWater) - { - // base chance depends on how much new info we have to radio to the others - iChance = 25 * WhatIKnowThatPublicDont(pSoldier,TRUE); // just count them + // if we're a computer merc, and we have the action points remaining to RADIO + // (we never want NPCs to choose to radio if they would have to wait a turn) + // and we're not swimming in deep water, and somebody has called for spotters + // and we see the location of at least 2 opponents + if ((gTacticalStatus.ubSpottersCalledForBy != NOBODY) && (pSoldier->bActionPoints >= AP_RADIO) && + (pSoldier->bOppCnt > 1) && !fCivilian && + (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) && !bInDeepWater) + { + // base chance depends on how much new info we have to radio to the others + iChance = 25 * WhatIKnowThatPublicDont(pSoldier,TRUE); // just count them - // if I actually know something they don't - if (iChance) - { + // if I actually know something they don't + if (iChance) + { #ifdef DEBUGDECISIONS - AINumMessage("Chance to radio for SPOTTING = ",iChance); + AINumMessage("Chance to radio for SPOTTING = ",iChance); #endif - if ((INT16)PreRandom(100) < iChance) - { + if ((INT16)PreRandom(100) < iChance) + { #ifdef DEBUGDECISIONS - AINameMessage(pSoldier,"decides to radio a RED for SPOTTING!",1000); + AINameMessage(pSoldier,"decides to radio a RED for SPOTTING!",1000); #endif - return(AI_ACTION_RED_ALERT); - } - } - } + return(AI_ACTION_RED_ALERT); + } + } + } - //////////////////////////////////////////////////////////////////////////// - // CROUCH IF NOT CROUCHING ALREADY - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // CROUCH IF NOT CROUCHING ALREADY + //////////////////////////////////////////////////////////////////////////// - // if not in water and not already crouched, try to crouch down first - if (!gfTurnBasedAI || GetAPsToChangeStance( pSoldier, ANIM_CROUCH ) <= pSoldier->bActionPoints) - { + // if not in water and not already crouched, try to crouch down first + if (!gfTurnBasedAI || GetAPsToChangeStance( pSoldier, ANIM_CROUCH ) <= pSoldier->bActionPoints) + { if ( !fCivilian && !gfHiddenInterrupt && IsValidStance( pSoldier, ANIM_CROUCH ) ) { pSoldier->usActionData = StanceChange( pSoldier, BestAttack.ubAPCost ); @@ -4699,12 +4714,12 @@ bCanAttack = FALSE; { // we might want to turn before lying down! if ( (!gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints - GetAPsToChangeStance( pSoldier, (INT8) pSoldier->usActionData )) && - (((pSoldier->bAIMorale > MORALE_HOPELESS) || ubCanMove) && !AimingGun(pSoldier)) ) + (((pSoldier->bAIMorale > MORALE_HOPELESS) || ubCanMove) && !AimingGun(pSoldier)) ) { // determine the location of the known closest opponent // (don't care if he's conscious, don't care if he's reachable at all) - sClosestOpponent = ClosestSeenOpponent(pSoldier, NULL, NULL); + sClosestOpponent = ClosestSeenOpponent(pSoldier, NULL, NULL); // if we have a closest seen opponent if (sClosestOpponent != NOWHERE) { @@ -4719,10 +4734,10 @@ bCanAttack = FALSE; pSoldier->bNextAction = AI_ACTION_CHANGE_STANCE; pSoldier->usNextActionData = pSoldier->usActionData; pSoldier->usActionData = bDirection; - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - TURNS to face CLOSEST OPPONENT in direction %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); - #endif + AIPopMessage(tempstr); +#endif return(AI_ACTION_CHANGE_FACING); } else if ( (pSoldier->usActionData == ANIM_PRONE) && (InternalIsValidStance( pSoldier, bDirection, ANIM_CROUCH) ) ) @@ -4747,90 +4762,90 @@ bCanAttack = FALSE; } } - //////////////////////////////////////////////////////////////////////////// - // TURN TO FACE CLOSEST KNOWN OPPONENT (IF NOT FACING THERE ALREADY) - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // TURN TO FACE CLOSEST KNOWN OPPONENT (IF NOT FACING THERE ALREADY) + //////////////////////////////////////////////////////////////////////////// if (!gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints) { - // hopeless guys shouldn't waste their time this way, UNLESS they CAN move - // but chose not to to get this far (which probably means they're cornered) - // ALSO, don't bother turning if we're already aiming a gun - if ( !gfHiddenInterrupt && ((pSoldier->bAIMorale > MORALE_HOPELESS) || ubCanMove) && !AimingGun(pSoldier)) - { - // determine the location of the known closest opponent - // (don't care if he's conscious, don't care if he's reachable at all) - - - sClosestOpponent = ClosestSeenOpponent(pSoldier, NULL, NULL); - // if we have a closest reachable opponent - if (sClosestOpponent != NOWHERE) - { - bDirection = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent)); + // hopeless guys shouldn't waste their time this way, UNLESS they CAN move + // but chose not to to get this far (which probably means they're cornered) + // ALSO, don't bother turning if we're already aiming a gun + if ( !gfHiddenInterrupt && ((pSoldier->bAIMorale > MORALE_HOPELESS) || ubCanMove) && !AimingGun(pSoldier)) + { + // determine the location of the known closest opponent + // (don't care if he's conscious, don't care if he's reachable at all) - // if we're not facing towards him - if ( pSoldier->bDirection != bDirection && InternalIsValidStance( pSoldier, bDirection, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) ) - { - pSoldier->usActionData = bDirection; - #ifdef DEBUGDECISIONS - sprintf(tempstr,"%s - TURNS to face CLOSEST OPPONENT in direction %d",pSoldier->name,pSoldier->usActionData); - AIPopMessage(tempstr); - #endif + sClosestOpponent = ClosestSeenOpponent(pSoldier, NULL, NULL); + // if we have a closest reachable opponent + if (sClosestOpponent != NOWHERE) + { + bDirection = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent)); - return(AI_ACTION_CHANGE_FACING); - } - } - } + // if we're not facing towards him + if ( pSoldier->bDirection != bDirection && InternalIsValidStance( pSoldier, bDirection, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) ) + { + pSoldier->usActionData = bDirection; + +#ifdef DEBUGDECISIONS + sprintf(tempstr,"%s - TURNS to face CLOSEST OPPONENT in direction %d",pSoldier->name,pSoldier->usActionData); + AIPopMessage(tempstr); +#endif + + return(AI_ACTION_CHANGE_FACING); + } + } + } } - // if a militia has absofreaking nothing else to do, maybe they should radio in a report! + // if a militia has absofreaking nothing else to do, maybe they should radio in a report! - //////////////////////////////////////////////////////////////////////////// - // RADIO RED ALERT: determine %chance to call others and report contact - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // RADIO RED ALERT: determine %chance to call others and report contact + //////////////////////////////////////////////////////////////////////////// - if ( pSoldier->bTeam == MILITIA_TEAM && (pSoldier->bActionPoints >= AP_RADIO) && (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) ) - { + if ( pSoldier->bTeam == MILITIA_TEAM && (pSoldier->bActionPoints >= AP_RADIO) && (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) ) + { - // if there hasn't been an initial RED ALERT yet in this sector - if ( !(gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition) || NeedToRadioAboutPanicTrigger() ) - { // since I'm at STATUS RED, I obviously know we're being invaded! - DebugMsg(TOPIC_JA2AI,DBG_LEVEL_3,String("DecideActionBlack: check chance to radio contact")); - iChance = gbDiff[DIFF_RADIO_RED_ALERT][ SoldierDifficultyLevel( pSoldier ) ]; - } - else // subsequent radioing (only to update enemy positions, request help) - // base chance depends on how much new info we have to radio to the others - iChance = 10 * WhatIKnowThatPublicDont(pSoldier,FALSE); // use 10 * for RED alert + // if there hasn't been an initial RED ALERT yet in this sector + if ( !(gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition) || NeedToRadioAboutPanicTrigger() ) + { // since I'm at STATUS RED, I obviously know we're being invaded! + DebugMsg(TOPIC_JA2AI,DBG_LEVEL_3,String("DecideActionBlack: check chance to radio contact")); + iChance = gbDiff[DIFF_RADIO_RED_ALERT][ SoldierDifficultyLevel( pSoldier ) ]; + } + else // subsequent radioing (only to update enemy positions, request help) + // base chance depends on how much new info we have to radio to the others + iChance = 10 * WhatIKnowThatPublicDont(pSoldier,FALSE); // use 10 * for RED alert - // if I actually know something they don't and I ain't swimming (deep water) - if (iChance && !bInDeepWater) - { - // modify base chance according to orders - switch (pSoldier->bOrders) - { - case STATIONARY: iChance += 20; break; - case ONGUARD: iChance += 15; break; - case ONCALL: iChance += 10; break; - case CLOSEPATROL: break; - case RNDPTPATROL: - case POINTPATROL: iChance += -5; break; - case FARPATROL: iChance += -10; break; - case SEEKENEMY: iChance += -20; break; - case SNIPER: iChance += -10; break; - } + // if I actually know something they don't and I ain't swimming (deep water) + if (iChance && !bInDeepWater) + { + // modify base chance according to orders + switch (pSoldier->bOrders) + { + case STATIONARY: iChance += 20; break; + case ONGUARD: iChance += 15; break; + case ONCALL: iChance += 10; break; + case CLOSEPATROL: break; + case RNDPTPATROL: + case POINTPATROL: iChance += -5; break; + case FARPATROL: iChance += -10; break; + case SEEKENEMY: iChance += -20; break; + case SNIPER: iChance += -10; break; + } - // modify base chance according to attitude - switch (pSoldier->bAttitude) - { - case DEFENSIVE: iChance += 20; break; - case BRAVESOLO: iChance += -10; break; - case BRAVEAID: break; - case CUNNINGSOLO: iChance += -5; break; - case CUNNINGAID: break; - case AGGRESSIVE: iChance += -20; break; - case ATTACKSLAYONLY: iChance = 0; - } + // modify base chance according to attitude + switch (pSoldier->bAttitude) + { + case DEFENSIVE: iChance += 20; break; + case BRAVESOLO: iChance += -10; break; + case BRAVEAID: break; + case CUNNINGSOLO: iChance += -5; break; + case CUNNINGAID: break; + case AGGRESSIVE: iChance += -20; break; + case ATTACKSLAYONLY: iChance = 0; + } if (gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition) { @@ -4838,52 +4853,52 @@ bCanAttack = FALSE; } else { - // modify base chance according to morale - switch (pSoldier->bAIMorale) + // modify base chance according to morale + switch (pSoldier->bAIMorale) { - case MORALE_HOPELESS: iChance *= 3; break; - case MORALE_WORRIED: iChance *= 2; break; - case MORALE_NORMAL: break; - case MORALE_CONFIDENT: iChance /= 2; break; - case MORALE_FEARLESS: iChance /= 3; break; + case MORALE_HOPELESS: iChance *= 3; break; + case MORALE_WORRIED: iChance *= 2; break; + case MORALE_NORMAL: break; + case MORALE_CONFIDENT: iChance /= 2; break; + case MORALE_FEARLESS: iChance /= 3; break; } } - // reduce chance because we're in combat - iChance /= 2; + // reduce chance because we're in combat + iChance /= 2; #ifdef DEBUGDECISIONS - AINumMessage("Chance to radio RED alert = ",iChance); + AINumMessage("Chance to radio RED alert = ",iChance); #endif - if ((INT16) PreRandom(100) < iChance) - { + if ((INT16) PreRandom(100) < iChance) + { #ifdef DEBUGDECISIONS - AINameMessage(pSoldier,"decides to radio a RED alert!",1000); + AINameMessage(pSoldier,"decides to radio a RED alert!",1000); #endif - return(AI_ACTION_RED_ALERT); - } - } - } + return(AI_ACTION_RED_ALERT); + } + } + } - //////////////////////////////////////////////////////////////////////////// - // LEAVE THE SECTOR - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // LEAVE THE SECTOR + //////////////////////////////////////////////////////////////////////////// - // NOT IMPLEMENTED + // NOT IMPLEMENTED - //////////////////////////////////////////////////////////////////////////// - // DO NOTHING: Not enough points left to move, so save them for next turn - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// + // DO NOTHING: Not enough points left to move, so save them for next turn + //////////////////////////////////////////////////////////////////////////// #ifdef DEBUGDECISIONS - AINameMessage(pSoldier,"- DOES NOTHING (BLACK)",1000); + AINameMessage(pSoldier,"- DOES NOTHING (BLACK)",1000); #endif - // by default, if everything else fails, just stand in place and wait - pSoldier->usActionData = NOWHERE; - return(AI_ACTION_NONE); + // by default, if everything else fails, just stand in place and wait + pSoldier->usActionData = NOWHERE; + return(AI_ACTION_NONE); } @@ -4891,12 +4906,12 @@ INT8 DecideAction(SOLDIERTYPE *pSoldier) { DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideAction"); INT8 bAction=AI_ACTION_NONE; - #ifdef DEBUGDECISIONS - STR16 tempstr; - #endif +#ifdef DEBUGDECISIONS + STR16 tempstr; +#endif #ifdef AI_TIMING_TESTS - UINT32 uiStartTime, uiEndTime; + UINT32 uiStartTime, uiEndTime; #endif if ( pSoldier->bTeam != MILITIA_TEAM ) @@ -4914,129 +4929,129 @@ INT8 DecideAction(SOLDIERTYPE *pSoldier) SayQuoteFromAnyBodyInSector( QUOTE_WEARY_SLASH_SUSPUCIOUS ); } } - // turn off cautious flag + // turn off cautious flag pSoldier->fAIFlags &= (~AI_CAUTIOUS); //reset flank count - //NumMessage("DecideAction - Guy#",pSoldier->ubID); + //NumMessage("DecideAction - Guy#",pSoldier->ubID); - // if the NPC is being "ESCORTED" (seen civilians only for now) - if (pSoldier->bUnderEscort) - { + // if the NPC is being "ESCORTED" (seen civilians only for now) + if (pSoldier->bUnderEscort) + { #ifdef DEBUGDECISIONS - AIPopMessage("AlertStatus = ESCORT"); + AIPopMessage("AlertStatus = ESCORT"); #endif - //bAction = DecideActionEscort(pSoldier); - } - else // "normal" NPC AI - { - // if status over-ride is set, bypass RED/YELLOW and go directly to GREEN! - if ((pSoldier->bBypassToGreen) && (pSoldier->bAlertStatus < STATUS_BLACK)) - { - bAction = DecideActionGreen(pSoldier); - if ( !gfTurnBasedAI ) - { - // reset bypass now - pSoldier->bBypassToGreen = 0; - } - } - else - { - switch (pSoldier->bAlertStatus) - { - case STATUS_GREEN: - #ifdef DEBUGDECISIONS - AIPopMessage("AlertStatus = GREEN"); - #endif - #ifdef AI_TIMING_TESTS - uiStartTime = GetJA2Clock(); - #endif - bAction = DecideActionGreen(pSoldier); - #ifdef AI_TIMING_TESTS - uiEndTime = GetJA2Clock(); - guiGreenTimeTotal += (uiEndTime - uiStartTime); - guiGreenCounter++; - #endif - break; + //bAction = DecideActionEscort(pSoldier); + } + else // "normal" NPC AI + { + // if status over-ride is set, bypass RED/YELLOW and go directly to GREEN! + if ((pSoldier->bBypassToGreen) && (pSoldier->bAlertStatus < STATUS_BLACK)) + { + bAction = DecideActionGreen(pSoldier); + if ( !gfTurnBasedAI ) + { + // reset bypass now + pSoldier->bBypassToGreen = 0; + } + } + else + { + switch (pSoldier->bAlertStatus) + { + case STATUS_GREEN: +#ifdef DEBUGDECISIONS + AIPopMessage("AlertStatus = GREEN"); +#endif +#ifdef AI_TIMING_TESTS + uiStartTime = GetJA2Clock(); +#endif + bAction = DecideActionGreen(pSoldier); +#ifdef AI_TIMING_TESTS + uiEndTime = GetJA2Clock(); + guiGreenTimeTotal += (uiEndTime - uiStartTime); + guiGreenCounter++; +#endif + break; - case STATUS_YELLOW: - #ifdef DEBUGDECISIONS - AIPopMessage("AlertStatus = YELLOW"); - #endif - #ifdef AI_TIMING_TESTS - uiStartTime = GetJA2Clock(); - #endif - bAction = DecideActionYellow(pSoldier); - #ifdef AI_TIMING_TESTS - uiEndTime = GetJA2Clock(); - guiYellowTimeTotal += (uiEndTime - uiStartTime); - guiYellowCounter++; - #endif - break; + case STATUS_YELLOW: +#ifdef DEBUGDECISIONS + AIPopMessage("AlertStatus = YELLOW"); +#endif +#ifdef AI_TIMING_TESTS + uiStartTime = GetJA2Clock(); +#endif + bAction = DecideActionYellow(pSoldier); +#ifdef AI_TIMING_TESTS + uiEndTime = GetJA2Clock(); + guiYellowTimeTotal += (uiEndTime - uiStartTime); + guiYellowCounter++; +#endif + break; - case STATUS_RED: - #ifdef DEBUGDECISIONS - AIPopMessage("AlertStatus = RED"); - #endif - #ifdef AI_TIMING_TESTS - uiStartTime = GetJA2Clock(); - #endif - bAction = DecideActionRed(pSoldier,TRUE); - #ifdef AI_TIMING_TESTS - uiEndTime = GetJA2Clock(); - guiRedTimeTotal += (uiEndTime - uiStartTime); - guiRedCounter++; - #endif - break; + case STATUS_RED: +#ifdef DEBUGDECISIONS + AIPopMessage("AlertStatus = RED"); +#endif +#ifdef AI_TIMING_TESTS + uiStartTime = GetJA2Clock(); +#endif + bAction = DecideActionRed(pSoldier,TRUE); +#ifdef AI_TIMING_TESTS + uiEndTime = GetJA2Clock(); + guiRedTimeTotal += (uiEndTime - uiStartTime); + guiRedCounter++; +#endif + break; + + case STATUS_BLACK: +#ifdef DEBUGDECISIONS + AIPopMessage("AlertStatus = BLACK"); +#endif +#ifdef AI_TIMING_TESTS + uiStartTime = GetJA2Clock(); +#endif + bAction = DecideActionBlack(pSoldier); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("DecideActionBlack=%d",bAction)); +#ifdef AI_TIMING_TESTS + uiEndTime = GetJA2Clock(); + guiBlackTimeTotal += (uiEndTime - uiStartTime); + guiBlackCounter++; +#endif + break; + } + } + } - case STATUS_BLACK: - #ifdef DEBUGDECISIONS - AIPopMessage("AlertStatus = BLACK"); - #endif - #ifdef AI_TIMING_TESTS - uiStartTime = GetJA2Clock(); - #endif - bAction = DecideActionBlack(pSoldier); - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("DecideActionBlack=%d",bAction)); - #ifdef AI_TIMING_TESTS - uiEndTime = GetJA2Clock(); - guiBlackTimeTotal += (uiEndTime - uiStartTime); - guiBlackCounter++; - #endif - break; - } - } - } - #ifdef DEBUGDECISIONS sprintf( tempstr,"DecideAction: selected action %d, actionData %d\n\n",bAction,pSoldier->usActionData); DebugAI( tempstr ); #endif -DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideAction done"); - - return(bAction); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideAction done"); + + return(bAction); } INT8 DecideActionEscort(SOLDIERTYPE *pSoldier) { - #ifdef DEBUGDECISIONS - STR16 tempstr; - #endif - +#ifdef DEBUGDECISIONS + STR16 tempstr; +#endif + // if he has a place to go, and isn't already there... go! if (pSoldier->usActionData != NOWHERE && (pSoldier->sGridNo != pSoldier->usActionData)) { - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS sprintf(tempstr,"%s - ESCORTED NPC GOING to grid %d",pSoldier->name,pSoldier->usActionData); AIPopMessage(tempstr); - #endif +#endif return(AI_ACTION_ESCORTED_MOVE); - } + } else return(AI_ACTION_NONE); } @@ -5044,9 +5059,9 @@ INT8 DecideActionEscort(SOLDIERTYPE *pSoldier) void DecideAlertStatus( SOLDIERTYPE *pSoldier ) { - #ifdef DEBUGDECISIONS - STR16 tempstr; - #endif +#ifdef DEBUGDECISIONS + STR16 tempstr; +#endif INT8 bOldStatus; INT32 iDummy; BOOLEAN fClimbDummy,fReachableDummy; @@ -5079,53 +5094,53 @@ void DecideAlertStatus( SOLDIERTYPE *pSoldier ) { switch (bOldStatus) { - case STATUS_BLACK: - // then drop back to RED status + case STATUS_BLACK: + // then drop back to RED status + pSoldier->bAlertStatus = STATUS_RED; + break; + + case STATUS_RED: + // RED can never go back down below RED, only up to BLACK + break; + + case STATUS_YELLOW: + // if all enemies have been RED alerted, or we're under fire + if (!PTR_CIVILIAN && (gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition || pSoldier->bUnderFire)) + { pSoldier->bAlertStatus = STATUS_RED; - break; + } + else + { + // if we are NOT aware of any uninvestigated noises right now + // and we are not currently in the middle of an action + // (could still be on his way heading to investigate a noise!) + if ((MostImportantNoiseHeard(pSoldier,&iDummy,&fClimbDummy,&fReachableDummy) == NOWHERE) && !pSoldier->bActionInProgress) + { + // then drop back to GREEN status + pSoldier->bAlertStatus = STATUS_GREEN; + CheckForChangingOrders( pSoldier ); + } + } + break; - case STATUS_RED: - // RED can never go back down below RED, only up to BLACK - break; - - case STATUS_YELLOW: - // if all enemies have been RED alerted, or we're under fire - if (!PTR_CIVILIAN && (gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition || pSoldier->bUnderFire)) + case STATUS_GREEN: + // if all enemies have been RED alerted, or we're under fire + if (!PTR_CIVILIAN && (gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition || pSoldier->bUnderFire)) + { + pSoldier->bAlertStatus = STATUS_RED; + } + else + { + // if we ARE aware of any uninvestigated noises right now + if (MostImportantNoiseHeard(pSoldier,&iDummy,&fClimbDummy,&fReachableDummy) != NOWHERE) { - pSoldier->bAlertStatus = STATUS_RED; + // then move up to YELLOW status + pSoldier->bAlertStatus = STATUS_YELLOW; } - else - { - // if we are NOT aware of any uninvestigated noises right now - // and we are not currently in the middle of an action - // (could still be on his way heading to investigate a noise!) - if ((MostImportantNoiseHeard(pSoldier,&iDummy,&fClimbDummy,&fReachableDummy) == NOWHERE) && !pSoldier->bActionInProgress) - { - // then drop back to GREEN status - pSoldier->bAlertStatus = STATUS_GREEN; - CheckForChangingOrders( pSoldier ); - } - } - break; - - case STATUS_GREEN: - // if all enemies have been RED alerted, or we're under fire - if (!PTR_CIVILIAN && (gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition || pSoldier->bUnderFire)) - { - pSoldier->bAlertStatus = STATUS_RED; - } - else - { - // if we ARE aware of any uninvestigated noises right now - if (MostImportantNoiseHeard(pSoldier,&iDummy,&fClimbDummy,&fReachableDummy) != NOWHERE) - { - // then move up to YELLOW status - pSoldier->bAlertStatus = STATUS_YELLOW; - } - } - break; + } + break; } - // otherwise, RED stays RED, YELLOW stays YELLOW, GREEN stays GREEN + // otherwise, RED stays RED, YELLOW stays YELLOW, GREEN stays GREEN } } @@ -5140,38 +5155,38 @@ void DecideAlertStatus( SOLDIERTYPE *pSoldier ) { pSoldier->bAlertStatus = STATUS_RED; // enemy sector -/* + /* // wow, JA1 stuff... - // good guys all have a built-in, magic, "enemy detecting radar"... - if (Status.enemies) - pSoldier->bAlertStatus = STATUS_RED; // enemy sector - else - { - pSoldier->bAlertStatus = STATUS_GREEN; // secured sector + // good guys all have a built-in, magic, "enemy detecting radar"... + if (Status.enemies) + pSoldier->bAlertStatus = STATUS_RED; // enemy sector + else + { + pSoldier->bAlertStatus = STATUS_GREEN; // secured sector - // if he just dropped back from alert status, and it's a GUARD - if ((oldStatus >= STATUS_RED) && (pSoldier->manCategory == MAN_GUARD)) - { - if (pSoldier->whereIWas == NOWHERE) // not assigned to any trees - // FUTURE ENHANCEMENT: Look for unguarded trees with tappers - pSoldier->orders = ONCALL; - else // assigned to trees - // FUTURE ENHANCEMENT: If his tree is now tapperless, go ONCALL - pSoldier->orders = CLOSEPATROL; // go back to his tree area + // if he just dropped back from alert status, and it's a GUARD + if ((oldStatus >= STATUS_RED) && (pSoldier->manCategory == MAN_GUARD)) + { + if (pSoldier->whereIWas == NOWHERE) // not assigned to any trees + // FUTURE ENHANCEMENT: Look for unguarded trees with tappers + pSoldier->orders = ONCALL; + else // assigned to trees + // FUTURE ENHANCEMENT: If his tree is now tapperless, go ONCALL + pSoldier->orders = CLOSEPATROL; // go back to his tree area - // turn off any existing bypass to Green and its "hyper-activity" - pSoldier->bypassToGreen = FALSE; + // turn off any existing bypass to Green and its "hyper-activity" + pSoldier->bypassToGreen = FALSE; - // turn off the "inTheWay" flag, may have been set during TurnBased - pSoldier->inTheWay = FALSE; + // turn off the "inTheWay" flag, may have been set during TurnBased + pSoldier->inTheWay = FALSE; - // make the guard put his gun away if he has it drawn - HandleNoMoreTarget(pSoldier); - } + // make the guard put his gun away if he has it drawn + HandleNoMoreTarget(pSoldier); + } + } + */ + } } -*/ - } - } #endif if ( gTacticalStatus.bBoxingState == NOT_BOXING ) @@ -5194,12 +5209,12 @@ void DecideAlertStatus( SOLDIERTYPE *pSoldier ) CheckForChangingOrders(pSoldier); } - #ifdef DEBUGDECISIONS +#ifdef DEBUGDECISIONS // don't report status changes for human-controlled mercs sprintf(tempstr,"%s's Alert Status changed from %d to %d", - pSoldier->name,bOldStatus,pSoldier->bAlertStatus); - AIPopMessage(tempstr); - #endif + pSoldier->name,bOldStatus,pSoldier->bAlertStatus); + AIPopMessage(tempstr); +#endif } else // status didn't change diff --git a/TacticalAI/FindLocations.cpp b/TacticalAI/FindLocations.cpp index c0f51632..c1f6fd8c 100644 --- a/TacticalAI/FindLocations.cpp +++ b/TacticalAI/FindLocations.cpp @@ -23,6 +23,11 @@ #include "renderworld.h" #include "video.h" #endif + #include "worldman.h" + #include "strategicmap.h" + #include "environment.h" + #include "lighting.h" + #include "Buildings.h" #endif #include "PathAIDebug.h" diff --git a/TacticalAI/Knowledge.cpp b/TacticalAI/Knowledge.cpp index 590fc26c..8428da17 100644 --- a/TacticalAI/Knowledge.cpp +++ b/TacticalAI/Knowledge.cpp @@ -4,6 +4,12 @@ #include "ai.h" #include "AIInternals.h" #include "opplist.h" + #include "Soldier Profile.h" + #include "los.h" + #include "NPC.h" + #include "Quests.h" + #include "Render Fun.h" + #include "Soldier macros.h" #endif void CallAvailableEnemiesTo( INT16 sGridNo ) diff --git a/TacticalAI/Medical.cpp b/TacticalAI/Medical.cpp index e9527c2e..312d08e1 100644 --- a/TacticalAI/Medical.cpp +++ b/TacticalAI/Medical.cpp @@ -12,6 +12,9 @@ #include "overhead.h" #include "items.h" #include "Message.h" + #include "Buildings.h" + #include "worldman.h" + #include "Assignments.h" #endif extern BOOLEAN gfAutoBandageFailed; diff --git a/TacticalAI/Movement.cpp b/TacticalAI/Movement.cpp index d865e1e9..18541801 100644 --- a/TacticalAI/Movement.cpp +++ b/TacticalAI/Movement.cpp @@ -14,6 +14,8 @@ #include "strategic.h" #include "Strategic Pathing.h" #include "Soldier Control.h" + #include "Soldier macros.h" + #include "Render Fun.h" #endif // from strategic diff --git a/TacticalAI/NPC.cpp b/TacticalAI/NPC.cpp index 9cc246a5..ce7cc3ea 100644 --- a/TacticalAI/NPC.cpp +++ b/TacticalAI/NPC.cpp @@ -31,10 +31,22 @@ #include "Weapons.h" #include "meanwhile.h" -#ifdef JA2TESTVERSION - #include "Quest Debug System.h" - #include "QuestText.h" + #ifdef JA2TESTVERSION + #include "Quest Debug System.h" + #include "QuestText.h" #endif + + #include "SkillCheck.h" + #include "Render Fun.h" + #include "Text.h" + #include "finances.h" + #include "Arms Dealer Init.h" + #include "Interface Items.h" + #include "opplist.h" + #include "Animation Control.h" + #include "Scheduling.h" + #include "Tactical Save.h" + #include "Campaign Types.h" #endif #define NUM_CIVQUOTE_SECTORS 20 diff --git a/TacticalAI/PanicButtons.cpp b/TacticalAI/PanicButtons.cpp index 92942924..f35579ba 100644 --- a/TacticalAI/PanicButtons.cpp +++ b/TacticalAI/PanicButtons.cpp @@ -6,6 +6,10 @@ #include "pathai.h" #include "items.h" #include "World Items.h" + #include "strategicmap.h" + #include "Map Screen Interface Map.h" + #include "Soldier Profile.h" + #include "Quests.h" #endif #include "Queen Command.h" diff --git a/TacticalAI/Realtime.cpp b/TacticalAI/Realtime.cpp index ed2033b4..b8edbc25 100644 --- a/TacticalAI/Realtime.cpp +++ b/TacticalAI/Realtime.cpp @@ -12,6 +12,11 @@ #include "Soldier Profile Type.h" #include "Items.h" #include "Weapons.h" + #include "Soldier Macros.h" + #include "Soldier Profile.h" + #include "NPC.h" + #include "Render Fun.h" + #include "Quests.h" #endif INT8 RTPlayerDecideAction( SOLDIERTYPE * pSoldier ) diff --git a/TileEngine/Ambient Control.cpp b/TileEngine/Ambient Control.cpp index a3c048a4..af91da34 100644 --- a/TileEngine/Ambient Control.cpp +++ b/TileEngine/Ambient Control.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #else @@ -8,6 +10,9 @@ #include "environment.h" #include "Sound Control.h" #include "Game Events.h" + #include "Ambient Control.h" + #include "lighting.h" + #include "Random.h" #endif AMBIENTDATA_STRUCT gAmbData[ MAX_AMBIENT_SOUNDS ]; diff --git a/TileEngine/Buildings.cpp b/TileEngine/Buildings.cpp index 02add2fc..0c32b62b 100644 --- a/TileEngine/Buildings.cpp +++ b/TileEngine/Buildings.cpp @@ -11,6 +11,7 @@ #include "Render Fun.h" #include "Strategicmap.h" #include "Sys Globals.h" + #include "worldman.h" #endif #define ROOF_LOCATION_CHANCE 8 diff --git a/TileEngine/Exit Grids.cpp b/TileEngine/Exit Grids.cpp index c8b39b71..5913b450 100644 --- a/TileEngine/Exit Grids.cpp +++ b/TileEngine/Exit Grids.cpp @@ -20,6 +20,7 @@ #include "Sys Globals.h" #include "quests.h" #include "SaveLoadMap.h" + #include "Text.h" #endif BOOLEAN gfLoadingExitGrids = FALSE; diff --git a/TileEngine/Explosion Control.cpp b/TileEngine/Explosion Control.cpp index c61b6883..6a1a2291 100644 --- a/TileEngine/Explosion Control.cpp +++ b/TileEngine/Explosion Control.cpp @@ -1,60 +1,71 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS - #include "TileEngine All.h" - #include "end game.h" - #include "Morale.h" +#include "TileEngine All.h" +#include "end game.h" +#include "Morale.h" #else - #include - #include - #include "wcheck.h" - #include "stdlib.h" - #include "debug.h" - #include "soldier control.h" - #include "weapons.h" - #include "handle items.h" - #include "worlddef.h" - #include "worldman.h" - #include "rotting corpses.h" - #include "tile cache.h" - #include "isometric utils.h" - #include "animation control.h" - #include "utilities.h" - #include "game clock.h" - #include "soldier create.h" - #include "renderworld.h" - #include "soldier add.h" - #include "explosion control.h" - #include "tile animation.h" - #include "sound control.h" - #include "weapons.h" - #include "handle items.h" - #include "world items.h" - #include "structure wrap.h" - #include "tiledef.h" - #include "tiledat.h" - #include "interactive tiles.h" - #include "SaveLoadMap.h" - #include "Handle Doors.h" - #include "Message.h" - #include "Random.h" - #include "smokeeffects.h" - #include "handle ui.h" - #include "pathai.h" - #include "pits.h" - #include "campaign Types.h" - #include "strategicmap.h" - #include "strategic.h" - #include "Action Items.h" - #include "Soldier Profile.h" - #include "Quests.h" - #include "Interface Dialogue.h" - #include "LightEffects.h" - #include "AI.h" - #include "Soldier tile.h" - #include "lighting.h" - #include "Render Fun.h" - #include "Opplist.h" - #include "smell.h" - #include "GameSettings.h" +#include +#include +#include "wcheck.h" +#include "stdlib.h" +#include "debug.h" +#include "soldier control.h" +#include "weapons.h" +#include "handle items.h" +#include "worlddef.h" +#include "worldman.h" +#include "rotting corpses.h" +#include "tile cache.h" +#include "isometric utils.h" +#include "animation control.h" +#include "utilities.h" +#include "game clock.h" +#include "soldier create.h" +#include "renderworld.h" +#include "soldier add.h" +#include "explosion control.h" +#include "tile animation.h" +#include "sound control.h" +#include "weapons.h" +#include "handle items.h" +#include "world items.h" +#include "structure wrap.h" +#include "tiledef.h" +#include "tiledat.h" +#include "interactive tiles.h" +#include "SaveLoadMap.h" +#include "Handle Doors.h" +#include "Message.h" +#include "Random.h" +#include "smokeeffects.h" +#include "handle ui.h" +#include "pathai.h" +#include "pits.h" +#include "campaign Types.h" +#include "strategicmap.h" +#include "strategic.h" +#include "Action Items.h" +#include "Soldier Profile.h" +#include "Quests.h" +#include "Interface Dialogue.h" +#include "LightEffects.h" +#include "AI.h" +#include "Soldier tile.h" +#include "lighting.h" +#include "Render Fun.h" +#include "Opplist.h" +#include "smell.h" +#include "GameSettings.h" +#include "Interface.h" +#include "end game.h" +#include "WorldDat.h" +#include "environment.h" +#include "Buildings.h" +#include "Keys.h" +#include "Morale.h" +#include "fov.h" +#include "Map Information.h" #endif #include "Soldier Macros.h" @@ -68,7 +79,7 @@ BOOLEAN ExpAffect( INT16 sBombGridNo, INT16 sGridNo, UINT32 uiDist, UINT16 usIte // Flashbang effect on soldier UINT8 DetermineFlashbangEffect( SOLDIERTYPE *pSoldier, INT8 ubExplosionDir, BOOLEAN fInBuilding); -extern INT8 gbSAMGraphicList[ MAX_NUMBER_OF_SAMS ]; +extern INT8 gbSAMGraphicList[ MAX_NUMBER_OF_SAMS ]; extern void AddToShouldBecomeHostileOrSayQuoteList( UINT8 ubID ); extern void RecompileLocalMovementCostsForWall( INT16 sGridNo, UINT8 ubOrientation ); void FatigueCharacter( SOLDIERTYPE *pSoldier ); @@ -77,106 +88,106 @@ void FatigueCharacter( SOLDIERTYPE *pSoldier ); EXPLOSION_DATA gExpAniData[ NUM_EXP_TYPES ] = { -// Trans Damage Explosion Alternative Explosion Animation -// Key Key Sound Explosion Animation Speed -// Frame Frame ID SoundID Filename - {0, 0, EXPLOSION_1, EXPLOSION_ALT_BLAST_1, "", 0}, - {17, 3, EXPLOSION_1, EXPLOSION_ALT_BLAST_1, "TILECACHE\\ZGRAV_D.STI", 80}, - {28, 5, EXPLOSION_BLAST_2, NO_ALT_SOUND, "TILECACHE\\ZGRAV_C.STI", 80}, - {24, 5, EXPLOSION_BLAST_2, NO_ALT_SOUND, "TILECACHE\\ZGRAV_B.STI", 80}, - {1, 5, EXPLOSION_1, EXPLOSION_ALT_BLAST_1, "TILECACHE\\shckwave.STI", 20}, - {1, 18, AIR_ESCAPING_1, NO_ALT_SOUND, "TILECACHE\\WAT_EXP.STI", 80}, - {1, 18, AIR_ESCAPING_1, NO_ALT_SOUND, "TILECACHE\\TEAR_EXP.STI", 80}, - {1, 18, AIR_ESCAPING_1, NO_ALT_SOUND, "TILECACHE\\TEAR_EXP.STI", 80}, - {1, 18, AIR_ESCAPING_1, NO_ALT_SOUND, "TILECACHE\\MUST_EXP.STI", 80} + // Trans Damage Explosion Alternative Explosion Animation + // Key Key Sound Explosion Animation Speed + // Frame Frame ID SoundID Filename + {0, 0, EXPLOSION_1, EXPLOSION_ALT_BLAST_1, "", 0}, + {17, 3, EXPLOSION_1, EXPLOSION_ALT_BLAST_1, "TILECACHE\\ZGRAV_D.STI", 80}, + {28, 5, EXPLOSION_BLAST_2, NO_ALT_SOUND, "TILECACHE\\ZGRAV_C.STI", 80}, + {24, 5, EXPLOSION_BLAST_2, NO_ALT_SOUND, "TILECACHE\\ZGRAV_B.STI", 80}, + {1, 5, EXPLOSION_1, EXPLOSION_ALT_BLAST_1, "TILECACHE\\shckwave.STI", 20}, + {1, 18, AIR_ESCAPING_1, NO_ALT_SOUND, "TILECACHE\\WAT_EXP.STI", 80}, + {1, 18, AIR_ESCAPING_1, NO_ALT_SOUND, "TILECACHE\\TEAR_EXP.STI", 80}, + {1, 18, AIR_ESCAPING_1, NO_ALT_SOUND, "TILECACHE\\TEAR_EXP.STI", 80}, + {1, 18, AIR_ESCAPING_1, NO_ALT_SOUND, "TILECACHE\\MUST_EXP.STI", 80} }; -//UINT8 ubTransKeyFrame[ NUM_EXP_TYPES ] = +//UINT8 ubTransKeyFrame[ NUM_EXP_TYPES ] = //{ -// 0, -// 17, -// 28, -// 24, -// 1, -// 1, -// 1, -// 1, -// 1, +// 0, +// 17, +// 28, +// 24, +// 1, +// 1, +// 1, +// 1, +// 1, //}; // -//UINT8 ubDamageKeyFrame[ NUM_EXP_TYPES ] = +//UINT8 ubDamageKeyFrame[ NUM_EXP_TYPES ] = //{ -// 0, -// 3, -// 5, -// 5, -// 5, -// 18, -// 18, -// 18, -// 18, +// 0, +// 3, +// 5, +// 5, +// 5, +// 18, +// 18, +// 18, +// 18, //}; // // -//UINT32 uiExplosionSoundID[ NUM_EXP_TYPES ] = +//UINT32 uiExplosionSoundID[ NUM_EXP_TYPES ] = //{ -// EXPLOSION_1, -// EXPLOSION_1, -// EXPLOSION_BLAST_2, //LARGE -// EXPLOSION_BLAST_2, -// EXPLOSION_1, -// AIR_ESCAPING_1, -// AIR_ESCAPING_1, -// AIR_ESCAPING_1, -// AIR_ESCAPING_1, +// EXPLOSION_1, +// EXPLOSION_1, +// EXPLOSION_BLAST_2, //LARGE +// EXPLOSION_BLAST_2, +// EXPLOSION_1, +// AIR_ESCAPING_1, +// AIR_ESCAPING_1, +// AIR_ESCAPING_1, +// AIR_ESCAPING_1, //}; // // -//CHAR8 zBlastFilenames[][70] = +//CHAR8 zBlastFilenames[][70] = //{ -// "", -// "TILECACHE\\ZGRAV_D.STI", -// "TILECACHE\\ZGRAV_C.STI", -// "TILECACHE\\ZGRAV_B.STI", -// "TILECACHE\\shckwave.STI", -// "TILECACHE\\WAT_EXP.STI", -// "TILECACHE\\TEAR_EXP.STI", -// "TILECACHE\\TEAR_EXP.STI", -// "TILECACHE\\MUST_EXP.STI", +// "", +// "TILECACHE\\ZGRAV_D.STI", +// "TILECACHE\\ZGRAV_C.STI", +// "TILECACHE\\ZGRAV_B.STI", +// "TILECACHE\\shckwave.STI", +// "TILECACHE\\WAT_EXP.STI", +// "TILECACHE\\TEAR_EXP.STI", +// "TILECACHE\\TEAR_EXP.STI", +// "TILECACHE\\MUST_EXP.STI", //}; // -//CHAR8 sBlastSpeeds[] = -//{ -// 0, -// 80, -// 80, -// 80, -// 20, -// 80, -// 80, -// 80, -// 80, +//CHAR8 sBlastSpeeds[] = +//{ +// 0, +// 80, +// 80, +// 80, +// 20, +// 80, +// 80, +// 80, +// 80, //}; #define BOMB_QUEUE_DELAY (1000 + Random( 500 ) ) #define MAX_BOMB_QUEUE 40 -ExplosionQueueElement gExplosionQueue[MAX_BOMB_QUEUE]; -UINT8 gubElementsOnExplosionQueue = 0; -BOOLEAN gfExplosionQueueActive = FALSE; +ExplosionQueueElement gExplosionQueue[MAX_BOMB_QUEUE]; +UINT8 gubElementsOnExplosionQueue = 0; +BOOLEAN gfExplosionQueueActive = FALSE; -BOOLEAN gfExplosionQueueMayHaveChangedSight = FALSE; -UINT8 gubPersonToSetOffExplosions = NOBODY; +BOOLEAN gfExplosionQueueMayHaveChangedSight = FALSE; +UINT8 gubPersonToSetOffExplosions = NOBODY; -INT16 gsTempActionGridNo = NOWHERE; +INT16 gsTempActionGridNo = NOWHERE; extern UINT8 gubInterruptProvoker; -#define NUM_EXPLOSION_SLOTS 100 +#define NUM_EXPLOSION_SLOTS 100 // GLOBAL FOR SMOKE LISTING -EXPLOSIONTYPE gExplosionData[ NUM_EXPLOSION_SLOTS ]; -UINT32 guiNumExplosions = 0; +EXPLOSIONTYPE gExplosionData[ NUM_EXPLOSION_SLOTS ]; +UINT32 guiNumExplosions = 0; INT32 GetFreeExplosion( void ); @@ -221,7 +232,7 @@ void RecountExplosions( void ) // GENERATE EXPLOSION void InternalIgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT16 sGridNo, UINT16 usItem, BOOLEAN fLocate, INT8 bLevel ) { - EXPLOSION_PARAMS ExpParams ; + EXPLOSION_PARAMS ExpParams ; // Callahan start // Double check that we are using an explosive! @@ -252,33 +263,33 @@ void InternalIgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT16 } - gTacticalStatus.ubAttackBusyCount++; + // gTacticalStatus.ubAttackBusyCount++; DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Incrementing Attack: Explosion gone off, COunt now %d", gTacticalStatus.ubAttackBusyCount ) ); // OK, go on! - ExpParams.uiFlags = EXPLOSION_FLAG_USEABSPOS; - ExpParams.ubOwner = ubOwner; + ExpParams.uiFlags = EXPLOSION_FLAG_USEABSPOS; + ExpParams.ubOwner = ubOwner; // No explosive but an attacker with HE ammo. if ( !( Item[ usItem ].usItemClass & IC_EXPLOSV ) && ubOwner != NOBODY) { ExpParams.ubTypeID = (INT8)Explosive[AmmoTypes[MercPtrs[ubOwner]->inv[MercPtrs[ubOwner]->ubAttackingHand ].ubGunAmmoType].highExplosive].ubAnimationID; - // return; + // return; } else // just normal explosives should get here { ExpParams.ubTypeID = (INT8)Explosive[ Item[ usItem ].ubClassIndex ].ubAnimationID; - } + } // Callahan end - ExpParams.sX = sX; - ExpParams.sY = sY; - ExpParams.sZ = sZ; - ExpParams.sGridNo = sGridNo; - ExpParams.usItem = usItem; - ExpParams.fLocate = fLocate; - ExpParams.bLevel = bLevel; + ExpParams.sX = sX; + ExpParams.sY = sY; + ExpParams.sZ = sZ; + ExpParams.sGridNo = sGridNo; + ExpParams.usItem = usItem; + ExpParams.fLocate = fLocate; + ExpParams.bLevel = bLevel; GenerateExplosion( &ExpParams ); } @@ -294,28 +305,28 @@ void IgniteExplosion( UINT8 ubOwner, INT16 sX, INT16 sY, INT16 sZ, INT16 sGridNo void GenerateExplosion( EXPLOSION_PARAMS *pExpParams ) { - EXPLOSIONTYPE *pExplosion; - UINT32 uiFlags; - UINT8 ubOwner; - UINT8 ubTypeID; - INT16 sX; - INT16 sY; - INT16 sZ; - INT16 sGridNo; - UINT16 usItem; - INT32 iIndex; - INT8 bLevel; + EXPLOSIONTYPE *pExplosion; + UINT32 uiFlags; + UINT8 ubOwner; + UINT8 ubTypeID; + INT16 sX; + INT16 sY; + INT16 sZ; + INT16 sGridNo; + UINT16 usItem; + INT32 iIndex; + INT8 bLevel; // Assign param values - uiFlags = pExpParams->uiFlags; - ubOwner = pExpParams->ubOwner; - ubTypeID = pExpParams->ubTypeID; - sX = pExpParams->sX; - sY = pExpParams->sY; - sZ = pExpParams->sZ; - sGridNo = pExpParams->sGridNo; - usItem = pExpParams->usItem; - bLevel = pExpParams->bLevel; + uiFlags = pExpParams->uiFlags; + ubOwner = pExpParams->ubOwner; + ubTypeID = pExpParams->ubTypeID; + sX = pExpParams->sX; + sY = pExpParams->sY; + sZ = pExpParams->sZ; + sGridNo = pExpParams->sGridNo; + usItem = pExpParams->usItem; + bLevel = pExpParams->bLevel; { @@ -339,7 +350,7 @@ void GenerateExplosion( EXPLOSION_PARAMS *pExpParams ) GenerateExplosionFromExplosionPointer( pExplosion ); } - + // ATE: Locate to explosion.... if ( pExpParams->fLocate ) { @@ -350,36 +361,36 @@ void GenerateExplosion( EXPLOSION_PARAMS *pExpParams ) void GenerateExplosionFromExplosionPointer( EXPLOSIONTYPE *pExplosion ) { - UINT32 uiFlags; - UINT8 ubOwner; - UINT8 ubTypeID; - INT16 sX; - INT16 sY; - INT16 sZ; - INT16 sGridNo; - UINT16 usItem; - UINT8 ubTerrainType; - INT8 bLevel; - UINT32 uiSoundID; + UINT32 uiFlags; + UINT8 ubOwner; + UINT8 ubTypeID; + INT16 sX; + INT16 sY; + INT16 sZ; + INT16 sGridNo; + UINT16 usItem; + UINT8 ubTerrainType; + INT8 bLevel; + UINT32 uiSoundID; - ANITILE_PARAMS AniParams; + ANITILE_PARAMS AniParams; // Assign param values - uiFlags = pExplosion->Params.uiFlags; - ubOwner = pExplosion->Params.ubOwner; - ubTypeID = pExplosion->Params.ubTypeID; - sX = pExplosion->Params.sX; - sY = pExplosion->Params.sY; - sZ = pExplosion->Params.sZ; - sGridNo = pExplosion->Params.sGridNo; - usItem = pExplosion->Params.usItem; - bLevel = pExplosion->Params.bLevel; + uiFlags = pExplosion->Params.uiFlags; + ubOwner = pExplosion->Params.ubOwner; + ubTypeID = pExplosion->Params.ubTypeID; + sX = pExplosion->Params.sX; + sY = pExplosion->Params.sY; + sZ = pExplosion->Params.sZ; + sGridNo = pExplosion->Params.sGridNo; + usItem = pExplosion->Params.usItem; + bLevel = pExplosion->Params.bLevel; - // If Z value given is 0 and bLevel > 0, make z heigher - if ( sZ == 0 && bLevel > 0 ) - { - sZ = ROOF_LEVEL_HEIGHT; - } + // If Z value given is 0 and bLevel > 0, make z heigher + if ( sZ == 0 && bLevel > 0 ) + { + sZ = ROOF_LEVEL_HEIGHT; + } pExplosion->iLightID = -1; @@ -389,17 +400,17 @@ void GenerateExplosionFromExplosionPointer( EXPLOSIONTYPE *pExplosion ) // Setup explosion! memset( &AniParams, 0, sizeof( ANITILE_PARAMS ) ); - AniParams.sGridNo = sGridNo; - AniParams.ubLevelID = ANI_TOPMOST_LEVEL; - AniParams.sDelay = gExpAniData[ ubTypeID ].sBlastSpeed; // Lesh: edit this line - AniParams.sStartFrame = pExplosion->sCurrentFrame; - AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_EXPLOSION; + AniParams.sGridNo = sGridNo; + AniParams.ubLevelID = ANI_TOPMOST_LEVEL; + AniParams.sDelay = gExpAniData[ ubTypeID ].sBlastSpeed; // Lesh: edit this line + AniParams.sStartFrame = pExplosion->sCurrentFrame; + AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_EXPLOSION; if ( ubTerrainType == LOW_WATER || ubTerrainType == MED_WATER || ubTerrainType == DEEP_WATER ) { // Change type to water explosion... ubTypeID = WATER_BLAST; - AniParams.uiFlags |= ANITILE_ALWAYS_TRANSLUCENT; + AniParams.uiFlags |= ANITILE_ALWAYS_TRANSLUCENT; } @@ -410,29 +421,35 @@ void GenerateExplosionFromExplosionPointer( EXPLOSIONTYPE *pExplosion ) if ( uiFlags & EXPLOSION_FLAG_USEABSPOS ) { - AniParams.sX = sX; - AniParams.sY = sY; - AniParams.sZ = sZ; + AniParams.sX = sX; + AniParams.sY = sY; + AniParams.sZ = sZ; - //AniParams.uiFlags |= ANITILE_USEABSOLUTEPOS; + //AniParams.uiFlags |= ANITILE_USEABSOLUTEPOS; } - AniParams.ubKeyFrame1 = gExpAniData[ ubTypeID ].ubTransKeyFrame; // Lesh: edit this line - AniParams.uiKeyFrame1Code = ANI_KEYFRAME_BEGIN_TRANSLUCENCY; + AniParams.ubKeyFrame1 = gExpAniData[ ubTypeID ].ubTransKeyFrame; // Lesh: edit this line + AniParams.uiKeyFrame1Code = ANI_KEYFRAME_BEGIN_TRANSLUCENCY; if ( !( uiFlags & EXPLOSION_FLAG_DISPLAYONLY ) ) { - AniParams.ubKeyFrame2 = gExpAniData[ ubTypeID ].ubDamageKeyFrame; // Lesh: edit this line - AniParams.uiKeyFrame2Code = ANI_KEYFRAME_BEGIN_DAMAGE; + AniParams.ubKeyFrame2 = gExpAniData[ ubTypeID ].ubDamageKeyFrame; // Lesh: edit this line + AniParams.uiKeyFrame2Code = ANI_KEYFRAME_BEGIN_DAMAGE; } - AniParams.uiUserData = usItem; - AniParams.ubUserData2 = ubOwner; - AniParams.uiUserData3 = pExplosion->iID; + AniParams.uiUserData = usItem; + AniParams.ubUserData2 = ubOwner; + AniParams.uiUserData3 = pExplosion->iID; strcpy( AniParams.zCachedFile, gExpAniData[ ubTypeID ].zBlastFilename ); // Lesh: edit this line - CreateAnimationTile( &AniParams ); + // A little safety here, for just in case. If it fails to create an explosion tile, don't increase the attack busy count. + // But if it succeeds, do it here. Don't futz with the count in other locations when it can be centralized! + if (CreateAnimationTile( &AniParams ) ) + { + gTacticalStatus.ubAttackBusyCount++; + DebugAttackBusy( String( "Explosion started. Incrementing attack busy, now %d\n", gTacticalStatus.ubAttackBusyCount ) ); + } // set light source for flashbangs.... or... if ( pExplosion->Params.ubTypeID == FLASHBANG_EXP ) @@ -447,27 +464,27 @@ void GenerateExplosionFromExplosionPointer( EXPLOSIONTYPE *pExplosion ) pExplosion->iLightID = LightSpriteCreate("L-R04.LHT", 0 ); } - if( pExplosion->iLightID != -1 ) - { - LightSpritePower ( pExplosion->iLightID, TRUE ); - LightSpriteRoofStatus( pExplosion->iLightID, pExplosion->Params.bLevel ); - LightSpritePosition ( pExplosion->iLightID, (INT16)(sX/CELL_X_SIZE), (INT16)(sY/CELL_Y_SIZE) ); - } + if( pExplosion->iLightID != -1 ) + { + LightSpritePower ( pExplosion->iLightID, TRUE ); + LightSpriteRoofStatus( pExplosion->iLightID, pExplosion->Params.bLevel ); + LightSpritePosition ( pExplosion->iLightID, (INT16)(sX/CELL_X_SIZE), (INT16)(sY/CELL_Y_SIZE) ); + } - // Lesh: sound randomization - uiSoundID = gExpAniData[ ubTypeID ].uiExplosionSoundID; + // Lesh: sound randomization + uiSoundID = gExpAniData[ ubTypeID ].uiExplosionSoundID; - if ( gExpAniData[ ubTypeID ].uiAltExplosionSoundID != NO_ALT_SOUND ) - { - // Randomize - if ( Random( 2 ) == 0 ) - { - uiSoundID = gExpAniData[ ubTypeID ].uiAltExplosionSoundID; - } - } - // Lesh: sound randomization ends - - PlayJA2Sample( uiSoundID, RATE_11025, SoundVolume( HIGHVOLUME, sGridNo ), 1, SoundDir( sGridNo ) ); + if ( gExpAniData[ ubTypeID ].uiAltExplosionSoundID != NO_ALT_SOUND ) + { + // Randomize + if ( Random( 2 ) == 0 ) + { + uiSoundID = gExpAniData[ ubTypeID ].uiAltExplosionSoundID; + } + } + // Lesh: sound randomization ends + + PlayJA2Sample( uiSoundID, RATE_11025, SoundVolume( HIGHVOLUME, sGridNo ), 1, SoundDir( sGridNo ) ); } @@ -506,9 +523,9 @@ void HandleFencePartnerCheck( INT16 sStructGridNo ) { STRUCTURE *pFenceStructure, *pFenceBaseStructure; LEVELNODE *pFenceNode; - INT8 bFenceDestructionPartner = -1; - UINT32 uiFenceType; - UINT16 usTileIndex; + INT8 bFenceDestructionPartner = -1; + UINT32 uiFenceType; + UINT16 usTileIndex; pFenceStructure = FindStructure( sStructGridNo, STRUCTURE_FENCE ); @@ -529,7 +546,7 @@ void HandleFencePartnerCheck( INT16 sStructGridNo ) bFenceDestructionPartner = -1 * ( pFenceBaseStructure->pDBStructureRef->pDBStructure->bDestructionPartner ); // Get new index - GetTileIndexFromTypeSubIndex( uiFenceType, (INT8)( bFenceDestructionPartner ), &usTileIndex ); + GetTileIndexFromTypeSubIndex( uiFenceType, (INT8)( bFenceDestructionPartner ), &usTileIndex ); //Set a flag indicating that the following changes are to go the the maps, temp file ApplyMapChangesToMapTempFile( TRUE ); @@ -551,19 +568,19 @@ void HandleFencePartnerCheck( INT16 sStructGridNo ) BOOLEAN ExplosiveDamageStructureAtGridNo( STRUCTURE * pCurrent, STRUCTURE **ppNextCurrent, INT16 sGridNo, INT16 sWoundAmt, UINT32 uiDist, BOOLEAN *pfRecompileMovementCosts, BOOLEAN fOnlyWalls, BOOLEAN fSubSequentMultiTilesTransitionDamage, UINT8 ubOwner, INT8 bLevel ) { INT16 sX, sY; - STRUCTURE *pBase, *pWallStruct, *pAttached, *pAttachedBase; + STRUCTURE *pBase, *pWallStruct, *pAttached, *pAttachedBase; LEVELNODE *pNode = NULL, *pNewNode = NULL, *pAttachedNode; INT16 sNewGridNo, sStructGridNo; - INT16 sNewIndex, sSubIndex; + INT16 sNewIndex, sSubIndex; UINT16 usObjectIndex, usTileIndex; - UINT8 ubNumberOfTiles, ubLoop; - DB_STRUCTURE_TILE ** ppTile; - INT8 bDestructionPartner=-1; - INT8 bDamageReturnVal; - BOOLEAN fContinue; - UINT32 uiTileType; - INT16 sBaseGridNo; - BOOLEAN fExplosive; + UINT8 ubNumberOfTiles, ubLoop; + DB_STRUCTURE_TILE ** ppTile; + INT8 bDestructionPartner=-1; + INT8 bDamageReturnVal; + BOOLEAN fContinue; + UINT32 uiTileType; + INT16 sBaseGridNo; + BOOLEAN fExplosive; // ATE: Check for O3 statue for special damage.. // note we do this check every time explosion goes off in game, but it's @@ -607,7 +624,7 @@ BOOLEAN ExplosiveDamageStructureAtGridNo( STRUCTURE * pCurrent, STRUCTURE **ppNe fContinue = FALSE; pBase = FindBaseStructure( pCurrent ); - + sBaseGridNo = pBase->sGridNo; // if the structure is openable, destroy all items there @@ -621,14 +638,14 @@ BOOLEAN ExplosiveDamageStructureAtGridNo( STRUCTURE * pCurrent, STRUCTURE **ppNe // Get LEVELNODE for struct and remove! pNode = FindLevelNodeBasedOnStructure( pBase->sGridNo, pBase ); - // ATE: if we have completely destroyed a structure, - // and this structure should have a in-between explosion partner, - // make damage code 2 - which means only damaged - the normal explosion - // spreading will cause it do use the proper peices.. - if ( bDamageReturnVal == 1 && pBase->pDBStructureRef->pDBStructure->bDestructionPartner < 0 ) - { - bDamageReturnVal = 2; - } + // ATE: if we have completely destroyed a structure, + // and this structure should have a in-between explosion partner, + // make damage code 2 - which means only damaged - the normal explosion + // spreading will cause it do use the proper peices.. + if ( bDamageReturnVal == 1 && pBase->pDBStructureRef->pDBStructure->bDestructionPartner < 0 ) + { + bDamageReturnVal = 2; + } if ( bDamageReturnVal == 1 ) { @@ -664,7 +681,7 @@ BOOLEAN ExplosiveDamageStructureAtGridNo( STRUCTURE * pCurrent, STRUCTURE **ppNe if ( pBase->pDBStructureRef->pDBStructure->bDestructionPartner > 0 ) { // Alrighty add! - + // Add to every gridno structure is in ubNumberOfTiles = pBase->pDBStructureRef->pDBStructure->ubNumberOfTiles; ppTile = pBase->pDBStructureRef->ppTile; @@ -675,7 +692,7 @@ BOOLEAN ExplosiveDamageStructureAtGridNo( STRUCTURE * pCurrent, STRUCTURE **ppNe // debris... if ( bDestructionPartner > 39 ) { - GetTileIndexFromTypeSubIndex( SECONDEXPLDEBRIS, (INT8)( bDestructionPartner - 40 ), &usTileIndex ); + GetTileIndexFromTypeSubIndex( SECONDEXPLDEBRIS, (INT8)( bDestructionPartner - 40 ), &usTileIndex ); } else { @@ -690,7 +707,7 @@ BOOLEAN ExplosiveDamageStructureAtGridNo( STRUCTURE * pCurrent, STRUCTURE **ppNe sStructGridNo = pBase->sGridNo + ppTile[ubLoop]->sPosRelToBase; // there might be two structures in this tile, one on each level, but we just want to // delete one on each pass - + if ( !TypeRangeExistsInObjectLayer( sStructGridNo, FIRSTEXPLDEBRIS, SECONDEXPLDEBRIS, &usObjectIndex ) ) { //Set a flag indicating that the following changes are to go the the maps, temp file @@ -708,35 +725,35 @@ BOOLEAN ExplosiveDamageStructureAtGridNo( STRUCTURE * pCurrent, STRUCTURE **ppNe { switch( pCurrent->ubWallOrientation ) { - case OUTSIDE_TOP_LEFT: - case INSIDE_TOP_LEFT: + case OUTSIDE_TOP_LEFT: + case INSIDE_TOP_LEFT: - sStructGridNo = NewGridNo( pBase->sGridNo, DirectionInc( SOUTH ) ); - if ( !TypeRangeExistsInObjectLayer( sStructGridNo, FIRSTEXPLDEBRIS, SECONDEXPLDEBRIS, &usObjectIndex ) ) - { - //Set a flag indicating that the following changes are to go the the maps, temp file - ApplyMapChangesToMapTempFile( TRUE ); + sStructGridNo = NewGridNo( pBase->sGridNo, DirectionInc( SOUTH ) ); + if ( !TypeRangeExistsInObjectLayer( sStructGridNo, FIRSTEXPLDEBRIS, SECONDEXPLDEBRIS, &usObjectIndex ) ) + { + //Set a flag indicating that the following changes are to go the the maps, temp file + ApplyMapChangesToMapTempFile( TRUE ); - AddObjectToHead( sStructGridNo, (UINT16)(usTileIndex + Random( 3 ) ) ); + AddObjectToHead( sStructGridNo, (UINT16)(usTileIndex + Random( 3 ) ) ); - ApplyMapChangesToMapTempFile( FALSE ); - } - break; + ApplyMapChangesToMapTempFile( FALSE ); + } + break; - case OUTSIDE_TOP_RIGHT: - case INSIDE_TOP_RIGHT: + case OUTSIDE_TOP_RIGHT: + case INSIDE_TOP_RIGHT: - sStructGridNo = NewGridNo( pBase->sGridNo, DirectionInc( EAST ) ); - if ( !TypeRangeExistsInObjectLayer( sStructGridNo, FIRSTEXPLDEBRIS, SECONDEXPLDEBRIS, &usObjectIndex ) ) - { - //Set a flag indicating that the following changes are to go the the maps, temp file - ApplyMapChangesToMapTempFile( TRUE ); + sStructGridNo = NewGridNo( pBase->sGridNo, DirectionInc( EAST ) ); + if ( !TypeRangeExistsInObjectLayer( sStructGridNo, FIRSTEXPLDEBRIS, SECONDEXPLDEBRIS, &usObjectIndex ) ) + { + //Set a flag indicating that the following changes are to go the the maps, temp file + ApplyMapChangesToMapTempFile( TRUE ); - AddObjectToHead( sStructGridNo, (UINT16)(usTileIndex + Random( 3 ) ) ); + AddObjectToHead( sStructGridNo, (UINT16)(usTileIndex + Random( 3 ) ) ); - ApplyMapChangesToMapTempFile( FALSE ); - } - break; + ApplyMapChangesToMapTempFile( FALSE ); + } + break; } } } @@ -746,23 +763,23 @@ BOOLEAN ExplosiveDamageStructureAtGridNo( STRUCTURE * pCurrent, STRUCTURE **ppNe // walk along based on orientation switch( pCurrent->ubWallOrientation ) { - case OUTSIDE_TOP_RIGHT: - case INSIDE_TOP_RIGHT: + case OUTSIDE_TOP_RIGHT: + case INSIDE_TOP_RIGHT: - sStructGridNo = NewGridNo( pBase->sGridNo, DirectionInc( SOUTH ) ); - HandleFencePartnerCheck( sStructGridNo ); - sStructGridNo = NewGridNo( pBase->sGridNo, DirectionInc( NORTH ) ); - HandleFencePartnerCheck( sStructGridNo ); - break; + sStructGridNo = NewGridNo( pBase->sGridNo, DirectionInc( SOUTH ) ); + HandleFencePartnerCheck( sStructGridNo ); + sStructGridNo = NewGridNo( pBase->sGridNo, DirectionInc( NORTH ) ); + HandleFencePartnerCheck( sStructGridNo ); + break; - case OUTSIDE_TOP_LEFT: - case INSIDE_TOP_LEFT: + case OUTSIDE_TOP_LEFT: + case INSIDE_TOP_LEFT: - sStructGridNo = NewGridNo( pBase->sGridNo, DirectionInc( EAST ) ); - HandleFencePartnerCheck( sStructGridNo ); - sStructGridNo = NewGridNo( pBase->sGridNo, DirectionInc( WEST ) ); - HandleFencePartnerCheck( sStructGridNo ); - break; + sStructGridNo = NewGridNo( pBase->sGridNo, DirectionInc( EAST ) ); + HandleFencePartnerCheck( sStructGridNo ); + sStructGridNo = NewGridNo( pBase->sGridNo, DirectionInc( WEST ) ); + HandleFencePartnerCheck( sStructGridNo ); + break; } } @@ -782,298 +799,298 @@ BOOLEAN ExplosiveDamageStructureAtGridNo( STRUCTURE * pCurrent, STRUCTURE **ppNe // if found, replace! switch( pCurrent->ubWallOrientation ) { - case OUTSIDE_TOP_LEFT: - case INSIDE_TOP_LEFT: - - // Move WEST - sNewGridNo = NewGridNo( pBase->sGridNo, DirectionInc( WEST ) ); + case OUTSIDE_TOP_LEFT: + case INSIDE_TOP_LEFT: - pNewNode = GetWallLevelNodeAndStructOfSameOrientationAtGridno( sNewGridNo, pCurrent->ubWallOrientation, &pWallStruct ); + // Move WEST + sNewGridNo = NewGridNo( pBase->sGridNo, DirectionInc( WEST ) ); - if ( pNewNode != NULL ) + pNewNode = GetWallLevelNodeAndStructOfSameOrientationAtGridno( sNewGridNo, pCurrent->ubWallOrientation, &pWallStruct ); + + if ( pNewNode != NULL ) + { + if ( pWallStruct->fFlags & STRUCTURE_WALL ) { - if ( pWallStruct->fFlags & STRUCTURE_WALL ) + if ( pCurrent->ubWallOrientation == OUTSIDE_TOP_LEFT ) { - if ( pCurrent->ubWallOrientation == OUTSIDE_TOP_LEFT ) - { - sSubIndex = 48; - } - else - { - sSubIndex = 52; - } - - // Replace! - GetTileIndexFromTypeSubIndex( gTileDatabase[ pNewNode->usIndex ].fType, sSubIndex, (UINT16 *)&sNewIndex ); - - //Set a flag indicating that the following changes are to go the the maps temp file - ApplyMapChangesToMapTempFile( TRUE ); - - RemoveStructFromLevelNode( sNewGridNo, pNewNode ); - AddWallToStructLayer( sNewGridNo, sNewIndex, TRUE ); - - ApplyMapChangesToMapTempFile( FALSE ); - + sSubIndex = 48; } - } - - // Move in EAST - sNewGridNo = NewGridNo( pBase->sGridNo, DirectionInc( EAST ) ); - - pNewNode = GetWallLevelNodeAndStructOfSameOrientationAtGridno( sNewGridNo, pCurrent->ubWallOrientation, &pWallStruct ); - - if ( pNewNode != NULL ) - { - if ( pWallStruct->fFlags & STRUCTURE_WALL ) + else { - if ( pCurrent->ubWallOrientation == OUTSIDE_TOP_LEFT ) - { - sSubIndex = 49; - } - else - { - sSubIndex = 53; - } + sSubIndex = 52; + } - // Replace! - GetTileIndexFromTypeSubIndex( gTileDatabase[ pNewNode->usIndex ].fType, sSubIndex, (UINT16 *)&sNewIndex ); + // Replace! + GetTileIndexFromTypeSubIndex( gTileDatabase[ pNewNode->usIndex ].fType, sSubIndex, (UINT16 *)&sNewIndex ); - //Set a flag indicating that the following changes are to go the the maps, temp file + //Set a flag indicating that the following changes are to go the the maps temp file + ApplyMapChangesToMapTempFile( TRUE ); + + RemoveStructFromLevelNode( sNewGridNo, pNewNode ); + AddWallToStructLayer( sNewGridNo, sNewIndex, TRUE ); + + ApplyMapChangesToMapTempFile( FALSE ); + + } + } + + // Move in EAST + sNewGridNo = NewGridNo( pBase->sGridNo, DirectionInc( EAST ) ); + + pNewNode = GetWallLevelNodeAndStructOfSameOrientationAtGridno( sNewGridNo, pCurrent->ubWallOrientation, &pWallStruct ); + + if ( pNewNode != NULL ) + { + if ( pWallStruct->fFlags & STRUCTURE_WALL ) + { + if ( pCurrent->ubWallOrientation == OUTSIDE_TOP_LEFT ) + { + sSubIndex = 49; + } + else + { + sSubIndex = 53; + } + + // Replace! + GetTileIndexFromTypeSubIndex( gTileDatabase[ pNewNode->usIndex ].fType, sSubIndex, (UINT16 *)&sNewIndex ); + + //Set a flag indicating that the following changes are to go the the maps, temp file + ApplyMapChangesToMapTempFile( TRUE ); + + RemoveStructFromLevelNode( sNewGridNo, pNewNode ); + AddWallToStructLayer( sNewGridNo, sNewIndex, TRUE ); + + ApplyMapChangesToMapTempFile( FALSE ); + } + } + + // look for attached structures in same tile + sNewGridNo = pBase->sGridNo; + pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_LEFT_WALL ); + while (pAttached) + { + pAttachedBase = FindBaseStructure( pAttached ); + if (pAttachedBase) + { + // Remove the beast! + while ( (*ppNextCurrent) != NULL && (*ppNextCurrent)->usStructureID == pAttachedBase->usStructureID ) + { + // the next structure will also be deleted so we had better + // skip past it! + (*ppNextCurrent) = (*ppNextCurrent)->pNext; + } + + pAttachedNode = FindLevelNodeBasedOnStructure( pAttachedBase->sGridNo, pAttachedBase ); + if (pAttachedNode) + { ApplyMapChangesToMapTempFile( TRUE ); - - RemoveStructFromLevelNode( sNewGridNo, pNewNode ); - AddWallToStructLayer( sNewGridNo, sNewIndex, TRUE ); - + RemoveStructFromLevelNode( pAttachedBase->sGridNo, pAttachedNode ); ApplyMapChangesToMapTempFile( FALSE ); } + else + { + // error! +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); +#endif + break; + } } - - // look for attached structures in same tile - sNewGridNo = pBase->sGridNo; + else + { + // error! +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); +#endif + break; + } + // search for another, from the start of the list pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_LEFT_WALL ); - while (pAttached) - { - pAttachedBase = FindBaseStructure( pAttached ); - if (pAttachedBase) - { - // Remove the beast! - while ( (*ppNextCurrent) != NULL && (*ppNextCurrent)->usStructureID == pAttachedBase->usStructureID ) - { - // the next structure will also be deleted so we had better - // skip past it! - (*ppNextCurrent) = (*ppNextCurrent)->pNext; - } + } - pAttachedNode = FindLevelNodeBasedOnStructure( pAttachedBase->sGridNo, pAttachedBase ); - if (pAttachedNode) - { - ApplyMapChangesToMapTempFile( TRUE ); - RemoveStructFromLevelNode( pAttachedBase->sGridNo, pAttachedNode ); - ApplyMapChangesToMapTempFile( FALSE ); - } - else - { - // error! - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); - #endif - break; - } + // Move in SOUTH, looking for attached structures to remove + sNewGridNo = NewGridNo( pBase->sGridNo, DirectionInc( SOUTH ) ); + pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_LEFT_WALL ); + while (pAttached) + { + pAttachedBase = FindBaseStructure( pAttached ); + if (pAttachedBase) + { + pAttachedNode = FindLevelNodeBasedOnStructure( pAttachedBase->sGridNo, pAttachedBase ); + if (pAttachedNode) + { + ApplyMapChangesToMapTempFile( TRUE ); + RemoveStructFromLevelNode( pAttachedBase->sGridNo, pAttachedNode ); + ApplyMapChangesToMapTempFile( FALSE ); } else { // error! - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); - #endif +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); +#endif break; } - // search for another, from the start of the list - pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_LEFT_WALL ); } - - // Move in SOUTH, looking for attached structures to remove - sNewGridNo = NewGridNo( pBase->sGridNo, DirectionInc( SOUTH ) ); + else + { + // error! +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); +#endif + break; + } + // search for another, from the start of the list pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_LEFT_WALL ); - while (pAttached) + } + break; + + case OUTSIDE_TOP_RIGHT: + case INSIDE_TOP_RIGHT: + + // Move in NORTH + sNewGridNo = NewGridNo( pBase->sGridNo, DirectionInc( NORTH ) ); + + pNewNode = GetWallLevelNodeAndStructOfSameOrientationAtGridno( sNewGridNo, pCurrent->ubWallOrientation, &pWallStruct ); + + if ( pNewNode != NULL ) + { + if ( pWallStruct->fFlags & STRUCTURE_WALL ) { - pAttachedBase = FindBaseStructure( pAttached ); - if (pAttachedBase) + if ( pCurrent->ubWallOrientation == OUTSIDE_TOP_RIGHT ) { - pAttachedNode = FindLevelNodeBasedOnStructure( pAttachedBase->sGridNo, pAttachedBase ); - if (pAttachedNode) - { - ApplyMapChangesToMapTempFile( TRUE ); - RemoveStructFromLevelNode( pAttachedBase->sGridNo, pAttachedNode ); - ApplyMapChangesToMapTempFile( FALSE ); - } - else - { - // error! - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); - #endif - break; - } + sSubIndex = 51; } else { - // error! - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); - #endif - break; + sSubIndex = 55; } - // search for another, from the start of the list - pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_LEFT_WALL ); + + // Replace! + GetTileIndexFromTypeSubIndex( gTileDatabase[ pNewNode->usIndex ].fType, sSubIndex, (UINT16 *)&sNewIndex ); + + //Set a flag indicating that the following changes are to go the the maps, temp file + ApplyMapChangesToMapTempFile( TRUE ); + + RemoveStructFromLevelNode( sNewGridNo, pNewNode ); + AddWallToStructLayer( sNewGridNo, sNewIndex, TRUE ); + + ApplyMapChangesToMapTempFile( FALSE ); } - break; + } - case OUTSIDE_TOP_RIGHT: - case INSIDE_TOP_RIGHT: + // Move in SOUTH + sNewGridNo = NewGridNo( pBase->sGridNo, DirectionInc( SOUTH ) ); - // Move in NORTH - sNewGridNo = NewGridNo( pBase->sGridNo, DirectionInc( NORTH ) ); + pNewNode = GetWallLevelNodeAndStructOfSameOrientationAtGridno( sNewGridNo, pCurrent->ubWallOrientation, &pWallStruct ); - pNewNode = GetWallLevelNodeAndStructOfSameOrientationAtGridno( sNewGridNo, pCurrent->ubWallOrientation, &pWallStruct ); - - if ( pNewNode != NULL ) + if ( pNewNode != NULL ) + { + if ( pWallStruct->fFlags & STRUCTURE_WALL ) { - if ( pWallStruct->fFlags & STRUCTURE_WALL ) + if ( pCurrent->ubWallOrientation == OUTSIDE_TOP_RIGHT ) { - if ( pCurrent->ubWallOrientation == OUTSIDE_TOP_RIGHT ) - { - sSubIndex = 51; - } - else - { - sSubIndex = 55; - } + sSubIndex = 50; + } + else + { + sSubIndex = 54; + } - // Replace! - GetTileIndexFromTypeSubIndex( gTileDatabase[ pNewNode->usIndex ].fType, sSubIndex, (UINT16 *)&sNewIndex ); + // Replace! + GetTileIndexFromTypeSubIndex( gTileDatabase[ pNewNode->usIndex ].fType, sSubIndex, (UINT16 *)&sNewIndex ); - //Set a flag indicating that the following changes are to go the the maps, temp file + //Set a flag indicating that the following changes are to go the the maps, temp file + ApplyMapChangesToMapTempFile( TRUE ); + + RemoveStructFromLevelNode( sNewGridNo, pNewNode ); + AddWallToStructLayer( sNewGridNo, sNewIndex, TRUE ); + + ApplyMapChangesToMapTempFile( FALSE ); + } + } + + // looking for attached structures to remove in base tile + sNewGridNo = pBase->sGridNo; + pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_RIGHT_WALL ); + while (pAttached) + { + pAttachedBase = FindBaseStructure( pAttached ); + if (pAttachedBase) + { + pAttachedNode = FindLevelNodeBasedOnStructure( pAttachedBase->sGridNo, pAttachedBase ); + if (pAttachedNode) + { ApplyMapChangesToMapTempFile( TRUE ); - - RemoveStructFromLevelNode( sNewGridNo, pNewNode ); - AddWallToStructLayer( sNewGridNo, sNewIndex, TRUE ); - + RemoveStructFromLevelNode( pAttachedBase->sGridNo, pAttachedNode ); ApplyMapChangesToMapTempFile( FALSE ); } - } - - // Move in SOUTH - sNewGridNo = NewGridNo( pBase->sGridNo, DirectionInc( SOUTH ) ); - - pNewNode = GetWallLevelNodeAndStructOfSameOrientationAtGridno( sNewGridNo, pCurrent->ubWallOrientation, &pWallStruct ); - - if ( pNewNode != NULL ) - { - if ( pWallStruct->fFlags & STRUCTURE_WALL ) + else { - if ( pCurrent->ubWallOrientation == OUTSIDE_TOP_RIGHT ) - { - sSubIndex = 50; - } - else - { - sSubIndex = 54; - } + // error! +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); +#endif + break; + } + } + else + { + // error! +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); +#endif + break; + } + // search for another, from the start of the list + pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_RIGHT_WALL ); + } - // Replace! - GetTileIndexFromTypeSubIndex( gTileDatabase[ pNewNode->usIndex ].fType, sSubIndex, (UINT16 *)&sNewIndex ); - - //Set a flag indicating that the following changes are to go the the maps, temp file + // Move in EAST, looking for attached structures to remove + sNewGridNo = NewGridNo( pBase->sGridNo, DirectionInc( EAST ) ); + pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_RIGHT_WALL ); + while (pAttached) + { + pAttachedBase = FindBaseStructure( pAttached ); + if (pAttachedBase) + { + pAttachedNode = FindLevelNodeBasedOnStructure( pAttachedBase->sGridNo, pAttachedBase ); + if (pAttachedNode) + { ApplyMapChangesToMapTempFile( TRUE ); - - RemoveStructFromLevelNode( sNewGridNo, pNewNode ); - AddWallToStructLayer( sNewGridNo, sNewIndex, TRUE ); - + RemoveStructFromLevelNode( pAttachedBase->sGridNo, pAttachedNode ); ApplyMapChangesToMapTempFile( FALSE ); } - } - - // looking for attached structures to remove in base tile - sNewGridNo = pBase->sGridNo; - pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_RIGHT_WALL ); - while (pAttached) - { - pAttachedBase = FindBaseStructure( pAttached ); - if (pAttachedBase) - { - pAttachedNode = FindLevelNodeBasedOnStructure( pAttachedBase->sGridNo, pAttachedBase ); - if (pAttachedNode) - { - ApplyMapChangesToMapTempFile( TRUE ); - RemoveStructFromLevelNode( pAttachedBase->sGridNo, pAttachedNode ); - ApplyMapChangesToMapTempFile( FALSE ); - } - else - { - // error! - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); - #endif - break; - } - } else { // error! - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); - #endif +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); +#endif break; } - // search for another, from the start of the list - pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_RIGHT_WALL ); } - - // Move in EAST, looking for attached structures to remove - sNewGridNo = NewGridNo( pBase->sGridNo, DirectionInc( EAST ) ); - pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_RIGHT_WALL ); - while (pAttached) + else { - pAttachedBase = FindBaseStructure( pAttached ); - if (pAttachedBase) - { - pAttachedNode = FindLevelNodeBasedOnStructure( pAttachedBase->sGridNo, pAttachedBase ); - if (pAttachedNode) - { - ApplyMapChangesToMapTempFile( TRUE ); - RemoveStructFromLevelNode( pAttachedBase->sGridNo, pAttachedNode ); - ApplyMapChangesToMapTempFile( FALSE ); - } - else - { - // error! - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); - #endif - break; - } - } - else - { - // error! - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); - #endif - break; - } - // search for another, from the start of the list - pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_RIGHT_WALL ); + // error! +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Problems removing structure attached to wall at %d", sNewGridNo ); +#endif + break; } + // search for another, from the start of the list + pAttached = FindStructure( sNewGridNo, STRUCTURE_ON_RIGHT_WALL ); + } - break; + break; } // CJC, Sept 16: if we destroy any wall of the brothel, make Kingpin's men hostile! if ( gWorldSectorX == 5 && gWorldSectorY == MAP_ROW_C && gbWorldSectorZ == 0 ) { - UINT8 ubRoom; - BOOLEAN fInRoom; + UINT8 ubRoom; + BOOLEAN fInRoom; fInRoom = InARoom( sGridNo, &ubRoom ); if ( !fInRoom ) @@ -1137,7 +1154,7 @@ BOOLEAN ExplosiveDamageStructureAtGridNo( STRUCTURE * pCurrent, STRUCTURE **ppNe { // We have a levelnode... // Get new index for new grpahic.... - GetTileIndexFromTypeSubIndex( uiTileType, bDestructionPartner, &usTileIndex ); + GetTileIndexFromTypeSubIndex( uiTileType, bDestructionPartner, &usTileIndex ); ApplyMapChangesToMapTempFile( TRUE ); @@ -1180,14 +1197,14 @@ BOOLEAN ExplosiveDamageStructureAtGridNo( STRUCTURE * pCurrent, STRUCTURE **ppNe return( FALSE ); } } - + // 2 is NO DAMAGE return( 2 ); } } return( 1 ); - + } STRUCTURE *gStruct; @@ -1195,22 +1212,22 @@ STRUCTURE *gStruct; // Lesh: somewhere here once I got CTD when militia stepped on mine in cambria sam void ExplosiveDamageGridNo( INT16 sGridNo, INT16 sWoundAmt, UINT32 uiDist, BOOLEAN *pfRecompileMovementCosts, BOOLEAN fOnlyWalls, INT8 bMultiStructSpecialFlag, BOOLEAN fSubSequentMultiTilesTransitionDamage, UINT8 ubOwner, INT8 bLevel ) { - STRUCTURE * pCurrent, *pNextCurrent, *pStructure; - STRUCTURE * pBaseStructure; - INT16 sDesiredLevel; - DB_STRUCTURE_TILE **ppTile; - UINT8 ubLoop, ubLoop2; - INT16 sNewGridNo, sNewGridNo2, sBaseGridNo; - BOOLEAN fToBreak = FALSE; - BOOLEAN fMultiStructure = FALSE; - UINT8 ubNumberOfTiles; - BOOLEAN fMultiStructSpecialFlag = FALSE; - BOOLEAN fExplodeDamageReturn = FALSE; + STRUCTURE * pCurrent, *pNextCurrent, *pStructure; + STRUCTURE * pBaseStructure; + INT16 sDesiredLevel; + DB_STRUCTURE_TILE **ppTile; + UINT8 ubLoop, ubLoop2; + INT16 sNewGridNo, sNewGridNo2, sBaseGridNo; + BOOLEAN fToBreak = FALSE; + BOOLEAN fMultiStructure = FALSE; + UINT8 ubNumberOfTiles; + BOOLEAN fMultiStructSpecialFlag = FALSE; + BOOLEAN fExplodeDamageReturn = FALSE; // Based on distance away, damage any struct at this gridno // OK, loop through structures and damage! - pCurrent = gpWorldLevelData[ sGridNo ].pStructureHead; - sDesiredLevel = STRUCTURE_ON_GROUND; + pCurrent = gpWorldLevelData[ sGridNo ].pStructureHead; + sDesiredLevel = STRUCTURE_ON_GROUND; // This code gets a little hairy because // (1) we might need to destroy the currently-examined structure @@ -1292,7 +1309,7 @@ void ExplosiveDamageGridNo( INT16 sGridNo, INT16 sWoundAmt, UINT32 uiDist, BOOLE for ( ubLoop = BASE_TILE; ubLoop < ubNumberOfTiles; ubLoop++) { sNewGridNo = sBaseGridNo + ppTile[ubLoop]->sPosRelToBase; - + // look in adjacent tiles for ( ubLoop2 = 0; ubLoop2 < NUM_WORLD_DIRECTIONS; ubLoop2++ ) { @@ -1346,209 +1363,210 @@ void ExplosiveDamageGridNo( INT16 sGridNo, INT16 sWoundAmt, UINT32 uiDist, BOOLE BOOLEAN DamageSoldierFromBlast( UINT8 ubPerson, UINT8 ubOwner, INT16 sBombGridNo, INT16 sWoundAmt, INT16 sBreathAmt, UINT32 uiDist, UINT16 usItem, INT16 sSubsequent ) { - SOLDIERTYPE *pSoldier; - INT16 sNewWoundAmt = 0; - UINT8 ubDirection; - UINT8 ubSpecial = 0; - BOOLEAN fInBuilding = InBuilding(sBombGridNo); - BOOLEAN fFlashbang = Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_FLASHBANG; - UINT16 usHalfExplosionRadius; + SOLDIERTYPE *pSoldier; + INT16 sNewWoundAmt = 0; + UINT8 ubDirection; + UINT8 ubSpecial = 0; + BOOLEAN fInBuilding = InBuilding(sBombGridNo); + BOOLEAN fFlashbang = Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_FLASHBANG; + UINT16 usHalfExplosionRadius; - pSoldier = MercPtrs[ ubPerson ]; // someone is here, and they're gonna get hurt + pSoldier = MercPtrs[ ubPerson ]; // someone is here, and they're gonna get hurt - if (!pSoldier->bActive || !pSoldier->bInSector || !pSoldier->bLife ) - return( FALSE ); + if (!pSoldier->bActive || !pSoldier->bInSector || !pSoldier->bLife ) + return( FALSE ); - if ( pSoldier->ubMiscSoldierFlags & SOLDIER_MISC_HURT_BY_EXPLOSION ) - { + if ( pSoldier->ubMiscSoldierFlags & SOLDIER_MISC_HURT_BY_EXPLOSION ) + { // don't want to damage the guy twice return( FALSE ); - } + } - // Lesh: if flashbang - // check if soldier is outdoor and situated farther that half explosion radius and not underground - usHalfExplosionRadius = Explosive[Item[usItem].ubClassIndex].ubRadius / 2; - if ( fFlashbang && !gbWorldSectorZ && !fInBuilding && (UINT16)uiDist > usHalfExplosionRadius ) - { + // Lesh: if flashbang + // check if soldier is outdoor and situated farther that half explosion radius and not underground + usHalfExplosionRadius = Explosive[Item[usItem].ubClassIndex].ubRadius / 2; + if ( fFlashbang && !gbWorldSectorZ && !fInBuilding && (UINT16)uiDist > usHalfExplosionRadius ) + { // then no effect return( FALSE ); - } + } - // Direction to center of explosion - ubDirection = (UINT8)GetDirectionFromGridNo( sBombGridNo, pSoldier ); + // Direction to center of explosion + ubDirection = (UINT8)GetDirectionFromGridNo( sBombGridNo, pSoldier ); - // Increment attack counter... - gTacticalStatus.ubAttackBusyCount++; - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Incrementing Attack: Explosion dishing out damage, Count now %d", gTacticalStatus.ubAttackBusyCount ) ); + // Increment attack counter... + // gTacticalStatus.ubAttackBusyCount++; + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Incrementing Attack: Explosion dishing out damage, Count now %d", gTacticalStatus.ubAttackBusyCount ) ); + DebugAttackBusy( String("Explosion dishing out damage to %d\n", pSoldier->ubID) ); - sNewWoundAmt = sWoundAmt - __min( sWoundAmt, 35 ) * ArmourVersusExplosivesPercent( pSoldier ) / 100; - if ( sNewWoundAmt < 0 ) - { + sNewWoundAmt = sWoundAmt - __min( sWoundAmt, 35 ) * ArmourVersusExplosivesPercent( pSoldier ) / 100; + if ( sNewWoundAmt < 0 ) + { sNewWoundAmt = 0; - } + } - // Lesh: flashbang does affect on soldier or not - check it - if ( (Item[usItem].usItemClass & IC_EXPLOSV) && fFlashbang ) - { - ubSpecial = DetermineFlashbangEffect( pSoldier, ubDirection, fInBuilding); - } + // Lesh: flashbang does affect on soldier or not - check it + if ( (Item[usItem].usItemClass & IC_EXPLOSV) && fFlashbang ) + { + ubSpecial = DetermineFlashbangEffect( pSoldier, ubDirection, fInBuilding); + } - EVENT_SoldierGotHit( pSoldier, usItem, sNewWoundAmt, sBreathAmt, ubDirection, (INT16)uiDist, ubOwner, ubSpecial, ANIM_CROUCH, sSubsequent, sBombGridNo ); + EVENT_SoldierGotHit( pSoldier, usItem, sNewWoundAmt, sBreathAmt, ubDirection, (INT16)uiDist, ubOwner, ubSpecial, ANIM_CROUCH, sSubsequent, sBombGridNo ); - pSoldier->ubMiscSoldierFlags |= SOLDIER_MISC_HURT_BY_EXPLOSION; + pSoldier->ubMiscSoldierFlags |= SOLDIER_MISC_HURT_BY_EXPLOSION; - if ( ubOwner != NOBODY && MercPtrs[ ubOwner ]->bTeam == gbPlayerNum && pSoldier->bTeam != gbPlayerNum ) - { + if ( ubOwner != NOBODY && MercPtrs[ ubOwner ]->bTeam == gbPlayerNum && pSoldier->bTeam != gbPlayerNum ) + { ProcessImplicationsOfPCAttack( MercPtrs[ ubOwner ], &pSoldier, REASON_EXPLOSION ); - } + } - return( TRUE ); + return( TRUE ); } BOOLEAN DishOutGasDamage( SOLDIERTYPE * pSoldier, EXPLOSIVETYPE * pExplosive, INT16 sSubsequent, BOOLEAN fRecompileMovementCosts, INT16 sWoundAmt, INT16 sBreathAmt, UINT8 ubOwner ) { - INT8 bPosOfMask = NO_SLOT; + INT8 bPosOfMask = NO_SLOT; - if (!pSoldier->bActive || !pSoldier->bInSector || !pSoldier->bLife || AM_A_ROBOT( pSoldier ) ) - { - return( fRecompileMovementCosts ); - } - - if ( pExplosive->ubType == EXPLOSV_CREATUREGAS || pExplosive->ubType == EXPLOSV_BURNABLEGAS) - { - if ( pSoldier->uiStatusFlags & SOLDIER_MONSTER ) - { - // unaffected by own gas effects - return( fRecompileMovementCosts ); - } - if ( sSubsequent && pSoldier->fHitByGasFlags & HIT_BY_CREATUREGAS ) - { - // already affected by creature gas this turn - return( fRecompileMovementCosts ); - } - if ( sSubsequent && pSoldier->fHitByGasFlags & HIT_BY_BURNABLEGAS ) - { - // already affected by BURNABLEGAS this turn - return( fRecompileMovementCosts ); - } - - } - else // no gas mask help from creature attacks - // ATE/CJC: gas stuff + if (!pSoldier->bActive || !pSoldier->bInSector || !pSoldier->bLife || AM_A_ROBOT( pSoldier ) ) { - if ( pExplosive->ubType == EXPLOSV_TEARGAS ) - { - if ( AM_A_ROBOT( pSoldier ) ) - { - return( fRecompileMovementCosts ); - } - - // ignore whether subsequent or not if hit this turn - if ( pSoldier->fHitByGasFlags & HIT_BY_TEARGAS ) - { - // already affected by creature gas this turn - return( fRecompileMovementCosts ); - } - } - else if ( pExplosive->ubType == EXPLOSV_MUSTGAS ) - { - if ( AM_A_ROBOT( pSoldier ) ) - { - return( fRecompileMovementCosts ); - } - - if ( sSubsequent && pSoldier->fHitByGasFlags & HIT_BY_MUSTARDGAS ) - { - // already affected by creature gas this turn - return( fRecompileMovementCosts ); - } + return( fRecompileMovementCosts ); + } - } - - bPosOfMask = FindGasMask(pSoldier); - if ( bPosOfMask == NO_SLOT || pSoldier->inv[ bPosOfMask ].bStatus[0] < USABLE ) - { + if ( pExplosive->ubType == EXPLOSV_CREATUREGAS || pExplosive->ubType == EXPLOSV_BURNABLEGAS) + { + if ( pSoldier->uiStatusFlags & SOLDIER_MONSTER ) + { + // unaffected by own gas effects + return( fRecompileMovementCosts ); + } + if ( sSubsequent && pSoldier->fHitByGasFlags & HIT_BY_CREATUREGAS ) + { + // already affected by creature gas this turn + return( fRecompileMovementCosts ); + } + if ( sSubsequent && pSoldier->fHitByGasFlags & HIT_BY_BURNABLEGAS ) + { + // already affected by BURNABLEGAS this turn + return( fRecompileMovementCosts ); + } + + } + else // no gas mask help from creature attacks + // ATE/CJC: gas stuff + { + if ( pExplosive->ubType == EXPLOSV_TEARGAS ) + { + if ( AM_A_ROBOT( pSoldier ) ) + { + return( fRecompileMovementCosts ); + } + + // ignore whether subsequent or not if hit this turn + if ( pSoldier->fHitByGasFlags & HIT_BY_TEARGAS ) + { + // already affected by creature gas this turn + return( fRecompileMovementCosts ); + } + } + else if ( pExplosive->ubType == EXPLOSV_MUSTGAS ) + { + if ( AM_A_ROBOT( pSoldier ) ) + { + return( fRecompileMovementCosts ); + } + + if ( sSubsequent && pSoldier->fHitByGasFlags & HIT_BY_MUSTARDGAS ) + { + // already affected by creature gas this turn + return( fRecompileMovementCosts ); + } + + } + + bPosOfMask = FindGasMask(pSoldier); + if ( bPosOfMask == NO_SLOT || pSoldier->inv[ bPosOfMask ].bStatus[0] < USABLE ) + { bPosOfMask = NO_SLOT; - } - //if ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK && pSoldier->inv[ HEAD1POS ].bStatus[0] >= USABLE ) - //{ - // bPosOfMask = HEAD1POS; - //} - //else if ( pSoldier->inv[ HEAD2POS ].usItem == GASMASK && pSoldier->inv[ HEAD2POS ].bStatus[0] >= USABLE ) - //{ - // bPosOfMask = HEAD2POS; - //} + } + //if ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK && pSoldier->inv[ HEAD1POS ].bStatus[0] >= USABLE ) + //{ + // bPosOfMask = HEAD1POS; + //} + //else if ( pSoldier->inv[ HEAD2POS ].usItem == GASMASK && pSoldier->inv[ HEAD2POS ].bStatus[0] >= USABLE ) + //{ + // bPosOfMask = HEAD2POS; + //} - if ( bPosOfMask != NO_SLOT ) - { - if ( pSoldier->inv[ bPosOfMask ].bStatus[0] < GASMASK_MIN_STATUS ) - { - // GAS MASK reduces breath loss by its work% (it leaks if not at least 70%) - sBreathAmt = ( sBreathAmt * ( 100 - pSoldier->inv[ bPosOfMask ].bStatus[0] ) ) / 100; - if ( sBreathAmt > 500 ) - { + if ( bPosOfMask != NO_SLOT ) + { + if ( pSoldier->inv[ bPosOfMask ].bStatus[0] < GASMASK_MIN_STATUS ) + { + // GAS MASK reduces breath loss by its work% (it leaks if not at least 70%) + sBreathAmt = ( sBreathAmt * ( 100 - pSoldier->inv[ bPosOfMask ].bStatus[0] ) ) / 100; + if ( sBreathAmt > 500 ) + { // if at least 500 of breath damage got through // the soldier within the blast radius is gassed for at least one // turn, possibly more if it's tear gas (which hangs around a while) pSoldier->uiStatusFlags |= SOLDIER_GASSED; - } + } - if ( pSoldier->uiStatusFlags & SOLDIER_PC ) - { + if ( pSoldier->uiStatusFlags & SOLDIER_PC ) + { - if ( sWoundAmt > 1 ) - { - pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 4 ); - sWoundAmt = ( sWoundAmt * ( 100 - pSoldier->inv[ bPosOfMask ].bStatus[0] ) ) / 100; - } - else if ( sWoundAmt == 1 ) - { - pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 2 ); - } - } - } - else - { - sBreathAmt = 0; - if ( sWoundAmt > 0 ) + if ( sWoundAmt > 1 ) + { + pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 4 ); + sWoundAmt = ( sWoundAmt * ( 100 - pSoldier->inv[ bPosOfMask ].bStatus[0] ) ) / 100; + } + else if ( sWoundAmt == 1 ) + { + pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 2 ); + } + } + } + else { - if ( sWoundAmt == 1 ) - { - pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 2 ); - } - else - { - // use up gas mask - pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 4 ); - } + sBreathAmt = 0; + if ( sWoundAmt > 0 ) + { + if ( sWoundAmt == 1 ) + { + pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 2 ); + } + else + { + // use up gas mask + pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 4 ); + } + } + sWoundAmt = 0; } - sWoundAmt = 0; - } - } + } } if ( sWoundAmt != 0 || sBreathAmt != 0 ) { switch( pExplosive->ubType ) { - case EXPLOSV_CREATUREGAS: - pSoldier->fHitByGasFlags |= HIT_BY_CREATUREGAS; - break; - case EXPLOSV_TEARGAS: - pSoldier->fHitByGasFlags |= HIT_BY_TEARGAS; - break; - case EXPLOSV_MUSTGAS: - pSoldier->fHitByGasFlags |= HIT_BY_MUSTARDGAS; - break; - case EXPLOSV_BURNABLEGAS: - pSoldier->fHitByGasFlags |= HIT_BY_BURNABLEGAS; - break; - default: - break; + case EXPLOSV_CREATUREGAS: + pSoldier->fHitByGasFlags |= HIT_BY_CREATUREGAS; + break; + case EXPLOSV_TEARGAS: + pSoldier->fHitByGasFlags |= HIT_BY_TEARGAS; + break; + case EXPLOSV_MUSTGAS: + pSoldier->fHitByGasFlags |= HIT_BY_MUSTARDGAS; + break; + case EXPLOSV_BURNABLEGAS: + pSoldier->fHitByGasFlags |= HIT_BY_BURNABLEGAS; + break; + default: + break; } - - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"ExpControl pSoldier->fHitByGasFlags: %d", pSoldier->fHitByGasFlags ); + + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"ExpControl pSoldier->fHitByGasFlags: %d", pSoldier->fHitByGasFlags ); // a gas effect, take damage directly... SoldierTakeDamage( pSoldier, ANIM_STAND, sWoundAmt, sBreathAmt, TAKE_DAMAGE_GAS, NOBODY, NOWHERE, 0, TRUE ); @@ -1558,10 +1576,10 @@ BOOLEAN DishOutGasDamage( SOLDIERTYPE * pSoldier, EXPLOSIVETYPE * pExplosive, IN DoMercBattleSound( pSoldier, (INT8)( BATTLE_SOUND_HIT1 + Random( 2 ) ) ); } - if ( ubOwner != NOBODY && MercPtrs[ ubOwner ]->bTeam == gbPlayerNum && pSoldier->bTeam != gbPlayerNum ) - { - ProcessImplicationsOfPCAttack( MercPtrs[ ubOwner ], &pSoldier, REASON_EXPLOSION ); - } + if ( ubOwner != NOBODY && MercPtrs[ ubOwner ]->bTeam == gbPlayerNum && pSoldier->bTeam != gbPlayerNum ) + { + ProcessImplicationsOfPCAttack( MercPtrs[ ubOwner ], &pSoldier, REASON_EXPLOSION ); + } } return( fRecompileMovementCosts ); } @@ -1576,66 +1594,66 @@ BOOLEAN ExpAffect( INT16 sBombGridNo, INT16 sGridNo, UINT32 uiDist, UINT16 usIte BOOLEAN fRecompileMovementCosts = FALSE; BOOLEAN fSmokeEffect = FALSE; BOOLEAN fStunEffect = FALSE; - BOOLEAN fBlastEffect = TRUE; - BOOLEAN fBloodEffect = FALSE; - INT8 bSmokeEffectType = 0; - INT16 sNewGridNo; + BOOLEAN fBlastEffect = TRUE; + BOOLEAN fBloodEffect = FALSE; + INT8 bSmokeEffectType = 0; + INT16 sNewGridNo; ITEM_POOL * pItemPool, * pItemPoolNext; - UINT32 uiRoll; + UINT32 uiRoll; //Init the variables sX = sY = -1; if ( sSubsequent == BLOOD_SPREAD_EFFECT ) { - fSmokeEffect = FALSE; - fBlastEffect = FALSE; - fBloodEffect = TRUE; + fSmokeEffect = FALSE; + fBlastEffect = FALSE; + fBloodEffect = TRUE; } else { - // Turn off blast effect if some types of items... - switch( Explosive[Item[usItem].ubClassIndex].ubType ) - { - case EXPLOSV_MUSTGAS: + // Turn off blast effect if some types of items... + switch( Explosive[Item[usItem].ubClassIndex].ubType ) + { + case EXPLOSV_MUSTGAS: - fSmokeEffect = TRUE; - bSmokeEffectType = MUSTARDGAS_SMOKE_EFFECT; - fBlastEffect = FALSE; - break; + fSmokeEffect = TRUE; + bSmokeEffectType = MUSTARDGAS_SMOKE_EFFECT; + fBlastEffect = FALSE; + break; - case EXPLOSV_BURNABLEGAS: + case EXPLOSV_BURNABLEGAS: - fSmokeEffect = TRUE; - bSmokeEffectType = BURNABLEGAS_SMOKE_EFFECT; - fBlastEffect = FALSE; - break; + fSmokeEffect = TRUE; + bSmokeEffectType = BURNABLEGAS_SMOKE_EFFECT; + fBlastEffect = FALSE; + break; - case EXPLOSV_TEARGAS: + case EXPLOSV_TEARGAS: - fSmokeEffect = TRUE; - bSmokeEffectType = TEARGAS_SMOKE_EFFECT; - fBlastEffect = FALSE; - break; + fSmokeEffect = TRUE; + bSmokeEffectType = TEARGAS_SMOKE_EFFECT; + fBlastEffect = FALSE; + break; - case EXPLOSV_SMOKE: + case EXPLOSV_SMOKE: - fSmokeEffect = TRUE; - bSmokeEffectType = NORMAL_SMOKE_EFFECT; - fBlastEffect = FALSE; - break; + fSmokeEffect = TRUE; + bSmokeEffectType = NORMAL_SMOKE_EFFECT; + fBlastEffect = FALSE; + break; - case EXPLOSV_STUN: - fStunEffect = TRUE; - break; - - case EXPLOSV_CREATUREGAS: + case EXPLOSV_STUN: + fStunEffect = TRUE; + break; - fSmokeEffect = TRUE; - bSmokeEffectType = CREATURE_SMOKE_EFFECT; - fBlastEffect = FALSE; - break; - } + case EXPLOSV_CREATUREGAS: + + fSmokeEffect = TRUE; + bSmokeEffectType = CREATURE_SMOKE_EFFECT; + fBlastEffect = FALSE; + break; + } } @@ -1647,19 +1665,19 @@ BOOLEAN ExpAffect( INT16 sBombGridNo, INT16 sGridNo, UINT32 uiDist, UINT16 usIte // Calculate wound amount INT16 newDamage = pExplosive->ubDamage + (INT16)(( pExplosive->ubDamage * gGameExternalOptions.ubExplosivesDamageMultiplier) / 100); //lal - + sWoundAmt = newDamage + (INT16) ( (newDamage * uiRoll) / 100 ); - - - + + + // Calculate breath amount ( if stun damage applicable ) INT16 newBreath = pExplosive->ubStunDamage + (INT16)(( pExplosive->ubStunDamage * gGameExternalOptions.ubExplosivesDamageMultiplier) / 100); //lal - - sBreathAmt = ( newBreath * 100 ) + (INT16) ( ( ( newBreath / 2 ) * 100 * uiRoll ) / 100 ) ; - - // ATE: Make sure guys get pissed at us! - HandleBuldingDestruction( sGridNo ,ubOwner ); + sBreathAmt = ( newBreath * 100 ) + (INT16) ( ( ( newBreath / 2 ) * 100 * uiRoll ) / 100 ) ; + + + // ATE: Make sure guys get pissed at us! + HandleBuldingDestruction( sGridNo ,ubOwner ); if ( fBlastEffect ) @@ -1697,13 +1715,13 @@ BOOLEAN ExpAffect( INT16 sBombGridNo, INT16 sGridNo, UINT32 uiDist, UINT16 usIte { if ( Item[ usItem ].usItemClass & IC_GRENADE ) { - sStructDmgAmt = sWoundAmt / 3; + sStructDmgAmt = sWoundAmt / 3; } else // most explosives { sStructDmgAmt = sWoundAmt; } - + ExplosiveDamageGridNo( sGridNo, sStructDmgAmt, uiDist, &fRecompileMovementCosts, FALSE, -1, 0 , ubOwner, bLevel ); // ATE: Look for damage to walls ONLY for next two gridnos @@ -1729,10 +1747,10 @@ BOOLEAN ExpAffect( INT16 sBombGridNo, INT16 sGridNo, UINT32 uiDist, UINT16 usIte { //if ( !TypeRangeExistsInObjectLayer( sGridNo, FIRSTEXPLDEBRIS, SECONDEXPLDEBRIS, &usObjectIndex ) ) //{ - // GetTileIndexFromTypeSubIndex( SECONDEXPLDEBRIS, (UINT16)( Random( 10 ) + 1 ), &usTileIndex ); - // AddObjectToHead( sGridNo, usTileIndex ); + // GetTileIndexFromTypeSubIndex( SECONDEXPLDEBRIS, (UINT16)( Random( 10 ) + 1 ), &usTileIndex ); + // AddObjectToHead( sGridNo, usTileIndex ); - // SetRenderFlags(RENDER_FLAG_FULL); + // SetRenderFlags(RENDER_FLAG_FULL); //} } @@ -1758,22 +1776,22 @@ BOOLEAN ExpAffect( INT16 sBombGridNo, INT16 sGridNo, UINT32 uiDist, UINT16 usIte // Search for an explosive item in item pool while ( ( iWorldItem = GetItemOfClassTypeInPool( sGridNo, IC_EXPLOSV, bLevel ) ) != -1 ) { - // Get usItem - usItem = gWorldItems[ iWorldItem ].o.usItem; + // Get usItem + usItem = gWorldItems[ iWorldItem ].o.usItem; - DamageItem + DamageItem - if ( CheckForChainReaction( usItem, gWorldItems[ iWorldItem ].o.bStatus[0], sWoundAmt, TRUE ) ) - { - RemoveItemFromPool( sGridNo, iWorldItem, bLevel ); + if ( CheckForChainReaction( usItem, gWorldItems[ iWorldItem ].o.bStatus[0], sWoundAmt, TRUE ) ) + { + RemoveItemFromPool( sGridNo, iWorldItem, bLevel ); - // OK, Ignite this explosion! - IgniteExplosion( NOBODY, sX, sY, 0, sGridNo, usItem, bLevel ); - } - else - { - RemoveItemFromPool( sGridNo, iWorldItem, bLevel ); - } + // OK, Ignite this explosion! + IgniteExplosion( NOBODY, sX, sY, 0, sGridNo, usItem, bLevel ); + } + else + { + RemoveItemFromPool( sGridNo, iWorldItem, bLevel ); + } } @@ -1781,9 +1799,9 @@ BOOLEAN ExpAffect( INT16 sBombGridNo, INT16 sGridNo, UINT32 uiDist, UINT16 usIte RemoveAllUnburiedItems( sGridNo, bLevel ); */ } - } - else if ( fSmokeEffect ) - { + } + else if ( fSmokeEffect ) + { // If tear gar, determine turns to spread..... if ( sSubsequent == ERASE_SPREAD_EFFECT ) { @@ -1793,250 +1811,250 @@ BOOLEAN ExpAffect( INT16 sBombGridNo, INT16 sGridNo, UINT32 uiDist, UINT16 usIte { AddSmokeEffectToTile( iSmokeEffectID, bSmokeEffectType, sGridNo, bLevel ); } - } - else - { + } + else + { // Drop blood .... - // Get blood quantity.... + // Get blood quantity.... InternalDropBlood( sGridNo, 0, 0, (UINT8)(__max( ( MAXBLOODQUANTITY - ( uiDist * 2 ) ), 0 ) ), 1 ); - } + } - if ( sSubsequent != ERASE_SPREAD_EFFECT && sSubsequent != BLOOD_SPREAD_EFFECT ) - { - // if an explosion effect.... - if ( fBlastEffect ) - { - // don't hurt anyone who is already dead & waiting to be removed - if ( ( ubPerson = WhoIsThere2( sGridNo, bLevel ) ) != NOBODY ) - { - DamageSoldierFromBlast( ubPerson, ubOwner, sBombGridNo, sWoundAmt, sBreathAmt, uiDist, usItem, sSubsequent ); - } + if ( sSubsequent != ERASE_SPREAD_EFFECT && sSubsequent != BLOOD_SPREAD_EFFECT ) + { + // if an explosion effect.... + if ( fBlastEffect ) + { + // don't hurt anyone who is already dead & waiting to be removed + if ( ( ubPerson = WhoIsThere2( sGridNo, bLevel ) ) != NOBODY ) + { + DamageSoldierFromBlast( ubPerson, ubOwner, sBombGridNo, sWoundAmt, sBreathAmt, uiDist, usItem, sSubsequent ); + } - if ( bLevel == 1 ) - { - if ( ( ubPerson = WhoIsThere2(sGridNo, 0 ) ) != NOBODY ) - { - if ( (sWoundAmt / 2) > 20 ) - { - // debris damage! - if ( (sBreathAmt / 2) > 20 ) - { - DamageSoldierFromBlast( ubPerson, ubOwner, sBombGridNo, (INT16) Random( (sWoundAmt / 2) - 20 ), (INT16) Random( (sBreathAmt / 2) - 20 ), uiDist, usItem, sSubsequent ); - } - else - { - DamageSoldierFromBlast( ubPerson, ubOwner, sBombGridNo, (INT16) Random( (sWoundAmt / 2) - 20 ), 1, uiDist, usItem, sSubsequent ); - } - - } + if ( bLevel == 1 ) + { + if ( ( ubPerson = WhoIsThere2(sGridNo, 0 ) ) != NOBODY ) + { + if ( (sWoundAmt / 2) > 20 ) + { + // debris damage! + if ( (sBreathAmt / 2) > 20 ) + { + DamageSoldierFromBlast( ubPerson, ubOwner, sBombGridNo, (INT16) Random( (sWoundAmt / 2) - 20 ), (INT16) Random( (sBreathAmt / 2) - 20 ), uiDist, usItem, sSubsequent ); + } + else + { + DamageSoldierFromBlast( ubPerson, ubOwner, sBombGridNo, (INT16) Random( (sWoundAmt / 2) - 20 ), 1, uiDist, usItem, sSubsequent ); + } - } - } - } - else - { - if ( ( ubPerson = WhoIsThere2(sGridNo, bLevel ) ) >= NOBODY ) - { - return( fRecompileMovementCosts ); - } + } - pSoldier = MercPtrs[ ubPerson ]; // someone is here, and they're gonna get hurt - - fRecompileMovementCosts = DishOutGasDamage( pSoldier, pExplosive, sSubsequent, fRecompileMovementCosts, sWoundAmt, sBreathAmt, ubOwner ); -/* - if (!pSoldier->bActive || !pSoldier->bInSector || !pSoldier->bLife || AM_A_ROBOT( pSoldier ) ) - { - return( fRecompileMovementCosts ); - } - - if ( pExplosive->ubType == EXPLOSV_CREATUREGAS ) - { - if ( pSoldier->uiStatusFlags & SOLDIER_MONSTER ) - { - // unaffected by own gas effects + } + } + } + else + { + if ( ( ubPerson = WhoIsThere2(sGridNo, bLevel ) ) >= NOBODY ) + { return( fRecompileMovementCosts ); - } - if ( sSubsequent && pSoldier->fHitByGasFlags & HIT_BY_CREATUREGAS ) - { - // already affected by creature gas this turn - return( fRecompileMovementCosts ); - } - } - else // no gas mask help from creature attacks + } + + pSoldier = MercPtrs[ ubPerson ]; // someone is here, and they're gonna get hurt + + fRecompileMovementCosts = DishOutGasDamage( pSoldier, pExplosive, sSubsequent, fRecompileMovementCosts, sWoundAmt, sBreathAmt, ubOwner ); + /* + if (!pSoldier->bActive || !pSoldier->bInSector || !pSoldier->bLife || AM_A_ROBOT( pSoldier ) ) + { + return( fRecompileMovementCosts ); + } + + if ( pExplosive->ubType == EXPLOSV_CREATUREGAS ) + { + if ( pSoldier->uiStatusFlags & SOLDIER_MONSTER ) + { + // unaffected by own gas effects + return( fRecompileMovementCosts ); + } + if ( sSubsequent && pSoldier->fHitByGasFlags & HIT_BY_CREATUREGAS ) + { + // already affected by creature gas this turn + return( fRecompileMovementCosts ); + } + } + else // no gas mask help from creature attacks // ATE/CJC: gas stuff { - INT8 bPosOfMask = NO_SLOT; + INT8 bPosOfMask = NO_SLOT; - if ( pExplosive->ubType == EXPLOSV_TEARGAS ) - { - // ignore whether subsequent or not if hit this turn - if ( pSoldier->fHitByGasFlags & HIT_BY_TEARGAS ) - { - // already affected by creature gas this turn - return( fRecompileMovementCosts ); - } - } - else if ( pExplosive->ubType == EXPLOSV_MUSTGAS ) - { - if ( sSubsequent && pSoldier->fHitByGasFlags & HIT_BY_MUSTARDGAS ) - { - // already affected by creature gas this turn - return( fRecompileMovementCosts ); - } + if ( pExplosive->ubType == EXPLOSV_TEARGAS ) + { + // ignore whether subsequent or not if hit this turn + if ( pSoldier->fHitByGasFlags & HIT_BY_TEARGAS ) + { + // already affected by creature gas this turn + return( fRecompileMovementCosts ); + } + } + else if ( pExplosive->ubType == EXPLOSV_MUSTGAS ) + { + if ( sSubsequent && pSoldier->fHitByGasFlags & HIT_BY_MUSTARDGAS ) + { + // already affected by creature gas this turn + return( fRecompileMovementCosts ); + } - } - - if ( sSubsequent && pSoldier->fHitByGasFlags & HIT_BY_CREATUREGAS ) - { - // already affected by creature gas this turn - return( fRecompileMovementCosts ); - } + } + + if ( sSubsequent && pSoldier->fHitByGasFlags & HIT_BY_CREATUREGAS ) + { + // already affected by creature gas this turn + return( fRecompileMovementCosts ); + } - if ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK && pSoldier->inv[ HEAD1POS ].bStatus[0] >= USABLE ) - { - bPosOfMask = HEAD1POS; - } - else if ( pSoldier->inv[ HEAD2POS ].usItem == GASMASK && pSoldier->inv[ HEAD2POS ].bStatus[0] >= USABLE ) - { - bPosOfMask = HEAD2POS; - } + if ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK && pSoldier->inv[ HEAD1POS ].bStatus[0] >= USABLE ) + { + bPosOfMask = HEAD1POS; + } + else if ( pSoldier->inv[ HEAD2POS ].usItem == GASMASK && pSoldier->inv[ HEAD2POS ].bStatus[0] >= USABLE ) + { + bPosOfMask = HEAD2POS; + } - if ( bPosOfMask != NO_SLOT ) - { - if ( pSoldier->inv[ bPosOfMask ].bStatus[0] < GASMASK_MIN_STATUS ) - { - // GAS MASK reduces breath loss by its work% (it leaks if not at least 70%) - sBreathAmt = ( sBreathAmt * ( 100 - pSoldier->inv[ bPosOfMask ].bStatus[0] ) ) / 100; - if ( sBreathAmt > 500 ) - { - // if at least 500 of breath damage got through - // the soldier within the blast radius is gassed for at least one - // turn, possibly more if it's tear gas (which hangs around a while) - pSoldier->uiStatusFlags |= SOLDIER_GASSED; - } + if ( bPosOfMask != NO_SLOT ) + { + if ( pSoldier->inv[ bPosOfMask ].bStatus[0] < GASMASK_MIN_STATUS ) + { + // GAS MASK reduces breath loss by its work% (it leaks if not at least 70%) + sBreathAmt = ( sBreathAmt * ( 100 - pSoldier->inv[ bPosOfMask ].bStatus[0] ) ) / 100; + if ( sBreathAmt > 500 ) + { + // if at least 500 of breath damage got through + // the soldier within the blast radius is gassed for at least one + // turn, possibly more if it's tear gas (which hangs around a while) + pSoldier->uiStatusFlags |= SOLDIER_GASSED; + } - if ( sWoundAmt > 1 ) - { - pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 4 ); - sWoundAmt = ( sWoundAmt * ( 100 - pSoldier->inv[ bPosOfMask ].bStatus[0] ) ) / 100; - } - else if ( sWoundAmt == 1 ) - { - pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 2 ); - } - } - else - { - sBreathAmt = 0; - if ( sWoundAmt > 0 ) - { - if ( sWoundAmt == 1 ) - { - pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 2 ); - } - else - { - // use up gas mask - pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 4 ); - } - } - sWoundAmt = 0; - } + if ( sWoundAmt > 1 ) + { + pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 4 ); + sWoundAmt = ( sWoundAmt * ( 100 - pSoldier->inv[ bPosOfMask ].bStatus[0] ) ) / 100; + } + else if ( sWoundAmt == 1 ) + { + pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 2 ); + } + } + else + { + sBreathAmt = 0; + if ( sWoundAmt > 0 ) + { + if ( sWoundAmt == 1 ) + { + pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 2 ); + } + else + { + // use up gas mask + pSoldier->inv[ bPosOfMask ].bStatus[0] -= (INT8) Random( 4 ); + } + } + sWoundAmt = 0; + } - } + } } if ( sWoundAmt != 0 || sBreathAmt != 0 ) { - switch( pExplosive->ubType ) - { - case EXPLOSV_CREATUREGAS: - pSoldier->fHitByGasFlags |= HIT_BY_CREATUREGAS; - break; - case EXPLOSV_TEARGAS: - pSoldier->fHitByGasFlags |= HIT_BY_TEARGAS; - break; - case EXPLOSV_MUSTGAS: - pSoldier->fHitByGasFlags |= HIT_BY_MUSTARDGAS; - break; - default: - break; - } - // a gas effect, take damage directly... - SoldierTakeDamage( pSoldier, ANIM_STAND, sWoundAmt, sBreathAmt, TAKE_DAMAGE_GAS, NOBODY, NOWHERE, 0, TRUE ); - if ( pSoldier->bLife >= CONSCIOUSNESS ) - { - DoMercBattleSound( pSoldier, (INT8)( BATTLE_SOUND_HIT1 + Random( 2 ) ) ); - } + switch( pExplosive->ubType ) + { + case EXPLOSV_CREATUREGAS: + pSoldier->fHitByGasFlags |= HIT_BY_CREATUREGAS; + break; + case EXPLOSV_TEARGAS: + pSoldier->fHitByGasFlags |= HIT_BY_TEARGAS; + break; + case EXPLOSV_MUSTGAS: + pSoldier->fHitByGasFlags |= HIT_BY_MUSTARDGAS; + break; + default: + break; + } + // a gas effect, take damage directly... + SoldierTakeDamage( pSoldier, ANIM_STAND, sWoundAmt, sBreathAmt, TAKE_DAMAGE_GAS, NOBODY, NOWHERE, 0, TRUE ); + if ( pSoldier->bLife >= CONSCIOUSNESS ) + { + DoMercBattleSound( pSoldier, (INT8)( BATTLE_SOUND_HIT1 + Random( 2 ) ) ); + } } */ - } + } - (*pfMercHit) = TRUE; - } + (*pfMercHit) = TRUE; + } - return( fRecompileMovementCosts ); + return( fRecompileMovementCosts ); } void GetRayStopInfo( UINT32 uiNewSpot, UINT8 ubDir, INT8 bLevel, BOOLEAN fSmokeEffect, INT32 uiCurRange, INT32 *piMaxRange, UINT8 *pubKeepGoing ) { - INT8 bStructHeight; - UINT8 ubMovementCost; - INT8 Blocking, BlockingTemp; - BOOLEAN fTravelCostObs = FALSE; - UINT32 uiRangeReduce; - INT16 sNewGridNo; - STRUCTURE * pBlockingStructure; - BOOLEAN fBlowWindowSouth = FALSE; - BOOLEAN fReduceRay = TRUE; + INT8 bStructHeight; + UINT8 ubMovementCost; + INT8 Blocking, BlockingTemp; + BOOLEAN fTravelCostObs = FALSE; + UINT32 uiRangeReduce; + INT16 sNewGridNo; + STRUCTURE * pBlockingStructure; + BOOLEAN fBlowWindowSouth = FALSE; + BOOLEAN fReduceRay = TRUE; - ubMovementCost = gubWorldMovementCosts[ uiNewSpot ][ ubDir ][ bLevel ]; + ubMovementCost = gubWorldMovementCosts[ uiNewSpot ][ ubDir ][ bLevel ]; - if ( IS_TRAVELCOST_DOOR( ubMovementCost ) ) - { - ubMovementCost = DoorTravelCost( NULL, uiNewSpot, ubMovementCost, FALSE, NULL ); - // If we have hit a wall, STOP HERE - if (ubMovementCost >= TRAVELCOST_BLOCKED) - { - fTravelCostObs = TRUE; - } - } - else - { - // If we have hit a wall, STOP HERE - if ( ubMovementCost == TRAVELCOST_WALL ) - { - // We have an obstacle here.. - fTravelCostObs = TRUE; - } - } + if ( IS_TRAVELCOST_DOOR( ubMovementCost ) ) + { + ubMovementCost = DoorTravelCost( NULL, uiNewSpot, ubMovementCost, FALSE, NULL ); + // If we have hit a wall, STOP HERE + if (ubMovementCost >= TRAVELCOST_BLOCKED) + { + fTravelCostObs = TRUE; + } + } + else + { + // If we have hit a wall, STOP HERE + if ( ubMovementCost == TRAVELCOST_WALL ) + { + // We have an obstacle here.. + fTravelCostObs = TRUE; + } + } - - Blocking = GetBlockingStructureInfo( (INT16)uiNewSpot, ubDir, 0, bLevel, &bStructHeight, &pBlockingStructure, TRUE ); - if ( pBlockingStructure ) - { - if ( pBlockingStructure->fFlags & STRUCTURE_CAVEWALL ) - { - // block completely! - fTravelCostObs = TRUE; - } - else if ( pBlockingStructure->pDBStructureRef->pDBStructure->ubDensity <= 15 ) - { + Blocking = GetBlockingStructureInfo( (INT16)uiNewSpot, ubDir, 0, bLevel, &bStructHeight, &pBlockingStructure, TRUE ); + + if ( pBlockingStructure ) + { + if ( pBlockingStructure->fFlags & STRUCTURE_CAVEWALL ) + { + // block completely! + fTravelCostObs = TRUE; + } + else if ( pBlockingStructure->pDBStructureRef->pDBStructure->ubDensity <= 15 ) + { // not stopped fTravelCostObs = FALSE; fReduceRay = FALSE; - } - } + } + } - // ATE: For smoke, don't let it go over roof.... - if ( fSmokeEffect ) - { - if ( bLevel ) - { + // ATE: For smoke, don't let it go over roof.... + if ( fSmokeEffect ) + { + if ( bLevel ) + { STRUCTURE * pStructure; // Check for roof here.... @@ -2047,191 +2065,191 @@ void GetRayStopInfo( UINT32 uiNewSpot, UINT8 ubDir, INT8 bLevel, BOOLEAN fSmokeE // block completely! fTravelCostObs = TRUE; } - } - } - if ( fTravelCostObs ) - { + } + } + if ( fTravelCostObs ) + { - if ( fSmokeEffect ) - { - if ( Blocking == BLOCKING_TOPRIGHT_OPEN_WINDOW || Blocking == BLOCKING_TOPLEFT_OPEN_WINDOW ) - { + if ( fSmokeEffect ) + { + if ( Blocking == BLOCKING_TOPRIGHT_OPEN_WINDOW || Blocking == BLOCKING_TOPLEFT_OPEN_WINDOW ) + { + // If open, fTravelCostObs set to false and reduce range.... + fTravelCostObs = FALSE; + // Range will be reduced below... + } + + if ( fTravelCostObs ) + { + // ATE: For windows, check to the west and north for a broken window, as movement costs + // will override there... + sNewGridNo = NewGridNo( (INT16)uiNewSpot, DirectionInc( WEST ) ); + + BlockingTemp = GetBlockingStructureInfo( (INT16)sNewGridNo, ubDir, 0, bLevel, &bStructHeight, &pBlockingStructure, TRUE ); + if ( BlockingTemp == BLOCKING_TOPRIGHT_OPEN_WINDOW || BlockingTemp == BLOCKING_TOPLEFT_OPEN_WINDOW ) + { // If open, fTravelCostObs set to false and reduce range.... fTravelCostObs = FALSE; // Range will be reduced below... - } - - if ( fTravelCostObs ) - { - // ATE: For windows, check to the west and north for a broken window, as movement costs - // will override there... - sNewGridNo = NewGridNo( (INT16)uiNewSpot, DirectionInc( WEST ) ); - - BlockingTemp = GetBlockingStructureInfo( (INT16)sNewGridNo, ubDir, 0, bLevel, &bStructHeight, &pBlockingStructure, TRUE ); - if ( BlockingTemp == BLOCKING_TOPRIGHT_OPEN_WINDOW || BlockingTemp == BLOCKING_TOPLEFT_OPEN_WINDOW ) - { - // If open, fTravelCostObs set to false and reduce range.... - fTravelCostObs = FALSE; - // Range will be reduced below... - } - if ( pBlockingStructure && pBlockingStructure->pDBStructureRef->pDBStructure->ubDensity <= 15 ) - { + } + if ( pBlockingStructure && pBlockingStructure->pDBStructureRef->pDBStructure->ubDensity <= 15 ) + { fTravelCostObs = FALSE; fReduceRay = FALSE; - } - } + } + } - if ( fTravelCostObs ) - { - sNewGridNo = NewGridNo( (INT16)uiNewSpot, DirectionInc( NORTH ) ); + if ( fTravelCostObs ) + { + sNewGridNo = NewGridNo( (INT16)uiNewSpot, DirectionInc( NORTH ) ); - BlockingTemp = GetBlockingStructureInfo( (INT16)sNewGridNo, ubDir, 0, bLevel, &bStructHeight, &pBlockingStructure, TRUE ); - if ( BlockingTemp == BLOCKING_TOPRIGHT_OPEN_WINDOW || BlockingTemp == BLOCKING_TOPLEFT_OPEN_WINDOW ) - { - // If open, fTravelCostObs set to false and reduce range.... - fTravelCostObs = FALSE; - // Range will be reduced below... - } - if ( pBlockingStructure && pBlockingStructure->pDBStructureRef->pDBStructure->ubDensity <= 15 ) - { + BlockingTemp = GetBlockingStructureInfo( (INT16)sNewGridNo, ubDir, 0, bLevel, &bStructHeight, &pBlockingStructure, TRUE ); + if ( BlockingTemp == BLOCKING_TOPRIGHT_OPEN_WINDOW || BlockingTemp == BLOCKING_TOPLEFT_OPEN_WINDOW ) + { + // If open, fTravelCostObs set to false and reduce range.... + fTravelCostObs = FALSE; + // Range will be reduced below... + } + if ( pBlockingStructure && pBlockingStructure->pDBStructureRef->pDBStructure->ubDensity <= 15 ) + { fTravelCostObs = FALSE; fReduceRay = FALSE; - } - } + } + } - } - else - { - // We are a blast effect.... + } + else + { + // We are a blast effect.... - // ATE: explode windows!!!! - if ( Blocking == BLOCKING_TOPLEFT_WINDOW || Blocking == BLOCKING_TOPRIGHT_WINDOW ) - { - // Explode! - if ( ubDir == SOUTH || ubDir == SOUTHEAST || ubDir == SOUTHWEST ) - { - fBlowWindowSouth = TRUE; - } + // ATE: explode windows!!!! + if ( Blocking == BLOCKING_TOPLEFT_WINDOW || Blocking == BLOCKING_TOPRIGHT_WINDOW ) + { + // Explode! + if ( ubDir == SOUTH || ubDir == SOUTHEAST || ubDir == SOUTHWEST ) + { + fBlowWindowSouth = TRUE; + } - if ( pBlockingStructure != NULL ) - { - WindowHit( (INT16)uiNewSpot, pBlockingStructure->usStructureID, fBlowWindowSouth, TRUE ); - } - } + if ( pBlockingStructure != NULL ) + { + WindowHit( (INT16)uiNewSpot, pBlockingStructure->usStructureID, fBlowWindowSouth, TRUE ); + } + } - // ATE: For windows, check to the west and north for a broken window, as movement costs - // will override there... - sNewGridNo = NewGridNo( (INT16)uiNewSpot, DirectionInc( WEST ) ); + // ATE: For windows, check to the west and north for a broken window, as movement costs + // will override there... + sNewGridNo = NewGridNo( (INT16)uiNewSpot, DirectionInc( WEST ) ); - BlockingTemp = GetBlockingStructureInfo( (INT16)sNewGridNo, ubDir, 0, bLevel, &bStructHeight, &pBlockingStructure , TRUE ); - if ( pBlockingStructure && pBlockingStructure->pDBStructureRef->pDBStructure->ubDensity <= 15 ) - { + BlockingTemp = GetBlockingStructureInfo( (INT16)sNewGridNo, ubDir, 0, bLevel, &bStructHeight, &pBlockingStructure , TRUE ); + if ( pBlockingStructure && pBlockingStructure->pDBStructureRef->pDBStructure->ubDensity <= 15 ) + { fTravelCostObs = FALSE; fReduceRay = FALSE; - } - if ( BlockingTemp == BLOCKING_TOPRIGHT_WINDOW || BlockingTemp == BLOCKING_TOPLEFT_WINDOW ) - { - if ( pBlockingStructure != NULL ) - { - WindowHit( sNewGridNo, pBlockingStructure->usStructureID, FALSE, TRUE ); - } - } + } + if ( BlockingTemp == BLOCKING_TOPRIGHT_WINDOW || BlockingTemp == BLOCKING_TOPLEFT_WINDOW ) + { + if ( pBlockingStructure != NULL ) + { + WindowHit( sNewGridNo, pBlockingStructure->usStructureID, FALSE, TRUE ); + } + } - sNewGridNo = NewGridNo( (INT16)uiNewSpot, DirectionInc( NORTH ) ); - BlockingTemp = GetBlockingStructureInfo( (INT16)sNewGridNo, ubDir, 0, bLevel, &bStructHeight, &pBlockingStructure, TRUE ); + sNewGridNo = NewGridNo( (INT16)uiNewSpot, DirectionInc( NORTH ) ); + BlockingTemp = GetBlockingStructureInfo( (INT16)sNewGridNo, ubDir, 0, bLevel, &bStructHeight, &pBlockingStructure, TRUE ); - if ( pBlockingStructure && pBlockingStructure->pDBStructureRef->pDBStructure->ubDensity <= 15 ) - { - fTravelCostObs = FALSE; - fReduceRay = FALSE; - } - if ( BlockingTemp == BLOCKING_TOPRIGHT_WINDOW || BlockingTemp == BLOCKING_TOPLEFT_WINDOW ) - { - if ( pBlockingStructure != NULL ) - { - WindowHit( sNewGridNo, pBlockingStructure->usStructureID, FALSE, TRUE ); - } - } - } - } + if ( pBlockingStructure && pBlockingStructure->pDBStructureRef->pDBStructure->ubDensity <= 15 ) + { + fTravelCostObs = FALSE; + fReduceRay = FALSE; + } + if ( BlockingTemp == BLOCKING_TOPRIGHT_WINDOW || BlockingTemp == BLOCKING_TOPLEFT_WINDOW ) + { + if ( pBlockingStructure != NULL ) + { + WindowHit( sNewGridNo, pBlockingStructure->usStructureID, FALSE, TRUE ); + } + } + } + } - // Have we hit things like furniture, etc? - if ( Blocking != NOTHING_BLOCKING && !fTravelCostObs ) - { - // ATE: Tall things should blaock all - if ( bStructHeight == 4 ) - { - (*pubKeepGoing) = FALSE; - } - else - { - // If we are smoke, reduce range variably.... - if ( fReduceRay ) - { - if ( fSmokeEffect ) - { - switch( bStructHeight ) - { - case 3: - uiRangeReduce = 2; - break; + // Have we hit things like furniture, etc? + if ( Blocking != NOTHING_BLOCKING && !fTravelCostObs ) + { + // ATE: Tall things should blaock all + if ( bStructHeight == 4 ) + { + (*pubKeepGoing) = FALSE; + } + else + { + // If we are smoke, reduce range variably.... + if ( fReduceRay ) + { + if ( fSmokeEffect ) + { + switch( bStructHeight ) + { + case 3: + uiRangeReduce = 2; + break; - case 2: + case 2: - uiRangeReduce = 1; - break; + uiRangeReduce = 1; + break; - default: + default: - uiRangeReduce = 0; - break; - } - } - else - { - uiRangeReduce = 2; - } + uiRangeReduce = 0; + break; + } + } + else + { + uiRangeReduce = 2; + } - ( *piMaxRange ) -= uiRangeReduce; - } + ( *piMaxRange ) -= uiRangeReduce; + } - if ( uiCurRange <= (*piMaxRange) ) - { - (*pubKeepGoing) = TRUE; - } - else - { - (*pubKeepGoing) = FALSE; - } - } - } - else - { - if ( fTravelCostObs ) - { - ( *pubKeepGoing ) = FALSE; - } - else - { - ( *pubKeepGoing ) = TRUE; - } - } + if ( uiCurRange <= (*piMaxRange) ) + { + (*pubKeepGoing) = TRUE; + } + else + { + (*pubKeepGoing) = FALSE; + } + } + } + else + { + if ( fTravelCostObs ) + { + ( *pubKeepGoing ) = FALSE; + } + else + { + ( *pubKeepGoing ) = TRUE; + } + } } void SpreadEffect( INT16 sGridNo, UINT8 ubRadius, UINT16 usItem, UINT8 ubOwner, BOOLEAN fSubsequent, INT8 bLevel, INT32 iSmokeEffectID ) { - INT32 uiNewSpot, uiTempSpot, uiBranchSpot, cnt, branchCnt; - INT32 uiTempRange, ubBranchRange; - UINT8 ubDir,ubBranchDir, ubKeepGoing; - INT16 sRange; - BOOLEAN fRecompileMovement = FALSE; - BOOLEAN fAnyMercHit = FALSE; - BOOLEAN fSmokeEffect = FALSE; + INT32 uiNewSpot, uiTempSpot, uiBranchSpot, cnt, branchCnt; + INT32 uiTempRange, ubBranchRange; + UINT8 ubDir,ubBranchDir, ubKeepGoing; + INT16 sRange; + BOOLEAN fRecompileMovement = FALSE; + BOOLEAN fAnyMercHit = FALSE; + BOOLEAN fSmokeEffect = FALSE; - switch( Explosive[Item[usItem].ubClassIndex].ubType ) - { + switch( Explosive[Item[usItem].ubClassIndex].ubType ) + { case EXPLOSV_MUSTGAS: case EXPLOSV_BURNABLEGAS: @@ -2239,99 +2257,99 @@ void SpreadEffect( INT16 sGridNo, UINT8 ubRadius, UINT16 usItem, UINT8 ubOwner, case EXPLOSV_SMOKE: case EXPLOSV_CREATUREGAS: - fSmokeEffect = TRUE; + fSmokeEffect = TRUE; break; - } - + } + // Set values for recompile region to optimize area we need to recompile for MPs gsRecompileAreaTop = sGridNo / WORLD_COLS; gsRecompileAreaLeft = sGridNo % WORLD_COLS; gsRecompileAreaRight = gsRecompileAreaLeft; gsRecompileAreaBottom = gsRecompileAreaTop; - // multiply range by 2 so we can correctly calculate approximately round explosion regions - sRange = ubRadius * 2; + // multiply range by 2 so we can correctly calculate approximately round explosion regions + sRange = ubRadius * 2; - // first, affect main spot - if ( ExpAffect( sGridNo, sGridNo, 0, usItem, ubOwner, fSubsequent, &fAnyMercHit, bLevel, iSmokeEffectID ) ) - { + // first, affect main spot + if ( ExpAffect( sGridNo, sGridNo, 0, usItem, ubOwner, fSubsequent, &fAnyMercHit, bLevel, iSmokeEffectID ) ) + { fRecompileMovement = TRUE; - } + } - - for (ubDir = NORTH; ubDir <= NORTHWEST; ubDir++ ) - { - uiTempSpot = sGridNo; - uiTempRange = sRange; + for (ubDir = NORTH; ubDir <= NORTHWEST; ubDir++ ) + { + uiTempSpot = sGridNo; - if (ubDir & 1) - { - cnt = 3; - } - else - { - cnt = 2; - } - while( cnt <= uiTempRange) // end of range loop - { - // move one tile in direction - uiNewSpot = NewGridNo( (INT16)uiTempSpot, DirectionInc( ubDir ) ); + uiTempRange = sRange; - // see if this was a different spot & if we should be able to reach - // this spot - if (uiNewSpot == uiTempSpot) - { - ubKeepGoing = FALSE; - } - else - { - // Check if struct is a tree, etc and reduce range... - GetRayStopInfo( uiNewSpot, ubDir, bLevel, fSmokeEffect, cnt, &uiTempRange, &ubKeepGoing ); - } + if (ubDir & 1) + { + cnt = 3; + } + else + { + cnt = 2; + } + while( cnt <= uiTempRange) // end of range loop + { + // move one tile in direction + uiNewSpot = NewGridNo( (INT16)uiTempSpot, DirectionInc( ubDir ) ); - if (ubKeepGoing) - { - uiTempSpot = uiNewSpot; + // see if this was a different spot & if we should be able to reach + // this spot + if (uiNewSpot == uiTempSpot) + { + ubKeepGoing = FALSE; + } + else + { + // Check if struct is a tree, etc and reduce range... + GetRayStopInfo( uiNewSpot, ubDir, bLevel, fSmokeEffect, cnt, &uiTempRange, &ubKeepGoing ); + } - //DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Explosion affects %d", uiNewSpot) ); - // ok, do what we do here... - if ( ExpAffect( sGridNo, (INT16)uiNewSpot, cnt / 2, usItem, ubOwner, fSubsequent, &fAnyMercHit, bLevel, iSmokeEffectID ) ) - { + if (ubKeepGoing) + { + uiTempSpot = uiNewSpot; + + //DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Explosion affects %d", uiNewSpot) ); + // ok, do what we do here... + if ( ExpAffect( sGridNo, (INT16)uiNewSpot, cnt / 2, usItem, ubOwner, fSubsequent, &fAnyMercHit, bLevel, iSmokeEffectID ) ) + { fRecompileMovement = TRUE; - } + } - // how far should we branch out here? - ubBranchRange = (UINT8)( sRange - cnt ); + // how far should we branch out here? + ubBranchRange = (UINT8)( sRange - cnt ); - if ( ubBranchRange ) - { - // ok, there's a branch here. Mark where we start this branch. - uiBranchSpot = uiNewSpot; + if ( ubBranchRange ) + { + // ok, there's a branch here. Mark where we start this branch. + uiBranchSpot = uiNewSpot; - // figure the branch direction - which is one dir clockwise - ubBranchDir = (ubDir + 1) % 8; + // figure the branch direction - which is one dir clockwise + ubBranchDir = (ubDir + 1) % 8; - if (ubBranchDir & 1) - { - branchCnt = 3; - } - else - { - branchCnt = 2; - } + if (ubBranchDir & 1) + { + branchCnt = 3; + } + else + { + branchCnt = 2; + } - while( branchCnt <= ubBranchRange) // end of range loop - { - ubKeepGoing = TRUE; - uiNewSpot = NewGridNo( (INT16)uiBranchSpot, DirectionInc(ubBranchDir)); + while( branchCnt <= ubBranchRange) // end of range loop + { + ubKeepGoing = TRUE; + uiNewSpot = NewGridNo( (INT16)uiBranchSpot, DirectionInc(ubBranchDir)); if (uiNewSpot != uiBranchSpot) { - // Check if struct is a tree, etc and reduce range... - GetRayStopInfo( uiNewSpot, ubBranchDir, bLevel, fSmokeEffect, branchCnt, &ubBranchRange, &ubKeepGoing ); + // Check if struct is a tree, etc and reduce range... + GetRayStopInfo( uiNewSpot, ubBranchDir, bLevel, fSmokeEffect, branchCnt, &ubBranchRange, &ubKeepGoing ); - if ( ubKeepGoing ) + if ( ubKeepGoing ) { // ok, do what we do here //DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Explosion affects %d", uiNewSpot) ); @@ -2343,45 +2361,45 @@ void SpreadEffect( INT16 sGridNo, UINT8 ubRadius, UINT16 usItem, UINT8 ubOwner, } //else { - // check if it's ANY door, and if so, affect that spot so it's damaged - // if (RealDoorAt(uiNewSpot)) - // { - // ExpAffect(sGridNo,uiNewSpot,cnt,ubReason,fSubsequent); - // } - // blocked, break out of the the sub-branch loop - // break; + // check if it's ANY door, and if so, affect that spot so it's damaged + // if (RealDoorAt(uiNewSpot)) + // { + // ExpAffect(sGridNo,uiNewSpot,cnt,ubReason,fSubsequent); + // } + // blocked, break out of the the sub-branch loop + // break; } } - if (ubBranchDir & 1) - { - branchCnt += 3; - } - else - { - branchCnt += 2; - } + if (ubBranchDir & 1) + { + branchCnt += 3; + } + else + { + branchCnt += 2; + } - } - } // end of if a branch to do + } + } // end of if a branch to do - } - else // at edge, or tile blocks further spread in that direction - { - break; - } + } + else // at edge, or tile blocks further spread in that direction + { + break; + } - if (ubDir & 1) - { - cnt += 3; - } - else - { - cnt += 2; - } - } + if (ubDir & 1) + { + cnt += 3; + } + else + { + cnt += 2; + } + } - } // end of dir loop + } // end of dir loop // Recompile movement costs... if ( fRecompileMovement ) @@ -2392,7 +2410,7 @@ void SpreadEffect( INT16 sGridNo, UINT8 ubRadius, UINT16 usItem, UINT8 ubOwner, ConvertGridNoToXY( (INT16)sGridNo, &sX, &sY ); SetRecalculateWireFrameFlagRadius( sX, sY, ubRadius ); CalculateWorldWireFrameTiles( FALSE ); - + RecompileLocalMovementCostsInAreaWithFlags(); RecompileLocalMovementCostsFromRadius( sGridNo, MAX_DISTANCE_EXPLOSIVE_CAN_DESTROY_STRUCTURES ); @@ -2410,7 +2428,7 @@ void SpreadEffect( INT16 sGridNo, UINT8 ubRadius, UINT16 usItem, UINT8 ubOwner, { if ( gubElementsOnExplosionQueue ) { - gfExplosionQueueMayHaveChangedSight = TRUE; + gfExplosionQueueMayHaveChangedSight = TRUE; } } @@ -2428,7 +2446,7 @@ void SpreadEffect( INT16 sGridNo, UINT8 ubRadius, UINT16 usItem, UINT8 ubOwner, { MercSlots[ cnt ]->ubMiscSoldierFlags &= ~SOLDIER_MISC_HURT_BY_EXPLOSION; } - } + } } if ( fSubsequent != BLOOD_SPREAD_EFFECT ) @@ -2440,8 +2458,8 @@ void SpreadEffect( INT16 sGridNo, UINT8 ubRadius, UINT16 usItem, UINT8 ubOwner, void ToggleActionItemsByFrequency( INT8 bFrequency ) { - UINT32 uiWorldBombIndex; - OBJECTTYPE * pObj; + UINT32 uiWorldBombIndex; + OBJECTTYPE * pObj; // Go through all the bombs in the world, and look for remote ones for (uiWorldBombIndex = 0; uiWorldBombIndex < guiNumWorldBombs; uiWorldBombIndex++) @@ -2471,8 +2489,8 @@ void ToggleActionItemsByFrequency( INT8 bFrequency ) void TogglePressureActionItemsInGridNo( INT16 sGridNo ) { - UINT32 uiWorldBombIndex; - OBJECTTYPE * pObj; + UINT32 uiWorldBombIndex; + OBJECTTYPE * pObj; // Go through all the bombs in the world, and look for remote ones for (uiWorldBombIndex = 0; uiWorldBombIndex < guiNumWorldBombs; uiWorldBombIndex++) @@ -2518,8 +2536,8 @@ void BillyBlocksDoorCallback( void ) BOOLEAN HookerInRoom( UINT8 ubRoom ) { - UINT8 ubLoop, ubTempRoom; - SOLDIERTYPE * pSoldier; + UINT8 ubLoop, ubTempRoom; + SOLDIERTYPE * pSoldier; for ( ubLoop = gTacticalStatus.Team[ CIV_TEAM ].bFirstID; ubLoop <= gTacticalStatus.Team[ CIV_TEAM ].bLastID; ubLoop++ ) { @@ -2543,69 +2561,16 @@ void PerformItemAction( INT16 sGridNo, OBJECTTYPE * pObj ) switch( pObj->bActionValue ) { - case ACTION_ITEM_OPEN_DOOR: - pStructure = FindStructure( sGridNo, STRUCTURE_ANYDOOR ); - if (pStructure) + case ACTION_ITEM_OPEN_DOOR: + pStructure = FindStructure( sGridNo, STRUCTURE_ANYDOOR ); + if (pStructure) + { + if (pStructure->fFlags & STRUCTURE_OPEN) { - if (pStructure->fFlags & STRUCTURE_OPEN) - { - // it's already open - this MIGHT be an error but probably not - // because we are basically just ensuring that the door is open - } - else - { - if (pStructure->fFlags & STRUCTURE_BASE_TILE) - { - HandleDoorChangeFromGridNo( NULL, sGridNo, FALSE ); - } - else - { - HandleDoorChangeFromGridNo( NULL, pStructure->sBaseGridNo, FALSE ); - } - gfExplosionQueueMayHaveChangedSight = TRUE; - } + // it's already open - this MIGHT be an error but probably not + // because we are basically just ensuring that the door is open } else - { - // error message here - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Action item to open door in gridno %d but there is none!", sGridNo ); - #endif - } - break; - case ACTION_ITEM_CLOSE_DOOR: - pStructure = FindStructure( sGridNo, STRUCTURE_ANYDOOR ); - if (pStructure) - { - if (pStructure->fFlags & STRUCTURE_OPEN) - { - if (pStructure->fFlags & STRUCTURE_BASE_TILE) - { - HandleDoorChangeFromGridNo( NULL, sGridNo , FALSE ); - } - else - { - HandleDoorChangeFromGridNo( NULL, pStructure->sBaseGridNo, FALSE ); - } - gfExplosionQueueMayHaveChangedSight = TRUE; - } - else - { - // it's already closed - this MIGHT be an error but probably not - // because we are basically just ensuring that the door is closed - } - } - else - { - // error message here - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Action item to close door in gridno %d but there is none!", sGridNo ); - #endif - } - break; - case ACTION_ITEM_TOGGLE_DOOR: - pStructure = FindStructure( sGridNo, STRUCTURE_ANYDOOR ); - if (pStructure) { if (pStructure->fFlags & STRUCTURE_BASE_TILE) { @@ -2613,322 +2578,375 @@ void PerformItemAction( INT16 sGridNo, OBJECTTYPE * pObj ) } else { - HandleDoorChangeFromGridNo( NULL, pStructure->sBaseGridNo , FALSE ); + HandleDoorChangeFromGridNo( NULL, pStructure->sBaseGridNo, FALSE ); + } + gfExplosionQueueMayHaveChangedSight = TRUE; + } + } + else + { + // error message here +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Action item to open door in gridno %d but there is none!", sGridNo ); +#endif + } + break; + case ACTION_ITEM_CLOSE_DOOR: + pStructure = FindStructure( sGridNo, STRUCTURE_ANYDOOR ); + if (pStructure) + { + if (pStructure->fFlags & STRUCTURE_OPEN) + { + if (pStructure->fFlags & STRUCTURE_BASE_TILE) + { + HandleDoorChangeFromGridNo( NULL, sGridNo , FALSE ); + } + else + { + HandleDoorChangeFromGridNo( NULL, pStructure->sBaseGridNo, FALSE ); } gfExplosionQueueMayHaveChangedSight = TRUE; } else { - // error message here - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Action item to toggle door in gridno %d but there is none!", sGridNo ); - #endif + // it's already closed - this MIGHT be an error but probably not + // because we are basically just ensuring that the door is closed } - break; - case ACTION_ITEM_UNLOCK_DOOR: + } + else + { + // error message here +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Action item to close door in gridno %d but there is none!", sGridNo ); +#endif + } + break; + case ACTION_ITEM_TOGGLE_DOOR: + pStructure = FindStructure( sGridNo, STRUCTURE_ANYDOOR ); + if (pStructure) + { + if (pStructure->fFlags & STRUCTURE_BASE_TILE) { - DOOR * pDoor; - - pDoor = FindDoorInfoAtGridNo( sGridNo ); - if ( pDoor ) + HandleDoorChangeFromGridNo( NULL, sGridNo, FALSE ); + } + else + { + HandleDoorChangeFromGridNo( NULL, pStructure->sBaseGridNo , FALSE ); + } + gfExplosionQueueMayHaveChangedSight = TRUE; + } + else + { + // error message here +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Action item to toggle door in gridno %d but there is none!", sGridNo ); +#endif + } + break; + case ACTION_ITEM_UNLOCK_DOOR: + { + DOOR * pDoor; + + pDoor = FindDoorInfoAtGridNo( sGridNo ); + if ( pDoor ) + { + pDoor->fLocked = FALSE; + } + } + break; + case ACTION_ITEM_TOGGLE_LOCK: + { + DOOR * pDoor; + + pDoor = FindDoorInfoAtGridNo( sGridNo ); + if ( pDoor ) + { + if ( pDoor->fLocked ) { pDoor->fLocked = FALSE; } - } - break; - case ACTION_ITEM_TOGGLE_LOCK: - { - DOOR * pDoor; - - pDoor = FindDoorInfoAtGridNo( sGridNo ); - if ( pDoor ) + else { - if ( pDoor->fLocked ) + pDoor->fLocked = TRUE; + } + } + } + break; + case ACTION_ITEM_UNTRAP_DOOR: + { + DOOR * pDoor; + + pDoor = FindDoorInfoAtGridNo( sGridNo ); + if ( pDoor ) + { + pDoor->ubTrapLevel = 0; + pDoor->ubTrapID = NO_TRAP; + } + } + break; + case ACTION_ITEM_SMALL_PIT: + Add3X3Pit( sGridNo ); + SearchForOtherMembersWithinPitRadiusAndMakeThemFall( sGridNo, 1 ); + break; + case ACTION_ITEM_LARGE_PIT: + Add5X5Pit( sGridNo ); + SearchForOtherMembersWithinPitRadiusAndMakeThemFall( sGridNo, 2 ); + break; + case ACTION_ITEM_TOGGLE_ACTION1: + ToggleActionItemsByFrequency( FIRST_MAP_PLACED_FREQUENCY + 1 ); + break; + case ACTION_ITEM_TOGGLE_ACTION2: + ToggleActionItemsByFrequency( FIRST_MAP_PLACED_FREQUENCY + 2 ); + break; + case ACTION_ITEM_TOGGLE_ACTION3: + ToggleActionItemsByFrequency( FIRST_MAP_PLACED_FREQUENCY + 3 ); + break; + case ACTION_ITEM_TOGGLE_ACTION4: + ToggleActionItemsByFrequency( FIRST_MAP_PLACED_FREQUENCY + 4 ); + break; + case ACTION_ITEM_TOGGLE_PRESSURE_ITEMS: + TogglePressureActionItemsInGridNo( sGridNo ); + break; + case ACTION_ITEM_ENTER_BROTHEL: + // JA2Gold: Disable brothel tracking + /* + if ( ! (gTacticalStatus.uiFlags & INCOMBAT) ) + { + UINT8 ubID; + + ubID = WhoIsThere2( sGridNo, 0 ); + if ( (ubID != NOBODY) && (MercPtrs[ ubID ]->bTeam == gbPlayerNum) ) + { + if ( MercPtrs[ ubID ]->sOldGridNo == sGridNo + DirectionInc( SOUTH ) ) + { + gMercProfiles[ MADAME ].bNPCData2++; + + SetFactTrue( FACT_PLAYER_USED_BROTHEL ); + SetFactTrue( FACT_PLAYER_PASSED_GOON ); + + // If we for any reason trigger Madame's record 34 then we don't bother to do + // anything else + + // Billy always moves back on a timer so that the player has a chance to sneak + // someone else through + + // Madame's quote about female mercs should therefore not be made on a timer + + if ( gMercProfiles[ MADAME ].bNPCData2 > 2 ) + { + // more than 2 entering brothel + TriggerNPCRecord( MADAME, 35 ); + return; + } + + if ( gMercProfiles[ MADAME ].bNPCData2 == gMercProfiles[ MADAME ].bNPCData ) + { + // full # of mercs who paid have entered brothel + // have Billy block the way again + SetCustomizableTimerCallbackAndDelay( 2000, BillyBlocksDoorCallback, FALSE ); + //TriggerNPCRecord( BILLY, 6 ); + } + else if ( gMercProfiles[ MADAME ].bNPCData2 > gMercProfiles[ MADAME ].bNPCData ) + { + // more than full # of mercs who paid have entered brothel + // have Billy block the way again? + if ( CheckFact( FACT_PLAYER_FORCED_WAY_INTO_BROTHEL, 0 ) ) + { + // player already did this once! + TriggerNPCRecord( MADAME, 35 ); + return; + } + else + { + SetCustomizableTimerCallbackAndDelay( 2000, BillyBlocksDoorCallback, FALSE ); + SetFactTrue( FACT_PLAYER_FORCED_WAY_INTO_BROTHEL ); + TriggerNPCRecord( MADAME, 34 ); + } + } + + if ( gMercProfiles[ MercPtrs[ ubID ]->ubProfile ].bSex == FEMALE ) + { + // woman walking into brothel + TriggerNPCRecordImmediately( MADAME, 33 ); + } + + } + else + { + // someone wants to leave the brothel + TriggerNPCRecord( BILLY, 5 ); + } + + } + + } + */ + break; + case ACTION_ITEM_EXIT_BROTHEL: + // JA2Gold: Disable brothel tracking + /* + if ( ! (gTacticalStatus.uiFlags & INCOMBAT) ) + { + UINT8 ubID; + + ubID = WhoIsThere2( sGridNo, 0 ); + if ( (ubID != NOBODY) && (MercPtrs[ ubID ]->bTeam == gbPlayerNum) && MercPtrs[ ubID ]->sOldGridNo == sGridNo + DirectionInc( NORTH ) ) + { + gMercProfiles[ MADAME ].bNPCData2--; + if ( gMercProfiles[ MADAME ].bNPCData2 == 0 ) + { + // reset paid # + gMercProfiles[ MADAME ].bNPCData = 0; + } + // Billy should move back to block the door again + gsTempActionGridNo = sGridNo; + SetCustomizableTimerCallbackAndDelay( 1000, DelayedBillyTriggerToBlockOnExit, TRUE ); + } + } + */ + break; + case ACTION_ITEM_KINGPIN_ALARM: + PlayJA2Sample( KLAXON_ALARM, RATE_11025, SoundVolume( MIDVOLUME, sGridNo ), 5, SoundDir( sGridNo ) ); + CallAvailableKingpinMenTo( sGridNo ); + + gTacticalStatus.fCivGroupHostile[ KINGPIN_CIV_GROUP ] = CIV_GROUP_HOSTILE; + + { + UINT8 ubID, ubID2; + BOOLEAN fEnterCombat = FALSE; + + for ( ubID = gTacticalStatus.Team[ CIV_TEAM ].bFirstID; ubID <= gTacticalStatus.Team[ CIV_TEAM ].bLastID; ubID++ ) + { + if ( MercPtrs[ ubID ]->bActive && MercPtrs[ ubID ]->bInSector && MercPtrs[ ubID ]->ubCivilianGroup == KINGPIN_CIV_GROUP ) + { + for ( ubID2 = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; ubID2 <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ubID2++ ) { - pDoor->fLocked = FALSE; - } - else - { - pDoor->fLocked = TRUE; + if ( MercPtrs[ ubID ]->bOppList[ ubID2 ] == SEEN_CURRENTLY ) + { + MakeCivHostile( MercPtrs[ ubID ], 2 ); + fEnterCombat = TRUE; + } } } } - break; - case ACTION_ITEM_UNTRAP_DOOR: - { - DOOR * pDoor; - - pDoor = FindDoorInfoAtGridNo( sGridNo ); - if ( pDoor ) - { - pDoor->ubTrapLevel = 0; - pDoor->ubTrapID = NO_TRAP; - } - } - break; - case ACTION_ITEM_SMALL_PIT: - Add3X3Pit( sGridNo ); - SearchForOtherMembersWithinPitRadiusAndMakeThemFall( sGridNo, 1 ); - break; - case ACTION_ITEM_LARGE_PIT: - Add5X5Pit( sGridNo ); - SearchForOtherMembersWithinPitRadiusAndMakeThemFall( sGridNo, 2 ); - break; - case ACTION_ITEM_TOGGLE_ACTION1: - ToggleActionItemsByFrequency( FIRST_MAP_PLACED_FREQUENCY + 1 ); - break; - case ACTION_ITEM_TOGGLE_ACTION2: - ToggleActionItemsByFrequency( FIRST_MAP_PLACED_FREQUENCY + 2 ); - break; - case ACTION_ITEM_TOGGLE_ACTION3: - ToggleActionItemsByFrequency( FIRST_MAP_PLACED_FREQUENCY + 3 ); - break; - case ACTION_ITEM_TOGGLE_ACTION4: - ToggleActionItemsByFrequency( FIRST_MAP_PLACED_FREQUENCY + 4 ); - break; - case ACTION_ITEM_TOGGLE_PRESSURE_ITEMS: - TogglePressureActionItemsInGridNo( sGridNo ); - break; - case ACTION_ITEM_ENTER_BROTHEL: - // JA2Gold: Disable brothel tracking -/* + if ( ! (gTacticalStatus.uiFlags & INCOMBAT) ) { - UINT8 ubID; - - ubID = WhoIsThere2( sGridNo, 0 ); - if ( (ubID != NOBODY) && (MercPtrs[ ubID ]->bTeam == gbPlayerNum) ) - { - if ( MercPtrs[ ubID ]->sOldGridNo == sGridNo + DirectionInc( SOUTH ) ) - { - gMercProfiles[ MADAME ].bNPCData2++; - - SetFactTrue( FACT_PLAYER_USED_BROTHEL ); - SetFactTrue( FACT_PLAYER_PASSED_GOON ); - - // If we for any reason trigger Madame's record 34 then we don't bother to do - // anything else - - // Billy always moves back on a timer so that the player has a chance to sneak - // someone else through - - // Madame's quote about female mercs should therefore not be made on a timer - - if ( gMercProfiles[ MADAME ].bNPCData2 > 2 ) - { - // more than 2 entering brothel - TriggerNPCRecord( MADAME, 35 ); - return; - } - - if ( gMercProfiles[ MADAME ].bNPCData2 == gMercProfiles[ MADAME ].bNPCData ) - { - // full # of mercs who paid have entered brothel - // have Billy block the way again - SetCustomizableTimerCallbackAndDelay( 2000, BillyBlocksDoorCallback, FALSE ); - //TriggerNPCRecord( BILLY, 6 ); - } - else if ( gMercProfiles[ MADAME ].bNPCData2 > gMercProfiles[ MADAME ].bNPCData ) - { - // more than full # of mercs who paid have entered brothel - // have Billy block the way again? - if ( CheckFact( FACT_PLAYER_FORCED_WAY_INTO_BROTHEL, 0 ) ) - { - // player already did this once! - TriggerNPCRecord( MADAME, 35 ); - return; - } - else - { - SetCustomizableTimerCallbackAndDelay( 2000, BillyBlocksDoorCallback, FALSE ); - SetFactTrue( FACT_PLAYER_FORCED_WAY_INTO_BROTHEL ); - TriggerNPCRecord( MADAME, 34 ); - } - } - - if ( gMercProfiles[ MercPtrs[ ubID ]->ubProfile ].bSex == FEMALE ) - { - // woman walking into brothel - TriggerNPCRecordImmediately( MADAME, 33 ); - } - - } - else - { - // someone wants to leave the brothel - TriggerNPCRecord( BILLY, 5 ); - } - - } - + EnterCombatMode( CIV_TEAM ); } -*/ - break; - case ACTION_ITEM_EXIT_BROTHEL: - // JA2Gold: Disable brothel tracking -/* - if ( ! (gTacticalStatus.uiFlags & INCOMBAT) ) + } + + // now zap this object so it won't activate again + pObj->fFlags &= (~OBJECT_DISABLED_BOMB); + break; + case ACTION_ITEM_SEX: + // JA2Gold: Disable brothel sex Madd: Re-enabled + + if ( ! (gTacticalStatus.uiFlags & INCOMBAT) ) + { + UINT8 ubID; + OBJECTTYPE DoorCloser; + INT16 sTeleportSpot; + INT16 sDoorSpot; + UINT8 ubDirection; + UINT8 ubRoom, ubOldRoom; + + ubID = WhoIsThere2( sGridNo, 0 ); + if ( (ubID != NOBODY) && (MercPtrs[ ubID ]->bTeam == gbPlayerNum) ) { - UINT8 ubID; - - ubID = WhoIsThere2( sGridNo, 0 ); - if ( (ubID != NOBODY) && (MercPtrs[ ubID ]->bTeam == gbPlayerNum) && MercPtrs[ ubID ]->sOldGridNo == sGridNo + DirectionInc( NORTH ) ) + if ( InARoom( sGridNo, &ubRoom ) && InARoom( MercPtrs[ ubID ]->sOldGridNo, &ubOldRoom ) && ubOldRoom != ubRoom ) { - gMercProfiles[ MADAME ].bNPCData2--; - if ( gMercProfiles[ MADAME ].bNPCData2 == 0 ) + // also require there to be a miniskirt civ in the room + if ( HookerInRoom( ubRoom ) ) { - // reset paid # - gMercProfiles[ MADAME ].bNPCData = 0; - } - // Billy should move back to block the door again - gsTempActionGridNo = sGridNo; - SetCustomizableTimerCallbackAndDelay( 1000, DelayedBillyTriggerToBlockOnExit, TRUE ); - } - } -*/ - break; - case ACTION_ITEM_KINGPIN_ALARM: - PlayJA2Sample( KLAXON_ALARM, RATE_11025, SoundVolume( MIDVOLUME, sGridNo ), 5, SoundDir( sGridNo ) ); - CallAvailableKingpinMenTo( sGridNo ); - gTacticalStatus.fCivGroupHostile[ KINGPIN_CIV_GROUP ] = CIV_GROUP_HOSTILE; + // stop the merc... + EVENT_StopMerc( MercPtrs[ ubID ], MercPtrs[ ubID ]->sGridNo, MercPtrs[ ubID ]->bDirection ); - { - UINT8 ubID, ubID2; - BOOLEAN fEnterCombat = FALSE; - - for ( ubID = gTacticalStatus.Team[ CIV_TEAM ].bFirstID; ubID <= gTacticalStatus.Team[ CIV_TEAM ].bLastID; ubID++ ) - { - if ( MercPtrs[ ubID ]->bActive && MercPtrs[ ubID ]->bInSector && MercPtrs[ ubID ]->ubCivilianGroup == KINGPIN_CIV_GROUP ) - { - for ( ubID2 = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; ubID2 <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ubID2++ ) + switch( sGridNo ) { - if ( MercPtrs[ ubID ]->bOppList[ ubID2 ] == SEEN_CURRENTLY ) - { - MakeCivHostile( MercPtrs[ ubID ], 2 ); - fEnterCombat = TRUE; - } - } - } - } + case 13414: + sDoorSpot = 13413; + sTeleportSpot = 13413; + break; + case 11174: + sDoorSpot = 11173; + sTeleportSpot = 11173; + break; + case 12290: + sDoorSpot = 12290; + sTeleportSpot = 12291; + break; - if ( ! (gTacticalStatus.uiFlags & INCOMBAT) ) - { - EnterCombatMode( CIV_TEAM ); - } - } + default: - // now zap this object so it won't activate again - pObj->fFlags &= (~OBJECT_DISABLED_BOMB); - break; - case ACTION_ITEM_SEX: - // JA2Gold: Disable brothel sex Madd: Re-enabled - - if ( ! (gTacticalStatus.uiFlags & INCOMBAT) ) - { - UINT8 ubID; - OBJECTTYPE DoorCloser; - INT16 sTeleportSpot; - INT16 sDoorSpot; - UINT8 ubDirection; - UINT8 ubRoom, ubOldRoom; - - ubID = WhoIsThere2( sGridNo, 0 ); - if ( (ubID != NOBODY) && (MercPtrs[ ubID ]->bTeam == gbPlayerNum) ) - { - if ( InARoom( sGridNo, &ubRoom ) && InARoom( MercPtrs[ ubID ]->sOldGridNo, &ubOldRoom ) && ubOldRoom != ubRoom ) - { - // also require there to be a miniskirt civ in the room - if ( HookerInRoom( ubRoom ) ) - { - - // stop the merc... - EVENT_StopMerc( MercPtrs[ ubID ], MercPtrs[ ubID ]->sGridNo, MercPtrs[ ubID ]->bDirection ); - - switch( sGridNo ) - { - case 13414: - sDoorSpot = 13413; - sTeleportSpot = 13413; - break; - case 11174: - sDoorSpot = 11173; - sTeleportSpot = 11173; - break; - case 12290: - sDoorSpot = 12290; - sTeleportSpot = 12291; - break; - - default: - - sDoorSpot = NOWHERE; - sTeleportSpot = NOWHERE; + sDoorSpot = NOWHERE; + sTeleportSpot = NOWHERE; - } - - if ( sDoorSpot != NOWHERE && sTeleportSpot != NOWHERE ) - { - // close the door... - DoorCloser.bActionValue = ACTION_ITEM_CLOSE_DOOR; - PerformItemAction( sDoorSpot, &DoorCloser ); - - // have sex - HandleNPCDoAction( 0, NPC_ACTION_SEX, 0 ); - - // move the merc outside of the room again - sTeleportSpot = FindGridNoFromSweetSpotWithStructData( MercPtrs[ ubID ], STANDING, sTeleportSpot, 2, &ubDirection, FALSE ); - ChangeSoldierState( MercPtrs[ ubID ], STANDING, 0, TRUE ); - TeleportSoldier( MercPtrs[ ubID ], sTeleportSpot, FALSE ); - - HandleMoraleEvent( MercPtrs[ ubID ], MORALE_SEX, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); - FatigueCharacter( MercPtrs[ ubID ] ); - FatigueCharacter( MercPtrs[ ubID ] ); - FatigueCharacter( MercPtrs[ ubID ] ); - FatigueCharacter( MercPtrs[ ubID ] ); - DirtyMercPanelInterface( MercPtrs[ ubID ], DIRTYLEVEL1 ); - } } + if ( sDoorSpot != NOWHERE && sTeleportSpot != NOWHERE ) + { + // close the door... + DoorCloser.bActionValue = ACTION_ITEM_CLOSE_DOOR; + PerformItemAction( sDoorSpot, &DoorCloser ); + + // have sex + HandleNPCDoAction( 0, NPC_ACTION_SEX, 0 ); + + // move the merc outside of the room again + sTeleportSpot = FindGridNoFromSweetSpotWithStructData( MercPtrs[ ubID ], STANDING, sTeleportSpot, 2, &ubDirection, FALSE ); + ChangeSoldierState( MercPtrs[ ubID ], STANDING, 0, TRUE ); + TeleportSoldier( MercPtrs[ ubID ], sTeleportSpot, FALSE ); + + HandleMoraleEvent( MercPtrs[ ubID ], MORALE_SEX, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + FatigueCharacter( MercPtrs[ ubID ] ); + FatigueCharacter( MercPtrs[ ubID ] ); + FatigueCharacter( MercPtrs[ ubID ] ); + FatigueCharacter( MercPtrs[ ubID ] ); + DirtyMercPanelInterface( MercPtrs[ ubID ], DIRTYLEVEL1 ); + } } - break; } + break; + } - - break; - case ACTION_ITEM_REVEAL_ROOM: + } + + break; + case ACTION_ITEM_REVEAL_ROOM: + { + UINT8 ubRoom; + if ( InAHiddenRoom( sGridNo, &ubRoom ) ) { - UINT8 ubRoom; - if ( InAHiddenRoom( sGridNo, &ubRoom ) ) - { - RemoveRoomRoof( sGridNo, ubRoom, NULL ); - } + RemoveRoomRoof( sGridNo, ubRoom, NULL ); } - break; - case ACTION_ITEM_LOCAL_ALARM: - MakeNoise( NOBODY, sGridNo, 0, gpWorldLevelData[sGridNo].ubTerrainID, 30, NOISE_SILENT_ALARM ); - break; - case ACTION_ITEM_GLOBAL_ALARM: - CallAvailableEnemiesTo( sGridNo ); - break; - case ACTION_ITEM_BLOODCAT_ALARM: - CallAvailableTeamEnemiesTo( sGridNo, CREATURE_TEAM ); - break; - case ACTION_ITEM_KLAXON: - PlayJA2Sample( KLAXON_ALARM, RATE_11025, SoundVolume( MIDVOLUME, sGridNo ), 5, SoundDir( sGridNo ) ); - break; - case ACTION_ITEM_MUSEUM_ALARM: - PlayJA2Sample( KLAXON_ALARM, RATE_11025, SoundVolume( MIDVOLUME, sGridNo ), 5, SoundDir( sGridNo ) ); - CallEldinTo( sGridNo ); - break; - default: - // error message here - #ifdef JA2BETAVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Action item with invalid action in gridno %d!", sGridNo ); - #endif - break; + } + break; + case ACTION_ITEM_LOCAL_ALARM: + MakeNoise( NOBODY, sGridNo, 0, gpWorldLevelData[sGridNo].ubTerrainID, 30, NOISE_SILENT_ALARM ); + break; + case ACTION_ITEM_GLOBAL_ALARM: + CallAvailableEnemiesTo( sGridNo ); + break; + case ACTION_ITEM_BLOODCAT_ALARM: + CallAvailableTeamEnemiesTo( sGridNo, CREATURE_TEAM ); + break; + case ACTION_ITEM_KLAXON: + PlayJA2Sample( KLAXON_ALARM, RATE_11025, SoundVolume( MIDVOLUME, sGridNo ), 5, SoundDir( sGridNo ) ); + break; + case ACTION_ITEM_MUSEUM_ALARM: + PlayJA2Sample( KLAXON_ALARM, RATE_11025, SoundVolume( MIDVOLUME, sGridNo ), 5, SoundDir( sGridNo ) ); + CallEldinTo( sGridNo ); + break; + default: + // error message here +#ifdef JA2BETAVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Action item with invalid action in gridno %d!", sGridNo ); +#endif + break; } } @@ -2938,7 +2956,7 @@ void AddBombToQueue( UINT32 uiWorldBombIndex, UINT32 uiTimeStamp ) { return; } - + gExplosionQueue[gubElementsOnExplosionQueue].uiWorldBombIndex = uiWorldBombIndex; gExplosionQueue[gubElementsOnExplosionQueue].uiTimeStamp = uiTimeStamp; gExplosionQueue[gubElementsOnExplosionQueue].fExists = TRUE; @@ -2955,12 +2973,12 @@ void AddBombToQueue( UINT32 uiWorldBombIndex, UINT32 uiTimeStamp ) void HandleExplosionQueue( void ) { - UINT32 uiIndex; - UINT32 uiWorldBombIndex; - UINT32 uiCurrentTime; - INT16 sGridNo; - OBJECTTYPE * pObj; - UINT8 ubLevel; + UINT32 uiIndex; + UINT32 uiWorldBombIndex; + UINT32 uiCurrentTime; + INT16 sGridNo; + OBJECTTYPE * pObj; + UINT8 ubLevel; if ( !gfExplosionQueueActive ) { @@ -2973,7 +2991,7 @@ void HandleExplosionQueue( void ) if ( gExplosionQueue[ uiIndex ].fExists && uiCurrentTime >= gExplosionQueue[ uiIndex ].uiTimeStamp ) { // Set off this bomb now! - + // Preliminary assignments: uiWorldBombIndex = gExplosionQueue[ uiIndex ].uiWorldBombIndex; pObj = &( gWorldItems[ gWorldBombs[ uiWorldBombIndex ].iItemIndex ].o ); @@ -3086,9 +3104,9 @@ void HandleExplosionQueue( void ) void DecayBombTimers( void ) { - UINT32 uiWorldBombIndex; - UINT32 uiTimeStamp; - OBJECTTYPE * pObj; + UINT32 uiWorldBombIndex; + UINT32 uiTimeStamp; + OBJECTTYPE * pObj; uiTimeStamp = GetJA2Clock(); @@ -3106,15 +3124,15 @@ void DecayBombTimers( void ) { // put this bomb on the queue AddBombToQueue( uiWorldBombIndex, uiTimeStamp ); - // ATE: CC black magic.... - if ( pObj->ubBombOwner > 1 ) - { - gubPersonToSetOffExplosions = (UINT8) (pObj->ubBombOwner - 2); - } - else - { - gubPersonToSetOffExplosions = NOBODY; - } + // ATE: CC black magic.... + if ( pObj->ubBombOwner > 1 ) + { + gubPersonToSetOffExplosions = (UINT8) (pObj->ubBombOwner - 2); + } + else + { + gubPersonToSetOffExplosions = NOBODY; + } if (pObj->usItem != ACTION_ITEM || pObj->bActionValue == ACTION_ITEM_BLOW_UP) { @@ -3128,9 +3146,9 @@ void DecayBombTimers( void ) void SetOffBombsByFrequency( UINT8 ubID, INT8 bFrequency ) { - UINT32 uiWorldBombIndex; - UINT32 uiTimeStamp; - OBJECTTYPE * pObj; + UINT32 uiWorldBombIndex; + UINT32 uiTimeStamp; + OBJECTTYPE * pObj; uiTimeStamp = GetJA2Clock(); @@ -3165,29 +3183,29 @@ void SetOffPanicBombs( UINT8 ubID, INT8 bPanicTrigger ) // need to turn off gridnos & flags in gTacticalStatus gTacticalStatus.sPanicTriggerGridNo[ bPanicTrigger ] = NOWHERE; if ( (gTacticalStatus.sPanicTriggerGridNo[0] == NOWHERE) && - (gTacticalStatus.sPanicTriggerGridNo[1] == NOWHERE) && - (gTacticalStatus.sPanicTriggerGridNo[2] == NOWHERE) ) + (gTacticalStatus.sPanicTriggerGridNo[1] == NOWHERE) && + (gTacticalStatus.sPanicTriggerGridNo[2] == NOWHERE) ) { gTacticalStatus.fPanicFlags &= ~(PANIC_TRIGGERS_HERE); } switch( bPanicTrigger ) { - case 0: - SetOffBombsByFrequency( ubID, PANIC_FREQUENCY ); - gTacticalStatus.fPanicFlags &= ~(PANIC_BOMBS_HERE); - break; + case 0: + SetOffBombsByFrequency( ubID, PANIC_FREQUENCY ); + gTacticalStatus.fPanicFlags &= ~(PANIC_BOMBS_HERE); + break; - case 1: - SetOffBombsByFrequency( ubID, PANIC_FREQUENCY_2 ); - break; + case 1: + SetOffBombsByFrequency( ubID, PANIC_FREQUENCY_2 ); + break; - case 2: - SetOffBombsByFrequency( ubID, PANIC_FREQUENCY_3 ); - break; + case 2: + SetOffBombsByFrequency( ubID, PANIC_FREQUENCY_3 ); + break; - default: - break; + default: + break; } @@ -3200,10 +3218,10 @@ void SetOffPanicBombs( UINT8 ubID, INT8 bPanicTrigger ) BOOLEAN SetOffBombsInGridNo( UINT8 ubID, INT16 sGridNo, BOOLEAN fAllBombs, INT8 bLevel ) { - UINT32 uiWorldBombIndex; - UINT32 uiTimeStamp; - OBJECTTYPE * pObj; - BOOLEAN fFoundMine = FALSE; + UINT32 uiWorldBombIndex; + UINT32 uiTimeStamp; + OBJECTTYPE * pObj; + BOOLEAN fFoundMine = FALSE; uiTimeStamp = GetJA2Clock(); @@ -3220,19 +3238,19 @@ BOOLEAN SetOffBombsInGridNo( UINT8 ubID, INT16 sGridNo, BOOLEAN fAllBombs, INT8 // Snap: if we do set off our own trap (e.g. by trying to disarm it), we pay! /*if (!fAllBombs && MercPtrs[ ubID ]->bTeam != gbPlayerNum ) { - // ignore this unless it is a mine, etc which would have to have been placed by the - // player, seeing as how the others are all marked as known to the AI. - if ( !(Item[pObj->usItem].mine || pObj->usItem == TRIP_FLARE || pObj->usItem == TRIP_KLAXON ) ) - { - continue; - } + // ignore this unless it is a mine, etc which would have to have been placed by the + // player, seeing as how the others are all marked as known to the AI. + if ( !(Item[pObj->usItem].mine || pObj->usItem == TRIP_FLARE || pObj->usItem == TRIP_KLAXON ) ) + { + continue; + } } // player and militia ignore bombs set by player if ( pObj->ubBombOwner > 1 && (MercPtrs[ ubID ]->bTeam == gbPlayerNum || MercPtrs[ ubID ]->bTeam == MILITIA_TEAM) ) { - continue; - + continue; + }*/ if (pObj->usItem == SWITCH) @@ -3267,8 +3285,8 @@ BOOLEAN SetOffBombsInGridNo( UINT8 ubID, INT16 sGridNo, BOOLEAN fAllBombs, INT8 void ActivateSwitchInGridNo( UINT8 ubID, INT16 sGridNo ) { - UINT32 uiWorldBombIndex; - OBJECTTYPE * pObj; + UINT32 uiWorldBombIndex; + OBJECTTYPE * pObj; // Go through all the bombs in the world, and look for mines at this location for (uiWorldBombIndex = 0; uiWorldBombIndex < guiNumWorldBombs; uiWorldBombIndex++) @@ -3283,7 +3301,8 @@ void ActivateSwitchInGridNo( UINT8 ubID, INT16 sGridNo ) // isn't a bomb but a trigger // first set attack busy count to 0 in case of a lingering a.b.c. problem... - gTacticalStatus.ubAttackBusyCount = 0; + // No, not a good idea. + // gTacticalStatus.ubAttackBusyCount = 0; SetOffBombsByFrequency( ubID, pObj->bFrequency ); } @@ -3293,13 +3312,13 @@ void ActivateSwitchInGridNo( UINT8 ubID, INT16 sGridNo ) BOOLEAN SaveExplosionTableToSaveGameFile( HWFILE hFile ) { - UINT32 uiNumBytesWritten; - UINT32 uiExplosionCount=0; - UINT32 uiCnt; + UINT32 uiNumBytesWritten; + UINT32 uiExplosionCount=0; + UINT32 uiCnt; // - // Explosion queue Info + // Explosion queue Info // @@ -3325,7 +3344,7 @@ BOOLEAN SaveExplosionTableToSaveGameFile( HWFILE hFile ) // - // Explosion Data + // Explosion Data // //loop through and count all the active explosions @@ -3352,7 +3371,7 @@ BOOLEAN SaveExplosionTableToSaveGameFile( HWFILE hFile ) for( uiCnt=0; uiCnt< NUM_EXPLOSION_SLOTS; uiCnt++) { if( gExplosionData[ uiCnt ].fAllocated ) - { + { FileWrite( hFile, &gExplosionData[ uiCnt ], sizeof( EXPLOSIONTYPE ), &uiNumBytesWritten ); if( uiNumBytesWritten != sizeof( EXPLOSIONTYPE ) ) { @@ -3372,13 +3391,13 @@ BOOLEAN SaveExplosionTableToSaveGameFile( HWFILE hFile ) BOOLEAN LoadExplosionTableFromSavedGameFile( HWFILE hFile ) { - UINT32 uiNumBytesRead; - UINT32 uiExplosionCount=0; - UINT32 uiCnt; + UINT32 uiNumBytesRead; + UINT32 uiExplosionCount=0; + UINT32 uiCnt; // - // Explosion Queue + // Explosion Queue // //Clear the Explosion queue @@ -3405,9 +3424,9 @@ BOOLEAN LoadExplosionTableFromSavedGameFile( HWFILE hFile ) // - // Explosion Data + // Explosion Data // - + //Load the number of explosions FileRead( hFile, &guiNumExplosions, sizeof( UINT32 ), &uiNumBytesRead ); if( uiNumBytesRead != sizeof( UINT32 ) ) @@ -3439,7 +3458,7 @@ BOOLEAN LoadExplosionTableFromSavedGameFile( HWFILE hFile ) BOOLEAN DoesSAMExistHere( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, INT16 sGridNo ) { INT32 cnt; - INT16 sSectorNo; + INT16 sSectorNo; // ATE: If we are belwo, return right away... if ( sSectorZ != 0 ) @@ -3498,9 +3517,9 @@ void UpdateAndDamageSAMIfFound( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, void UpdateSAMDoneRepair( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ ) { INT32 cnt; - INT16 sSectorNo; - BOOLEAN fInSector = FALSE; - UINT16 usGoodGraphic, usDamagedGraphic; + INT16 sSectorNo; + BOOLEAN fInSector = FALSE; + UINT16 usGoodGraphic, usDamagedGraphic; // ATE: If we are below, return right away... if ( sSectorZ != 0 ) @@ -3522,7 +3541,7 @@ void UpdateSAMDoneRepair( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ ) if ( pSamList[ cnt ] == sSectorNo ) { // get graphic....... - GetTileIndexFromTypeSubIndex( EIGHTISTRUCT, (UINT16)( gbSAMGraphicList[ cnt ] ), &usGoodGraphic ); + GetTileIndexFromTypeSubIndex( EIGHTISTRUCT, (UINT16)( gbSAMGraphicList[ cnt ] ), &usGoodGraphic ); // Damaged one ( current ) is 2 less... usDamagedGraphic = usGoodGraphic - 2; @@ -3562,46 +3581,46 @@ void UpdateSAMDoneRepair( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ ) // see if they get angry void HandleBuldingDestruction( INT16 sGridNo, UINT8 ubOwner ) { - SOLDIERTYPE * pSoldier; - UINT8 cnt; + SOLDIERTYPE * pSoldier; + UINT8 cnt; - if ( ubOwner == NOBODY ) - { - return; - } + if ( ubOwner == NOBODY ) + { + return; + } - if ( MercPtrs[ ubOwner ]->bTeam != gbPlayerNum ) - { - return; - } + if ( MercPtrs[ ubOwner ]->bTeam != gbPlayerNum ) + { + return; + } cnt = gTacticalStatus.Team[ CIV_TEAM ].bFirstID; - for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ CIV_TEAM ].bLastID; cnt++ ,pSoldier++ ) + for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ CIV_TEAM ].bLastID; cnt++ ,pSoldier++ ) { if ( pSoldier->bActive && pSoldier->bInSector && pSoldier->bLife && pSoldier->bNeutral ) { - if ( pSoldier->ubProfile != NO_PROFILE ) - { + if ( pSoldier->ubProfile != NO_PROFILE ) + { // ignore if the player is fighting the enemy here and this is a good guy if ( gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector > 0 && (gMercProfiles[ pSoldier->ubProfile ].ubMiscFlags3 & PROFILE_MISC_FLAG3_GOODGUY) ) { continue; } - if ( DoesNPCOwnBuilding( pSoldier, sGridNo ) ) - { + if ( DoesNPCOwnBuilding( pSoldier, sGridNo ) ) + { MakeNPCGrumpyForMinorOffense( pSoldier, MercPtrs[ ubOwner ] ); - } - } + } + } } } } INT32 FindActiveTimedBomb( void ) { - UINT32 uiWorldBombIndex; - UINT32 uiTimeStamp; - OBJECTTYPE * pObj; + UINT32 uiWorldBombIndex; + UINT32 uiTimeStamp; + OBJECTTYPE * pObj; uiTimeStamp = GetJA2Clock(); @@ -3613,7 +3632,7 @@ INT32 FindActiveTimedBomb( void ) pObj = &( gWorldItems[ gWorldBombs[uiWorldBombIndex].iItemIndex ].o ); if ( pObj->bDetonatorType == BOMB_TIMED && !(pObj->fFlags & OBJECT_DISABLED_BOMB) ) { - return( gWorldBombs[uiWorldBombIndex].iItemIndex ); + return( gWorldBombs[uiWorldBombIndex].iItemIndex ); } } } @@ -3635,7 +3654,7 @@ BOOLEAN ActiveTimedBombExists( void ) void RemoveAllActiveTimedBombs( void ) { - INT32 iItemIndex; + INT32 iItemIndex; do { @@ -3645,18 +3664,18 @@ void RemoveAllActiveTimedBombs( void ) RemoveItemFromWorld( iItemIndex ); } } while( iItemIndex != -1 ); - + } UINT8 DetermineFlashbangEffect( SOLDIERTYPE *pSoldier, INT8 ubExplosionDir, BOOLEAN fInBuilding) { INT8 bNumTurns; UINT16 usHeadItem1, usHeadItem2; - + bNumTurns = FindNumTurnsBetweenDirs(pSoldier->bDirection, ubExplosionDir); usHeadItem1 = pSoldier->inv[ HEAD1POS ].usItem; usHeadItem2 = pSoldier->inv[ HEAD2POS ].usItem; - + // if soldier got in explosion area check if he is affected by flash // if soldier wears sun goggles OR grenade behind him OR // (he is not underground AND it is day AND he is outdoor) diff --git a/TileEngine/Interactive Tiles.cpp b/TileEngine/Interactive Tiles.cpp index 101e9ce5..d15ed2d6 100644 --- a/TileEngine/Interactive Tiles.cpp +++ b/TileEngine/Interactive Tiles.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #else @@ -33,6 +35,11 @@ #include "handle items.h" #include "message.h" #include "handle ui.h" + #include "NPC.h" + #include "Explosion Control.h" + #include "Text.h" + #include "GameSettings.h" + #include "environment.h" #endif #define MAX_INTTILE_STACK 10 diff --git a/TileEngine/Isometric Utils.cpp b/TileEngine/Isometric Utils.cpp index c990b6ff..a30f038e 100644 --- a/TileEngine/Isometric Utils.cpp +++ b/TileEngine/Isometric Utils.cpp @@ -333,13 +333,18 @@ BOOLEAN GetMouseWorldCoordsInCenter( INT16 *psMouseX, INT16 *psMouseY ) return( TRUE ); } +#if 0 +// 0verhaul +// I did that (or actually uncasted a bunch of stuff and re-typed others to correct them), so +// no worries // (jonathanl) to save me having to cast all the previous code BOOLEAN GetMouseMapPos( UINT16 *psMapPos ) { return GetMouseMapPos( (INT16 *)psMapPos ); } +#endif -BOOLEAN GetMouseMapPos( INT16 *psMapPos ) +BOOLEAN GetMouseMapPos( UINT16 *pusMapPos ) { INT16 sWorldX, sWorldY; static INT16 sSameCursorPos; @@ -348,7 +353,7 @@ BOOLEAN GetMouseMapPos( INT16 *psMapPos ) // Check if this is the same frame as before, return already calculated value if so! if ( uiOldFrameNumber == guiGameCycleCounter && !guiForceRefreshMousePositionCalculation ) { - ( *psMapPos ) = sSameCursorPos; + ( *pusMapPos ) = sSameCursorPos; if ( sSameCursorPos == 0 ) { @@ -363,14 +368,14 @@ BOOLEAN GetMouseMapPos( INT16 *psMapPos ) if ( GetMouseXY( &sWorldX, &sWorldY ) ) { - *psMapPos = MAPROWCOLTOPOS( sWorldY, sWorldX ); - sSameCursorPos = (*psMapPos); + *pusMapPos = MAPROWCOLTOPOS( sWorldY, sWorldX ); + sSameCursorPos = (*pusMapPos); return( TRUE ); } else { - *psMapPos = 0; - sSameCursorPos = (*psMapPos); + *pusMapPos = 0; + sSameCursorPos = (*pusMapPos); return( FALSE ); } diff --git a/TileEngine/Isometric Utils.h b/TileEngine/Isometric Utils.h index 706142cc..7b61470b 100644 --- a/TileEngine/Isometric Utils.h +++ b/TileEngine/Isometric Utils.h @@ -50,8 +50,7 @@ INT32 OutOfBounds(INT16 sGridno, INT16 sProposedGridno); BOOLEAN GetMouseCell( INT32 *piMouseMapPos ); BOOLEAN GetMouseXY( INT16 *psMouseX, INT16 *psMouseY ); BOOLEAN GetMouseWorldCoords( INT16 *psMouseX, INT16 *psMouseY ); -BOOLEAN GetMouseMapPos( UINT16 *psMapPos ); // (jonathanl) to save me having to cast all the previous code -BOOLEAN GetMouseMapPos( INT16 *psMapPos ); +BOOLEAN GetMouseMapPos( UINT16 *psMapPos ); BOOLEAN GetMouseWorldCoordsInCenter( INT16 *psMouseX, INT16 *psMouseY ); BOOLEAN GetMouseXYWithRemainder( INT16 *psMouseX, INT16 *psMouseY, INT16 *psCellX, INT16 *psCellY ); diff --git a/TileEngine/LightEffects.cpp b/TileEngine/LightEffects.cpp index fcde0556..4fa74905 100644 --- a/TileEngine/LightEffects.cpp +++ b/TileEngine/LightEffects.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #else @@ -21,6 +23,10 @@ #include "explosion control.h" #include "Random.h" #include "lighting.h" + #include "Game Clock.h" + #include "opplist.h" + #include "Campaign Types.h" + #include "Tactical Save.h" #endif #include "SaveLoadGame.h" diff --git a/TileEngine/Map Edgepoints.cpp b/TileEngine/Map Edgepoints.cpp index 9cc698ed..ebc1cb3f 100644 --- a/TileEngine/Map Edgepoints.cpp +++ b/TileEngine/Map Edgepoints.cpp @@ -15,6 +15,8 @@ #include "Animation Control.h" #include "Render Fun.h" #include "strategicmap.h" + #include "environment.h" + #include "worldman.h" #endif //dynamic arrays that contain the valid gridno's for each edge diff --git a/TileEngine/Radar Screen.cpp b/TileEngine/Radar Screen.cpp index 46d0f749..a77e045d 100644 --- a/TileEngine/Radar Screen.cpp +++ b/TileEngine/Radar Screen.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #else @@ -27,6 +29,9 @@ #include "Game Clock.h" #include "Map Screen Interface Map Inventory.h" #include "environment.h" + #include "meanwhile.h" + #include "strategicmap.h" + #include "Animation Data.h" #endif extern INT32 iCurrentMapSectorZ; diff --git a/TileEngine/Render Dirty.cpp b/TileEngine/Render Dirty.cpp index 7dfcf7a2..ae099484 100644 --- a/TileEngine/Render Dirty.cpp +++ b/TileEngine/Render Dirty.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #include "winfont.h" @@ -16,6 +18,8 @@ #include "wcheck.h" #include "video.h" #include "vobject_blitters.h" + #include "WinFont.h" + #include "Font Control.h" #endif #ifdef JA2BETAVERSION diff --git a/TileEngine/SaveLoadMap.cpp b/TileEngine/SaveLoadMap.cpp index 0f6c798f..932ff743 100644 --- a/TileEngine/SaveLoadMap.cpp +++ b/TileEngine/SaveLoadMap.cpp @@ -17,6 +17,7 @@ #include "Exit Grids.h" #include "Message.h" #include "GameSettings.h" + #include "Smell.h" #endif #define NUM_REVEALED_BYTES 3200 diff --git a/TileEngine/Shade Table Util.cpp b/TileEngine/Shade Table Util.cpp index 82094df8..a2f05b02 100644 --- a/TileEngine/Shade Table Util.cpp +++ b/TileEngine/Shade Table Util.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #else diff --git a/TileEngine/Smell.cpp b/TileEngine/Smell.cpp index 6854eb42..6269da6c 100644 --- a/TileEngine/Smell.cpp +++ b/TileEngine/Smell.cpp @@ -10,6 +10,9 @@ #include "gamesettings.h" #include "message.h" #include "Isometric utils.h" + #include "Map Information.h" + #include "Game Clock.h" + #include "Overhead.h" #endif /* diff --git a/TileEngine/SmokeEffects.cpp b/TileEngine/SmokeEffects.cpp index d284441d..1be1a1d1 100644 --- a/TileEngine/SmokeEffects.cpp +++ b/TileEngine/SmokeEffects.cpp @@ -1,3 +1,4 @@ +#include "builddefines.h" #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" @@ -21,6 +22,10 @@ #include "renderworld.h" #include "explosion control.h" #include "Random.h" + #include "Game Clock.h" + #include "opplist.h" + #include "Campaign Types.h" + #include "Tactical Save.h" #endif #include "SaveLoadGame.h" diff --git a/TileEngine/Tactical Placement GUI.cpp b/TileEngine/Tactical Placement GUI.cpp index e5b00cf4..dae199dc 100644 --- a/TileEngine/Tactical Placement GUI.cpp +++ b/TileEngine/Tactical Placement GUI.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + // WANNE 2 #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" @@ -40,6 +42,7 @@ #include "assignments.h" #include "text.h" #include "WordWrap.h" + #include "Game Clock.h" #endif typedef struct MERCPLACEMENT diff --git a/TileEngine/Tile Animation.cpp b/TileEngine/Tile Animation.cpp index 8a3ffe80..1afb32f5 100644 --- a/TileEngine/Tile Animation.cpp +++ b/TileEngine/Tile Animation.cpp @@ -1,31 +1,34 @@ #ifdef PRECOMPILEDHEADERS - #include "TileEngine All.h" +#include "TileEngine All.h" #else - #include "worlddef.h" - #include - #include - #include "wcheck.h" - #include "stdlib.h" - #include "time.h" - #include "video.h" - #include "debug.h" - #include "smooth.h" - #include "worldman.h" - #include "lighting.h" - #include "renderworld.h" - #include "overhead.h" - #include "ai.h" - #include "Sound Control.h" - #include "animation control.h" - #include "isometric utils.h" - #include "Font Control.h" - #include "message.h" - #include "tile animation.h" - #include "tile cache.h" - #include "explosion control.h" - #include "weapons.h" - #include "Keys.h" - #include "bullets.h" +#include "worlddef.h" +#include +#include +#include "wcheck.h" +#include "stdlib.h" +#include "time.h" +#include "video.h" +#include "debug.h" +#include "smooth.h" +#include "worldman.h" +#include "lighting.h" +#include "renderworld.h" +#include "overhead.h" +#include "ai.h" +#include "Sound Control.h" +#include "animation control.h" +#include "isometric utils.h" +#include "Font Control.h" +#include "message.h" +#include "tile animation.h" +#include "tile cache.h" +#include "explosion control.h" +#include "weapons.h" +#include "Keys.h" +#include "bullets.h" +#include "LightEffects.h" +#include "rotting corpses.h" +#include "SmokeEffects.h" #endif @@ -61,7 +64,7 @@ ANITILE *CreateAnimationTile( ANITILE_PARAMS *pAniParams ) sX = pAniParams->sX; sY = pAniParams->sY; sZ = pAniParams->sZ; - + pAniNode = pAniTileHead; @@ -90,44 +93,44 @@ ANITILE *CreateAnimationTile( ANITILE_PARAMS *pAniParams ) // ALLOCATE NEW TILE switch( ubLevel ) { - case ANI_STRUCT_LEVEL: - - pNode = ForceStructToTail( sGridNo, usTileIndex ); - break; + case ANI_STRUCT_LEVEL: - case ANI_SHADOW_LEVEL: - - AddShadowToHead( sGridNo, usTileIndex ); - pNode = gpWorldLevelData[ sGridNo ].pShadowHead; - break; + pNode = ForceStructToTail( sGridNo, usTileIndex ); + break; - case ANI_OBJECT_LEVEL: - - AddObjectToHead( sGridNo, usTileIndex ); - pNode = gpWorldLevelData[ sGridNo ].pObjectHead; - break; + case ANI_SHADOW_LEVEL: - case ANI_ROOF_LEVEL: - - AddRoofToHead( sGridNo, usTileIndex ); - pNode = gpWorldLevelData[ sGridNo ].pRoofHead; - break; + AddShadowToHead( sGridNo, usTileIndex ); + pNode = gpWorldLevelData[ sGridNo ].pShadowHead; + break; - case ANI_ONROOF_LEVEL: - - AddOnRoofToHead( sGridNo, usTileIndex ); - pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead; - break; + case ANI_OBJECT_LEVEL: - case ANI_TOPMOST_LEVEL: - - AddTopmostToHead( sGridNo, usTileIndex ); - pNode = gpWorldLevelData[ sGridNo ].pTopmostHead; - break; + AddObjectToHead( sGridNo, usTileIndex ); + pNode = gpWorldLevelData[ sGridNo ].pObjectHead; + break; - default: + case ANI_ROOF_LEVEL: - return( NULL ); + AddRoofToHead( sGridNo, usTileIndex ); + pNode = gpWorldLevelData[ sGridNo ].pRoofHead; + break; + + case ANI_ONROOF_LEVEL: + + AddOnRoofToHead( sGridNo, usTileIndex ); + pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead; + break; + + case ANI_TOPMOST_LEVEL: + + AddTopmostToHead( sGridNo, usTileIndex ); + pNode = gpWorldLevelData[ sGridNo ].pTopmostHead; + break; + + default: + + return( NULL ); } // SET NEW TILE VALUES @@ -174,38 +177,38 @@ ANITILE *CreateAnimationTile( ANITILE_PARAMS *pAniParams ) } - + switch( ubLevel ) { - case ANI_STRUCT_LEVEL: - - ResetSpecificLayerOptimizing( TILES_DYNAMIC_STRUCTURES ); - break; + case ANI_STRUCT_LEVEL: - case ANI_SHADOW_LEVEL: - - ResetSpecificLayerOptimizing( TILES_DYNAMIC_SHADOWS ); - break; + ResetSpecificLayerOptimizing( TILES_DYNAMIC_STRUCTURES ); + break; - case ANI_OBJECT_LEVEL: + case ANI_SHADOW_LEVEL: - ResetSpecificLayerOptimizing( TILES_DYNAMIC_OBJECTS ); - break; + ResetSpecificLayerOptimizing( TILES_DYNAMIC_SHADOWS ); + break; - case ANI_ROOF_LEVEL: + case ANI_OBJECT_LEVEL: - ResetSpecificLayerOptimizing( TILES_DYNAMIC_ROOF ); - break; + ResetSpecificLayerOptimizing( TILES_DYNAMIC_OBJECTS ); + break; - case ANI_ONROOF_LEVEL: + case ANI_ROOF_LEVEL: - ResetSpecificLayerOptimizing( TILES_DYNAMIC_ONROOF ); - break; + ResetSpecificLayerOptimizing( TILES_DYNAMIC_ROOF ); + break; - case ANI_TOPMOST_LEVEL: + case ANI_ONROOF_LEVEL: - ResetSpecificLayerOptimizing( TILES_DYNAMIC_TOPMOST ); - break; + ResetSpecificLayerOptimizing( TILES_DYNAMIC_ONROOF ); + break; + + case ANI_TOPMOST_LEVEL: + + ResetSpecificLayerOptimizing( TILES_DYNAMIC_TOPMOST ); + break; } @@ -237,7 +240,7 @@ ANITILE *CreateAnimationTile( ANITILE_PARAMS *pAniParams ) pNewAniNode->pLevelNode->uiFlags |= ( LEVELNODE_LASTDYNAMIC | LEVELNODE_UPDATESAVEBUFFERONCE ); pNewAniNode->pLevelNode->uiFlags &= (~LEVELNODE_DYNAMIC ); } - + if ( ( uiFlags & ANITILE_OPTIMIZEFORSMOKEEFFECT ) ) { pNewAniNode->pLevelNode->uiFlags |= LEVELNODE_NOWRITEZ; @@ -349,35 +352,35 @@ void DeleteAniTile( ANITILE *pAniTile ) // Delete memory assosiated with item switch( pAniNode->ubLevelID ) { - case ANI_STRUCT_LEVEL: - - RemoveStructFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode ); - break; + case ANI_STRUCT_LEVEL: - case ANI_SHADOW_LEVEL: - - RemoveShadowFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode ); - break; + RemoveStructFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode ); + break; - case ANI_OBJECT_LEVEL: - - RemoveObject( pAniNode->sGridNo, pAniNode->usTileIndex ); - break; + case ANI_SHADOW_LEVEL: - case ANI_ROOF_LEVEL: - - RemoveRoof( pAniNode->sGridNo, pAniNode->usTileIndex ); - break; + RemoveShadowFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode ); + break; - case ANI_ONROOF_LEVEL: - - RemoveOnRoof( pAniNode->sGridNo, pAniNode->usTileIndex ); - break; + case ANI_OBJECT_LEVEL: - case ANI_TOPMOST_LEVEL: - - RemoveTopmostFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode ); - break; + RemoveObject( pAniNode->sGridNo, pAniNode->usTileIndex ); + break; + + case ANI_ROOF_LEVEL: + + RemoveRoof( pAniNode->sGridNo, pAniNode->usTileIndex ); + break; + + case ANI_ONROOF_LEVEL: + + RemoveOnRoof( pAniNode->sGridNo, pAniNode->usTileIndex ); + break; + + case ANI_TOPMOST_LEVEL: + + RemoveTopmostFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode ); + break; } if ( pAniNode->uiFlags & ANITILE_LIGHT && pAniNode->lightSprite >= 0 ) @@ -404,9 +407,10 @@ void DeleteAniTile( ANITILE *pAniTile ) gTacticalStatus.uiFlags &= (~DISALLOW_SIGHT); } - // Freeup attacker from explosion - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., EXPLOSION effect gone off") ); - ReduceAttackBusyCount( (UINT8)pAniNode->ubUserData2, FALSE ); + // Freeup attacker from explosion + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., EXPLOSION effect gone off") ); + DebugAttackBusy( "@@@@@@@ EXPLOSION effect finished.\n"); + ReduceAttackBusyCount( ); } @@ -416,10 +420,10 @@ void DeleteAniTile( ANITILE *pAniTile ) // First delete the bullet! RemoveBullet( pAniNode->uiUserData3 ); - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - miss finished animation") ); - FreeUpAttacker( (UINT8) pAniNode->ubAttackerMissed ); + // 0verhaul: Removed because it's handled by RemoveBullet. + // DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - miss finished animation") ); + // FreeUpAttacker( (UINT8) pAniNode->ubAttackerMissed ); } - } else { @@ -431,7 +435,7 @@ void DeleteAniTile( ANITILE *pAniTile ) // OK, set our frame data back to zero.... pAniNode->pLevelNode->sCurrentFrame = 0; - + // Set some flags to write to Z / update save buffer // pAniNode->pLevelNode->uiFlags |=( LEVELNODE_LASTDYNAMIC | LEVELNODE_UPDATESAVEBUFFERONCE ); pAniNode->pLevelNode->uiFlags &= ~( LEVELNODE_DYNAMIC | LEVELNODE_USEZ | LEVELNODE_ANIMATION ); @@ -544,6 +548,8 @@ void UpdateAniTiles( ) case ANI_KEYFRAME_CHAIN_WATER_EXPLOSION: IgniteExplosion( pNode->ubUserData2, pNode->pLevelNode->sRelativeX, pNode->pLevelNode->sRelativeY, 0, pNode->sGridNo, (UINT16)( pNode->uiUserData ), 0 ); + DebugAttackBusy( "Reducing attack busy from water explosion delay.\n"); + ReduceAttackBusyCount( ); break; case ANI_KEYFRAME_DO_SOUND: @@ -801,39 +807,39 @@ ANITILE *GetCachedAniTileOfType( INT16 sGridNo, UINT8 ubLevelID, UINT32 uiFlags switch( ubLevelID ) { - case ANI_STRUCT_LEVEL: - - pNode = gpWorldLevelData[ sGridNo ].pStructHead; - break; + case ANI_STRUCT_LEVEL: - case ANI_SHADOW_LEVEL: - - pNode = gpWorldLevelData[ sGridNo ].pShadowHead; - break; + pNode = gpWorldLevelData[ sGridNo ].pStructHead; + break; - case ANI_OBJECT_LEVEL: - - pNode = gpWorldLevelData[ sGridNo ].pObjectHead; - break; + case ANI_SHADOW_LEVEL: - case ANI_ROOF_LEVEL: - - pNode = gpWorldLevelData[ sGridNo ].pRoofHead; - break; + pNode = gpWorldLevelData[ sGridNo ].pShadowHead; + break; - case ANI_ONROOF_LEVEL: - - pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead; - break; + case ANI_OBJECT_LEVEL: - case ANI_TOPMOST_LEVEL: - - pNode = gpWorldLevelData[ sGridNo ].pTopmostHead; - break; + pNode = gpWorldLevelData[ sGridNo ].pObjectHead; + break; - default: + case ANI_ROOF_LEVEL: - return( NULL ); + pNode = gpWorldLevelData[ sGridNo ].pRoofHead; + break; + + case ANI_ONROOF_LEVEL: + + pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead; + break; + + case ANI_TOPMOST_LEVEL: + + pNode = gpWorldLevelData[ sGridNo ].pTopmostHead; + break; + + default: + + return( NULL ); } while( pNode != NULL ) @@ -894,7 +900,7 @@ void PauseAllAniTilesOfType( UINT32 uiType, BOOLEAN fPause ) if ( pNode->uiFlags & uiType ) { - PauseAniTile( pNode, fPause ); + PauseAniTile( pNode, fPause ); } } diff --git a/TileEngine/Tile Cache.cpp b/TileEngine/Tile Cache.cpp index c7c2c1fd..7fbf0eab 100644 --- a/TileEngine/Tile Cache.cpp +++ b/TileEngine/Tile Cache.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #else diff --git a/TileEngine/Tile Surface.cpp b/TileEngine/Tile Surface.cpp index 4cc1143d..52f2e11b 100644 --- a/TileEngine/Tile Surface.cpp +++ b/TileEngine/Tile Surface.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #else diff --git a/TileEngine/WorldDat.cpp b/TileEngine/WorldDat.cpp index df485b34..b8f93242 100644 --- a/TileEngine/WorldDat.cpp +++ b/TileEngine/WorldDat.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #else diff --git a/TileEngine/XML_ExplosionData.cpp b/TileEngine/XML_ExplosionData.cpp index a6667ba8..788f2311 100644 --- a/TileEngine/XML_ExplosionData.cpp +++ b/TileEngine/XML_ExplosionData.cpp @@ -1,10 +1,17 @@ // Lesh: +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #else #include #include #include "explosion control.h" + #include "TopicIDs.h" + #include "TopicOps.h" + #include "Debug.h" + #include "FileMan.h" + #include "Debug Control.h" #endif #include "expat.h" diff --git a/TileEngine/environment.cpp b/TileEngine/environment.cpp index 3a667672..89b2f37b 100644 --- a/TileEngine/environment.cpp +++ b/TileEngine/environment.cpp @@ -23,6 +23,7 @@ #include "opplist.h" #include "Random.h" #include "strategicmap.h" + #include "GameSettings.h" #endif //effects whether or not time of day effects the lighting. Underground diff --git a/TileEngine/lighting.cpp b/TileEngine/lighting.cpp index fbaba3a3..6ef72c2c 100644 --- a/TileEngine/lighting.cpp +++ b/TileEngine/lighting.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + /**************************************************************************************** * JA2 Lighting Module * @@ -52,6 +54,7 @@ #include "rotting corpses.h" #include "Fileman.h" #include "environment.h" + #include "PATHAI.H" #endif #define LVL1_L1_PER (50) diff --git a/TileEngine/overhead map.cpp b/TileEngine/overhead map.cpp index 71d21cf3..3aebc1d6 100644 --- a/TileEngine/overhead map.cpp +++ b/TileEngine/overhead map.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #else @@ -31,6 +33,12 @@ #include "world items.h" #include "environment.h" #include "message.h" + #include "faces.h" + #include "Squads.h" + #include "Interactive Tiles.h" + #include "gameloop.h" + #include "sysutil.h" + #include "tile surface.h" #endif diff --git a/TileEngine/physics.cpp b/TileEngine/physics.cpp index af537a6a..6eb2dc5b 100644 --- a/TileEngine/physics.cpp +++ b/TileEngine/physics.cpp @@ -1,33 +1,37 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS - #include "TileEngine All.h" +#include "TileEngine All.h" #else - #include "physics.h" - #include "wcheck.h" - #include "timer control.h" - #include "isometric utils.h" - #include "los.h" - #include "worldman.h" - #include "event pump.h" - #include "Sound Control.h" - #include "soldier control.h" - #include "interface.h" - #include "interface items.h" - #include "weapons.h" - #include "explosion control.h" - #include "Debug Control.h" - #include "tile animation.h" - #include "message.h" - #include "weapons.h" - #include "structure wrap.h" - #include "physics.h" - #include "overhead.h" - #include "animation control.h" - #include "text.h" - #include "Random.h" - #include "lighteffects.h" - #include "opplist.h" - #include "World Items.h" - #include "environment.h" +#include "physics.h" +#include "wcheck.h" +#include "timer control.h" +#include "isometric utils.h" +#include "los.h" +#include "worldman.h" +#include "event pump.h" +#include "Sound Control.h" +#include "soldier control.h" +#include "interface.h" +#include "interface items.h" +#include "weapons.h" +#include "explosion control.h" +#include "Debug Control.h" +#include "tile animation.h" +#include "message.h" +#include "weapons.h" +#include "structure wrap.h" +#include "physics.h" +#include "overhead.h" +#include "animation control.h" +#include "text.h" +#include "Random.h" +#include "lighteffects.h" +#include "opplist.h" +#include "World Items.h" +#include "environment.h" +#include "GameSettings.h" +#include "Buildings.h" #endif #include "Campaign.h" @@ -52,7 +56,7 @@ #define GET_OBJECT_LEVEL( z ) ( (INT8)( ( z + 10 ) / HEIGHT_UNITS ) ) //#define OBJECT_DETONATE_ON_IMPACT( o ) ( ( o->Obj.usItem == MORTAR_SHELL ) ) // && ( o->ubActionCode == THROW_ARM_ITEM || pObject->fTestObject ) ) #define OBJECT_DETONATE_ON_IMPACT( o ) ( ( Item[o->Obj.usItem].usItemClass == IC_BOMB ) ) // && ( o->ubActionCode == THROW_ARM_ITEM || pObject->fTestObject ) ) - + #define MAX_INTEGRATIONS 8 @@ -146,11 +150,11 @@ void RecountObjectSlots(void) } } - guiNumObjectSlots = 0; + guiNumObjectSlots = 0; } -INT32 CreatePhysicalObject( OBJECTTYPE *pGameObj, real dLifeLength, real xPos, real yPos, real zPos, real xForce, real yForce, real zForce, UINT8 ubOwner, UINT8 ubActionCode, UINT32 uiActionData ) +INT32 CreatePhysicalObject( OBJECTTYPE *pGameObj, real dLifeLength, real xPos, real yPos, real zPos, real xForce, real yForce, real zForce, UINT8 ubOwner, UINT8 ubActionCode, UINT32 uiActionData, BOOLEAN fTestObject ) { INT32 iObjectIndex; FLOAT mass; @@ -185,7 +189,7 @@ INT32 CreatePhysicalObject( OBJECTTYPE *pGameObj, real dLifeLength, real xPos, r pObject->fAllocated = TRUE; pObject->fAlive = TRUE; pObject->fApplyFriction = FALSE; - pObject->iSoundID = NO_SAMPLE; + pObject->iSoundID = NO_SAMPLE; // Set values pObject->OneOverMass = 1 / mass; @@ -193,11 +197,12 @@ INT32 CreatePhysicalObject( OBJECTTYPE *pGameObj, real dLifeLength, real xPos, r pObject->Position.y = yPos; pObject->Position.z = zPos; pObject->fVisible = TRUE; + pObject->fTestObject = fTestObject; pObject->ubOwner = ubOwner; pObject->ubActionCode = ubActionCode; pObject->uiActionData = uiActionData; pObject->fDropItem = TRUE; - pObject->ubLastTargetTakenDamage = NOBODY; + pObject->ubLastTargetTakenDamage = NOBODY; pObject->fFirstTimeMoved = TRUE; @@ -207,7 +212,7 @@ INT32 CreatePhysicalObject( OBJECTTYPE *pGameObj, real dLifeLength, real xPos, r pObject->InitialForce = VDivScalar( &(pObject->InitialForce), (float)TIME_MULTI ); pObject->InitialForce = VMultScalar( &(pObject->InitialForce), 1.5 ); - + // Calculate gridNo pObject->sGridNo = MAPROWCOLTOPOS( ( (INT16)yPos / CELL_Y_SIZE ), ( (INT16)xPos / CELL_X_SIZE ) ); @@ -224,6 +229,13 @@ INT32 CreatePhysicalObject( OBJECTTYPE *pGameObj, real dLifeLength, real xPos, r PhysicsDebugMsg( String( "NewPhysics Object") ); + // If this is a real object being created, then increase the ABC + if (!fTestObject) + { + gTacticalStatus.ubAttackBusyCount++; + DebugAttackBusy( String( "@@@@@@@ Increasing attacker busy count..., PHYSICS OBJECT effect started. Now %d\n", gTacticalStatus.ubAttackBusyCount) ); + } + return( iObjectIndex ); } @@ -290,11 +302,11 @@ void SimulateObject( REAL_OBJECT *pObject, real deltaT ) if ( !PhysicsUpdateLife( pObject, (float)deltaT ) ) { -// DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"SimulateObject: don't update life, returning"); + // DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"SimulateObject: don't update life, returning"); return; } -// DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"SimulateObject: check life"); + // DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"SimulateObject: check life"); if ( pObject->fAlive ) { CurrentTime = 0; @@ -306,14 +318,14 @@ void SimulateObject( REAL_OBJECT *pObject, real deltaT ) if ( !PhysicsComputeForces( pObject ) ) { -// DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"SimulateObject: couldn't compute forces"); + // DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"SimulateObject: couldn't compute forces"); return; } while( CurrentTime < TargetTime ) { -//MADD TO KAIDEN: HERE IS THE PROBLEM: For some reason fEndThisObject is never set to true -// DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("SimulateObject: in loop while CurrentTime < TargetTime: %d < %d",CurrentTime,TargetTime)); + //MADD TO KAIDEN: HERE IS THE PROBLEM: For some reason fEndThisObject is never set to true + // DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("SimulateObject: in loop while CurrentTime < TargetTime: %d < %d",CurrentTime,TargetTime)); if ( !PhysicsIntegrate( pObject, DeltaTime ) ) { @@ -451,10 +463,10 @@ BOOLEAN PhysicsUpdateLife( REAL_OBJECT *pObject, real DeltaTime ) if ( !pObject->fTestObject ) { - if ( pObject->iSoundID != NO_SAMPLE ) - { - SoundStop( pObject->iSoundID ); - } + if ( pObject->iSoundID != NO_SAMPLE ) + { + SoundStop( pObject->iSoundID ); + } if ( pObject->ubActionCode == THROW_ARM_ITEM && !pObject->fInWater ) { @@ -463,7 +475,7 @@ BOOLEAN PhysicsUpdateLife( REAL_OBJECT *pObject, real DeltaTime ) else { // If we are in water, and we are a sinkable item... -// if ( !pObject->fInWater || !( Item[ pObject->Obj.usItem ].fFlags & ITEM_SINKS ) ) + // if ( !pObject->fInWater || !( Item[ pObject->Obj.usItem ].fFlags & ITEM_SINKS ) ) if ( !pObject->fInWater || !( Item[ pObject->Obj.usItem ].sinks ) ) { if ( pObject->fDropItem ) @@ -475,7 +487,7 @@ BOOLEAN PhysicsUpdateLife( REAL_OBJECT *pObject, real DeltaTime ) } // ATE: Yet another hack here, to make sure things don't fall through roofs - if ( pObject->ubLastTargetTakenDamage != NOBODY ) + if ( pObject->ubLastTargetTakenDamage != NOBODY ) { SOLDIERTYPE *pSoldier; @@ -509,7 +521,8 @@ BOOLEAN PhysicsUpdateLife( REAL_OBJECT *pObject, real DeltaTime ) } DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., PHYSICS OBJECT DONE effect gone off") ); - ReduceAttackBusyCount( pObject->ubOwner, FALSE ); + DebugAttackBusy( "@@@@@@@ PHYSICS OBJECT effect finished\n" ); + ReduceAttackBusyCount( ); // ATE: Handle end of animation... if ( pObject->fCatchAnimOn ) @@ -524,17 +537,17 @@ BOOLEAN PhysicsUpdateLife( REAL_OBJECT *pObject, real DeltaTime ) // Catch anim..... switch( gAnimControl[ pSoldier->usAnimState ].ubHeight ) { - case ANIM_STAND: + case ANIM_STAND: - pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; - EVENT_InitNewSoldierAnim( pSoldier, END_CATCH, 0 , FALSE ); - break; + pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; + EVENT_InitNewSoldierAnim( pSoldier, END_CATCH, 0 , FALSE ); + break; - case ANIM_CROUCH: + case ANIM_CROUCH: - pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; - EVENT_InitNewSoldierAnim( pSoldier, END_CROUCH_CATCH, 0 , FALSE ); - break; + pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; + EVENT_InitNewSoldierAnim( pSoldier, END_CROUCH_CATCH, 0 , FALSE ); + break; } PlayJA2Sample( CATCH_OBJECT, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); @@ -570,27 +583,28 @@ BOOLEAN PhysicsIntegrate( REAL_OBJECT *pObject, real DeltaTime ) vTemp = VMultScalar( &(pObject->Force), ( DeltaTime * pObject->OneOverMass ) ); pObject->Velocity = VAdd( &(pObject->Velocity), &vTemp ); - if ( pObject->fPotentialForDebug ) - { - PhysicsDebugMsg( String( "Object %d: Force %f %f %f", pObject->iID, pObject->Force.x, pObject->Force.y, pObject->Force.z ) ); - PhysicsDebugMsg( String( "Object %d: Velocity %f %f %f", pObject->iID, pObject->Velocity.x, pObject->Velocity.y, pObject->Velocity.z ) ); - PhysicsDebugMsg( String( "Object %d: Position %f %f %f", pObject->iID, pObject->Position.x, pObject->Position.y, pObject->Position.z ) ); - PhysicsDebugMsg( String( "Object %d: Delta Pos %f %f %f", pObject->iID, (pObject->OldPosition.x - pObject->Position.x ), (pObject->OldPosition.y - pObject->Position.y ), ( pObject->OldPosition.z - pObject->Position.z ) ) ); - } + if ( pObject->fPotentialForDebug ) + { + PhysicsDebugMsg( String( "Object %d: Force %f %f %f", pObject->iID, pObject->Force.x, pObject->Force.y, pObject->Force.z ) ); + PhysicsDebugMsg( String( "Object %d: Velocity %f %f %f", pObject->iID, pObject->Velocity.x, pObject->Velocity.y, pObject->Velocity.z ) ); + PhysicsDebugMsg( String( "Object %d: Position %f %f %f", pObject->iID, pObject->Position.x, pObject->Position.y, pObject->Position.z ) ); + PhysicsDebugMsg( String( "Object %d: Delta Pos %f %f %f", pObject->iID, (pObject->OldPosition.x - pObject->Position.x ), (pObject->OldPosition.y - pObject->Position.y ), ( pObject->OldPosition.z - pObject->Position.z ) ) ); + } -// if ( pObject->Obj.usItem == MORTAR_SHELL && !pObject->fTestObject && pObject->ubActionCode == THROW_ARM_ITEM ) -//DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 524, usItemClass=%d",Item[pObject->Obj.usItem].usItemClass)); - if ( Item[pObject->Obj.usItem].usItemClass == IC_BOMB && !pObject->fTestObject && pObject->ubActionCode == THROW_ARM_ITEM ) - { - // Start soud if we have reached our max height - if ( pObject->OldVelocity.z >= 0 && pObject->Velocity.z < 0 ) - { - if ( pObject->iSoundID == NO_SAMPLE ) - { - pObject->iSoundID = PlayJA2Sample( MORTAR_WHISTLE, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); - } - } - } + // if ( pObject->Obj.usItem == MORTAR_SHELL && !pObject->fTestObject && pObject->ubActionCode == THROW_ARM_ITEM ) + //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 524, usItemClass=%d",Item[pObject->Obj.usItem].usItemClass)); + + if ( Item[pObject->Obj.usItem].usItemClass == IC_BOMB && !pObject->fTestObject && pObject->ubActionCode == THROW_ARM_ITEM ) + { + // Start soud if we have reached our max height + if ( pObject->OldVelocity.z >= 0 && pObject->Velocity.z < 0 ) + { + if ( pObject->iSoundID == NO_SAMPLE ) + { + pObject->iSoundID = PlayJA2Sample( MORTAR_WHISTLE, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN ); + } + } + } return( TRUE ); } @@ -609,7 +623,7 @@ BOOLEAN PhysicsHandleCollisions( REAL_OBJECT *pObject, INT32 *piCollisionID, rea dDeltaZ = pObject->Position.z - pObject->OldPosition.z; if ( dDeltaX <= EPSILONV && dDeltaX >= -EPSILONV && - dDeltaY <= EPSILONV && dDeltaY >= -EPSILONV ) + dDeltaY <= EPSILONV && dDeltaY >= -EPSILONV ) { pObject->sConsecutiveZeroVelocityCollisions++; } @@ -651,11 +665,11 @@ BOOLEAN PhysicsHandleCollisions( REAL_OBJECT *pObject, INT32 *piCollisionID, rea //otherwise, continue falling downwards! // TO STOP? - + // Check for delta position values if ( dDeltaZ <= EPSILONP && dDeltaZ >= -EPSILONP && - dDeltaY <= EPSILONP && dDeltaY >= -EPSILONP && - dDeltaX <= EPSILONP && dDeltaX >= -EPSILONP ) + dDeltaY <= EPSILONP && dDeltaY >= -EPSILONP && + dDeltaX <= EPSILONP && dDeltaX >= -EPSILONP ) { //pObject->fAlive = FALSE; //return( FALSE ); @@ -674,12 +688,12 @@ BOOLEAN PhysicsHandleCollisions( REAL_OBJECT *pObject, INT32 *piCollisionID, rea // Check for -ve velocity still... /*if ( pObject->Velocity.z <= EPSILONV && pObject->Velocity.z >= -EPSILONV && - pObject->Velocity.y <= EPSILONV && pObject->Velocity.y >= -EPSILONV && - pObject->Velocity.x <= EPSILONV && pObject->Velocity.x >= -EPSILONV ) + pObject->Velocity.y <= EPSILONV && pObject->Velocity.y >= -EPSILONV && + pObject->Velocity.x <= EPSILONV && pObject->Velocity.x >= -EPSILONV ) { - PhysicsDeleteObject( pObject ); - pObject->fAlive = FALSE; - return( FALSE ); + PhysicsDeleteObject( pObject ); + pObject->fAlive = FALSE; + return( FALSE ); }*/ } @@ -782,123 +796,123 @@ BOOLEAN PhysicsCheckForCollisions( REAL_OBJECT *pObject, INT32 *piCollisionID ) if ( pObject->fTestObject == TEST_OBJECT_NOTWALLROOF_COLLISIONS ) { // So we don't collide with ourselves..... - if ( iCollisionCode != COLLISION_WATER && iCollisionCode != COLLISION_GROUND && iCollisionCode != COLLISION_NONE && - iCollisionCode != COLLISION_ROOF && iCollisionCode != COLLISION_INTERIOR_ROOF && - iCollisionCode != COLLISION_WALL_SOUTHEAST && iCollisionCode != COLLISION_WALL_SOUTHWEST && - iCollisionCode != COLLISION_WALL_NORTHEAST && iCollisionCode != COLLISION_WALL_NORTHWEST ) - { - if ( pObject->fFirstTimeMoved || pObject->sFirstGridNo == pObject->sGridNo ) - { - iCollisionCode = COLLISION_NONE; - } + if ( iCollisionCode != COLLISION_WATER && iCollisionCode != COLLISION_GROUND && iCollisionCode != COLLISION_NONE && + iCollisionCode != COLLISION_ROOF && iCollisionCode != COLLISION_INTERIOR_ROOF && + iCollisionCode != COLLISION_WALL_SOUTHEAST && iCollisionCode != COLLISION_WALL_SOUTHWEST && + iCollisionCode != COLLISION_WALL_NORTHEAST && iCollisionCode != COLLISION_WALL_NORTHWEST ) + { + if ( pObject->fFirstTimeMoved || pObject->sFirstGridNo == pObject->sGridNo ) + { + iCollisionCode = COLLISION_NONE; + } - // If we are NOT a wall or window, ignore.... - if ( pObject->uiNumTilesMoved < 4 ) - { - switch( iCollisionCode ) - { - case COLLISION_MERC: - case COLLISION_STRUCTURE: - case COLLISION_STRUCTURE_Z: + // If we are NOT a wall or window, ignore.... + if ( pObject->uiNumTilesMoved < 4 ) + { + switch( iCollisionCode ) + { + case COLLISION_MERC: + case COLLISION_STRUCTURE: + case COLLISION_STRUCTURE_Z: - // Set to no collision ( we shot past ) - iCollisionCode = COLLISION_NONE; - break; - } - } - } + // Set to no collision ( we shot past ) + iCollisionCode = COLLISION_NONE; + break; + } + } + } switch( iCollisionCode ) { // End test with any collision NOT a wall, roof... - case COLLISION_STRUCTURE: - case COLLISION_STRUCTURE_Z: + case COLLISION_STRUCTURE: + case COLLISION_STRUCTURE_Z: - // OK, if it's mercs... don't stop - if ( usStructureID >= INVALID_STRUCTURE_ID ) - { - pObject->fTestEndedWithCollision = TRUE; - - if ( !pObject->fEndedWithCollisionPositionSet ) - { - pObject->fEndedWithCollisionPositionSet = TRUE; - pObject->EndedWithCollisionPosition = VSetEqual( &(pObject->Position) ); - } - iCollisionCode = COLLISION_NONE; - } - else - { - if ( !pObject->fEndedWithCollisionPositionSet ) - { - pObject->fEndedWithCollisionPositionSet = TRUE; - pObject->EndedWithCollisionPosition = VSetEqual( &(pObject->Position) ); - } - } - break; - - case COLLISION_ROOF: + // OK, if it's mercs... don't stop + if ( usStructureID >= INVALID_STRUCTURE_ID ) + { + pObject->fTestEndedWithCollision = TRUE; if ( !pObject->fEndedWithCollisionPositionSet ) { pObject->fEndedWithCollisionPositionSet = TRUE; pObject->EndedWithCollisionPosition = VSetEqual( &(pObject->Position) ); } - break; + iCollisionCode = COLLISION_NONE; + } + else + { + if ( !pObject->fEndedWithCollisionPositionSet ) + { + pObject->fEndedWithCollisionPositionSet = TRUE; + pObject->EndedWithCollisionPosition = VSetEqual( &(pObject->Position) ); + } + } + break; - case COLLISION_WATER: - case COLLISION_GROUND: - case COLLISION_MERC: - case COLLISION_INTERIOR_ROOF: - case COLLISION_NONE: - case COLLISION_WINDOW_SOUTHEAST: - case COLLISION_WINDOW_SOUTHWEST: - case COLLISION_WINDOW_NORTHEAST: - case COLLISION_WINDOW_NORTHWEST: + case COLLISION_ROOF: - // Here we just keep going.. - break; + if ( !pObject->fEndedWithCollisionPositionSet ) + { + pObject->fEndedWithCollisionPositionSet = TRUE; + pObject->EndedWithCollisionPosition = VSetEqual( &(pObject->Position) ); + } + break; - default: - - // THis is for walls, windows, etc - // here, we set test ended with collision, but keep going... - pObject->fTestEndedWithCollision = TRUE; - break; - } + case COLLISION_WATER: + case COLLISION_GROUND: + case COLLISION_MERC: + case COLLISION_INTERIOR_ROOF: + case COLLISION_NONE: + case COLLISION_WINDOW_SOUTHEAST: + case COLLISION_WINDOW_SOUTHWEST: + case COLLISION_WINDOW_NORTHEAST: + case COLLISION_WINDOW_NORTHWEST: + + // Here we just keep going.. + break; + + default: + + // THis is for walls, windows, etc + // here, we set test ended with collision, but keep going... + pObject->fTestEndedWithCollision = TRUE; + break; + } } if ( pObject->fTestObject != TEST_OBJECT_NOTWALLROOF_COLLISIONS ) { - if ( iCollisionCode != COLLISION_WATER && iCollisionCode != COLLISION_GROUND && iCollisionCode != COLLISION_NONE && - iCollisionCode != COLLISION_ROOF && iCollisionCode != COLLISION_INTERIOR_ROOF && - iCollisionCode != COLLISION_WALL_SOUTHEAST && iCollisionCode != COLLISION_WALL_SOUTHWEST && - iCollisionCode != COLLISION_WALL_NORTHEAST && iCollisionCode != COLLISION_WALL_NORTHWEST ) - { - // So we don't collide with ourselves..... - if ( pObject->fFirstTimeMoved || pObject->sFirstGridNo == pObject->sGridNo ) - { - iCollisionCode = COLLISION_NONE; - } + if ( iCollisionCode != COLLISION_WATER && iCollisionCode != COLLISION_GROUND && iCollisionCode != COLLISION_NONE && + iCollisionCode != COLLISION_ROOF && iCollisionCode != COLLISION_INTERIOR_ROOF && + iCollisionCode != COLLISION_WALL_SOUTHEAST && iCollisionCode != COLLISION_WALL_SOUTHWEST && + iCollisionCode != COLLISION_WALL_NORTHEAST && iCollisionCode != COLLISION_WALL_NORTHWEST ) + { + // So we don't collide with ourselves..... + if ( pObject->fFirstTimeMoved || pObject->sFirstGridNo == pObject->sGridNo ) + { + iCollisionCode = COLLISION_NONE; + } - // If we are NOT a wall or window, ignore.... - if ( pObject->uiNumTilesMoved < 4 ) - { - switch( iCollisionCode ) - { - case COLLISION_MERC: - case COLLISION_STRUCTURE: - case COLLISION_STRUCTURE_Z: + // If we are NOT a wall or window, ignore.... + if ( pObject->uiNumTilesMoved < 4 ) + { + switch( iCollisionCode ) + { + case COLLISION_MERC: + case COLLISION_STRUCTURE: + case COLLISION_STRUCTURE_Z: - // Set to no collision ( we shot past ) - iCollisionCode = COLLISION_NONE; - break; - } - } + // Set to no collision ( we shot past ) + iCollisionCode = COLLISION_NONE; + break; + } + } - } - } + } + } *piCollisionID = iCollisionCode; @@ -927,7 +941,7 @@ BOOLEAN PhysicsCheckForCollisions( REAL_OBJECT *pObject, INT32 *piCollisionID ) ObjectHitWindow( sGridNo, usStructureID, FALSE, TRUE ); } *piCollisionID = COLLISION_NONE; - return( FALSE ); + return( FALSE ); } // ATE: IF detonate on impact, stop now! @@ -1002,6 +1016,8 @@ BOOLEAN PhysicsCheckForCollisions( REAL_OBJECT *pObject, INT32 *piCollisionID ) if ( pObject->ubActionCode == THROW_ARM_ITEM ) { + gTacticalStatus.ubAttackBusyCount++; + DebugAttackBusy( String( "Incrementing attack busy because of delayed water explosion. Now %d\n", gTacticalStatus.ubAttackBusyCount ) ); AniParams.ubKeyFrame1 = 11; AniParams.uiKeyFrame1Code = ANI_KEYFRAME_CHAIN_WATER_EXPLOSION; AniParams.uiUserData = pObject->Obj.usItem; @@ -1038,7 +1054,7 @@ BOOLEAN PhysicsCheckForCollisions( REAL_OBJECT *pObject, INT32 *piCollisionID ) //{ // vTemp.x = 0; // vTemp.y = 0; - // vTemp.z = 1; + // vTemp.z = 1; // pObject->fApplyFriction = TRUE; // pObject->AppliedMu = (float)(0.54 * TIME_MULTI ); @@ -1055,7 +1071,7 @@ BOOLEAN PhysicsCheckForCollisions( REAL_OBJECT *pObject, INT32 *piCollisionID ) return( FALSE ); } - CheckForObjectHittingMerc( pObject, usStructureID ); + CheckForObjectHittingMerc( pObject, usStructureID ); vTemp.x = 0; vTemp.y = 0; @@ -1090,13 +1106,13 @@ BOOLEAN PhysicsCheckForCollisions( REAL_OBJECT *pObject, INT32 *piCollisionID ) return( FALSE ); } - CheckForObjectHittingMerc( pObject, usStructureID ); + CheckForObjectHittingMerc( pObject, usStructureID ); vIncident.x = dDeltaX; vIncident.y = dDeltaY; vIncident.z = 0; // Nomralize - + vIncident = VGetNormal( &vIncident ); //vTemp.x = -1; @@ -1113,24 +1129,24 @@ BOOLEAN PhysicsCheckForCollisions( REAL_OBJECT *pObject, INT32 *piCollisionID ) if ( fDoCollision ) { - pObject->CollisionNormal.x = vTemp.x; - pObject->CollisionNormal.y = vTemp.y; - pObject->CollisionNormal.z = vTemp.z; - pObject->CollisionElasticity = dElasity; - pObject->iOldCollisionCode = iCollisionCode; + pObject->CollisionNormal.x = vTemp.x; + pObject->CollisionNormal.y = vTemp.y; + pObject->CollisionNormal.z = vTemp.z; + pObject->CollisionElasticity = dElasity; + pObject->iOldCollisionCode = iCollisionCode; - // Save collision velocity - pObject->CollisionVelocity = VSetEqual( &(pObject->OldVelocity) ); + // Save collision velocity + pObject->CollisionVelocity = VSetEqual( &(pObject->OldVelocity) ); - if ( pObject->fPotentialForDebug ) - { - PhysicsDebugMsg( String( "Object %d: Collision %d", pObject->iID, iCollisionCode ) ); - PhysicsDebugMsg( String( "Object %d: Collision Normal %f %f %f", pObject->iID, vTemp.x, vTemp.y, vTemp.z ) ); - PhysicsDebugMsg( String( "Object %d: Collision OldPos %f %f %f", pObject->iID, pObject->Position.x, pObject->Position.y, pObject->Position.z ) ); - PhysicsDebugMsg( String( "Object %d: Collision Velocity %f %f %f", pObject->iID, pObject->CollisionVelocity.x, pObject->CollisionVelocity.y, pObject->CollisionVelocity.z ) ); - } + if ( pObject->fPotentialForDebug ) + { + PhysicsDebugMsg( String( "Object %d: Collision %d", pObject->iID, iCollisionCode ) ); + PhysicsDebugMsg( String( "Object %d: Collision Normal %f %f %f", pObject->iID, vTemp.x, vTemp.y, vTemp.z ) ); + PhysicsDebugMsg( String( "Object %d: Collision OldPos %f %f %f", pObject->iID, pObject->Position.x, pObject->Position.y, pObject->Position.z ) ); + PhysicsDebugMsg( String( "Object %d: Collision Velocity %f %f %f", pObject->iID, pObject->CollisionVelocity.x, pObject->CollisionVelocity.y, pObject->CollisionVelocity.z ) ); + } - pObject->fColliding = TRUE; + pObject->fColliding = TRUE; } else @@ -1150,7 +1166,7 @@ void PhysicsResolveCollision( REAL_OBJECT *pObject, vector_3 *pVelocity, vector_ { real ImpulseNumerator, Impulse; vector_3 vTemp; - + ImpulseNumerator = -1 * CoefficientOfRestitution * VDotProduct( pVelocity , pNormal ); Impulse = ImpulseNumerator; @@ -1165,10 +1181,10 @@ BOOLEAN PhysicsMoveObject( REAL_OBJECT *pObject ) { LEVELNODE *pNode; INT16 sNewGridNo, sTileIndex; - ETRLEObject *pTrav; + ETRLEObject *pTrav; HVOBJECT hVObject; - + //Determine new gridno sNewGridNo = MAPROWCOLTOPOS( ( (INT16)pObject->Position.y / CELL_Y_SIZE ), ( (INT16)pObject->Position.x / CELL_X_SIZE ) ); @@ -1199,8 +1215,9 @@ BOOLEAN PhysicsMoveObject( REAL_OBJECT *pObject ) if ( pObject->fVisible ) { // Add smoke trails... -// if ( pObject->Obj.usItem == MORTAR_SHELL && pObject->uiNumTilesMoved > 2 && pObject->ubActionCode == THROW_ARM_ITEM ) - //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 1147")); + // if ( pObject->Obj.usItem == MORTAR_SHELL && pObject->uiNumTilesMoved > 2 && pObject->ubActionCode == THROW_ARM_ITEM ) + //DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 1147")); + if ( Item[pObject->Obj.usItem].usItemClass == IC_BOMB && pObject->uiNumTilesMoved > 2 && pObject->ubActionCode == THROW_ARM_ITEM ) { if ( sNewGridNo != pObject->sGridNo ) @@ -1223,45 +1240,45 @@ BOOLEAN PhysicsMoveObject( REAL_OBJECT *pObject ) } else if ( pObject->uiNumTilesMoved > 0 ) { - if ( sNewGridNo != pObject->sGridNo ) - { - // We're at a new gridno! - if ( pObject->pNode != NULL ) - { - RemoveStructFromLevelNode( pObject->sLevelNodeGridNo, pObject->pNode ); - } + if ( sNewGridNo != pObject->sGridNo ) + { + // We're at a new gridno! + if ( pObject->pNode != NULL ) + { + RemoveStructFromLevelNode( pObject->sLevelNodeGridNo, pObject->pNode ); + } - // We're at a new gridno! - if ( pObject->pShadow != NULL ) - { - RemoveShadowFromLevelNode( pObject->sLevelNodeGridNo, pObject->pShadow ); - } + // We're at a new gridno! + if ( pObject->pShadow != NULL ) + { + RemoveShadowFromLevelNode( pObject->sLevelNodeGridNo, pObject->pShadow ); + } - // Now get graphic index - sTileIndex = GetTileGraphicForItem( &(Item[ pObject->Obj.usItem ] ) ); - //sTileIndex = BULLETTILE1; + // Now get graphic index + sTileIndex = GetTileGraphicForItem( &(Item[ pObject->Obj.usItem ] ) ); + //sTileIndex = BULLETTILE1; - // Set new gridno, add - pNode = AddStructToTail( sNewGridNo, sTileIndex ); - pNode->ubShadeLevel=DEFAULT_SHADE_LEVEL; - pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL; - pNode->uiFlags |= ( LEVELNODE_USEABSOLUTEPOS | LEVELNODE_IGNOREHEIGHT | LEVELNODE_PHYSICSOBJECT | LEVELNODE_DYNAMIC ); + // Set new gridno, add + pNode = AddStructToTail( sNewGridNo, sTileIndex ); + pNode->ubShadeLevel=DEFAULT_SHADE_LEVEL; + pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL; + pNode->uiFlags |= ( LEVELNODE_USEABSOLUTEPOS | LEVELNODE_IGNOREHEIGHT | LEVELNODE_PHYSICSOBJECT | LEVELNODE_DYNAMIC ); - // Set levelnode - pObject->pNode = pNode; + // Set levelnode + pObject->pNode = pNode; - // Add shadow - AddShadowToHead( sNewGridNo, sTileIndex ); - pNode = gpWorldLevelData[ sNewGridNo ].pShadowHead; - pNode->ubShadeLevel=DEFAULT_SHADE_LEVEL; - pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL; - pNode->uiFlags |= ( LEVELNODE_USEABSOLUTEPOS | LEVELNODE_IGNOREHEIGHT | LEVELNODE_PHYSICSOBJECT | LEVELNODE_DYNAMIC ); + // Add shadow + AddShadowToHead( sNewGridNo, sTileIndex ); + pNode = gpWorldLevelData[ sNewGridNo ].pShadowHead; + pNode->ubShadeLevel=DEFAULT_SHADE_LEVEL; + pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL; + pNode->uiFlags |= ( LEVELNODE_USEABSOLUTEPOS | LEVELNODE_IGNOREHEIGHT | LEVELNODE_PHYSICSOBJECT | LEVELNODE_DYNAMIC ); - // Set levelnode - pObject->pShadow = pNode; + // Set levelnode + pObject->pShadow = pNode; - pObject->sLevelNodeGridNo = sNewGridNo; - } + pObject->sLevelNodeGridNo = sNewGridNo; + } } } else @@ -1282,23 +1299,24 @@ BOOLEAN PhysicsMoveObject( REAL_OBJECT *pObject ) pObject->pShadow = NULL; } - if ( sNewGridNo != pObject->sGridNo ) - { - pObject->uiNumTilesMoved++; - } + if ( sNewGridNo != pObject->sGridNo ) + { + pObject->uiNumTilesMoved++; + } pObject->sGridNo = sNewGridNo; - if ( pObject->fPotentialForDebug ) - { - PhysicsDebugMsg( String( "Object %d: uiNumTilesMoved: %d", pObject->iID, pObject->uiNumTilesMoved ) ); - } + if ( pObject->fPotentialForDebug ) + { + PhysicsDebugMsg( String( "Object %d: uiNumTilesMoved: %d", pObject->iID, pObject->uiNumTilesMoved ) ); + } } if ( pObject->fVisible ) { -// if ( pObject->Obj.usItem != MORTAR_SHELL || pObject->ubActionCode != THROW_ARM_ITEM ) - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 1238")); + // if ( pObject->Obj.usItem != MORTAR_SHELL || pObject->ubActionCode != THROW_ARM_ITEM ) + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 1238")); + if ( !(Item[pObject->Obj.usItem].usItemClass == IC_BOMB) || pObject->ubActionCode != THROW_ARM_ITEM ) { if ( pObject->pNode != NULL ) @@ -1330,7 +1348,7 @@ BOOLEAN PhysicsMoveObject( REAL_OBJECT *pObject ) { LEVELNODE *pNode; INT16 sNewGridNo; - + //Determine new gridno sNewGridNo = MAPROWCOLTOPOS( ( pObject->Position.y / CELL_Y_SIZE ), ( pObject->Position.x / CELL_X_SIZE ) ); @@ -1432,7 +1450,7 @@ vector_3 FindBestForceForTrajectory( INT16 sSrcGridNo, INT16 sGridNo,INT16 sStar // What's the diff? dTestDiff = dTestRange - dRange; - + // How have we done? // < 5% off... if ( fabs( ( dTestDiff / dRange ) ) < .01 ) @@ -1568,7 +1586,7 @@ real FindBestAngleForTrajectory( INT16 sSrcGridNo, INT16 sGridNo,INT16 sStartZ, // What's the diff? dTestDiff = dTestRange - dRange; - + // How have we done? // < 5% off... if ( fabs( (FLOAT)( dTestDiff / dRange ) ) < .05 ) @@ -1678,7 +1696,7 @@ FLOAT CalculateObjectTrajectory( INT16 sTargetZ, OBJECTTYPE *pItem, vector_3 *vP DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalculateObjectTrajectory: createphysicalobject"); // OK, create a physics object.... - iID = CreatePhysicalObject( pItem, -1, vPosition->x, vPosition->y, vPosition->z, vForce->x, vForce->y, vForce->z, NOBODY, NO_THROW_ACTION, 0 ); + iID = CreatePhysicalObject( pItem, -1, vPosition->x, vPosition->y, vPosition->z, vForce->x, vForce->y, vForce->z, NOBODY, NO_THROW_ACTION, 0, TEST_OBJECT_NO_COLLISIONS ); if ( iID == -1 ) { @@ -1699,7 +1717,7 @@ FLOAT CalculateObjectTrajectory( INT16 sTargetZ, OBJECTTYPE *pItem, vector_3 *vP while( pObject->fAlive ) { //cnt = cnt + 1; - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalculateObjectTrajectory: calling simulateobject - this object never fucking dies!!!!"); + // DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalculateObjectTrajectory: calling simulateobject - this object never fucking dies!!!!"); SimulateObject( pObject, (float)DELTA_T ); } @@ -1720,7 +1738,7 @@ FLOAT CalculateObjectTrajectory( INT16 sTargetZ, OBJECTTYPE *pItem, vector_3 *vP DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalculateObjectTrajectory: done"); return( (FLOAT)sqrt( ( dDiffX * dDiffX ) + ( dDiffY * dDiffY ) ) ); - + } @@ -1730,7 +1748,7 @@ INT32 ChanceToGetThroughObjectTrajectory( INT16 sTargetZ, OBJECTTYPE *pItem, vec REAL_OBJECT *pObject; // OK, create a physics object.... - iID = CreatePhysicalObject( pItem, -1, vPosition->x, vPosition->y, vPosition->z, vForce->x, vForce->y, vForce->z, NOBODY, NO_THROW_ACTION, 0 ); + iID = CreatePhysicalObject( pItem, -1, vPosition->x, vPosition->y, vPosition->z, vForce->x, vForce->y, vForce->z, NOBODY, NO_THROW_ACTION, 0, TEST_OBJECT_NOTWALLROOF_COLLISIONS ); if ( iID == -1 ) { @@ -1744,7 +1762,7 @@ INT32 ChanceToGetThroughObjectTrajectory( INT16 sTargetZ, OBJECTTYPE *pItem, vec pObject->fTestPositionNotSet = TRUE; pObject->TestZTarget = sTargetZ; pObject->fVisible = FALSE; - //pObject->fPotentialForDebug = TRUE; + //pObject->fPotentialForDebug = TRUE; // Alrighty, move this beast until it dies.... while( pObject->fAlive ) @@ -1755,20 +1773,20 @@ INT32 ChanceToGetThroughObjectTrajectory( INT16 sTargetZ, OBJECTTYPE *pItem, vec if ( psNewGridNo != NULL ) { - // Calculate gridno from last position + // Calculate gridno from last position - // If NOT from UI, use exact collision position + // If NOT from UI, use exact collision position // JA25 comment from CJC: testing breaklights, we ran into a situation where EndedWithCollisionPosition was not // set due to breaklight stopping on flat ground. It makes sense that if EndedWithCollisionPosition is // unset, at least the Position value is of SOME use... - if ( fFromUI || (pObject->EndedWithCollisionPosition.x == 0.0f && pObject->EndedWithCollisionPosition.y == 0.0f) ) - { - (*psNewGridNo) = MAPROWCOLTOPOS( ( (INT16)pObject->Position.y / CELL_Y_SIZE ), ( (INT16)pObject->Position.x / CELL_X_SIZE ) ); - } - else - { - (*psNewGridNo) = MAPROWCOLTOPOS( ( (INT16)pObject->EndedWithCollisionPosition.y / CELL_Y_SIZE ), ( (INT16)pObject->EndedWithCollisionPosition.x / CELL_X_SIZE ) ); - } + if ( fFromUI || (pObject->EndedWithCollisionPosition.x == 0.0f && pObject->EndedWithCollisionPosition.y == 0.0f) ) + { + (*psNewGridNo) = MAPROWCOLTOPOS( ( (INT16)pObject->Position.y / CELL_Y_SIZE ), ( (INT16)pObject->Position.x / CELL_X_SIZE ) ); + } + else + { + (*psNewGridNo) = MAPROWCOLTOPOS( ( (INT16)pObject->EndedWithCollisionPosition.y / CELL_Y_SIZE ), ( (INT16)pObject->EndedWithCollisionPosition.x / CELL_X_SIZE ) ); + } (*pbLevel) = GET_OBJECT_LEVEL( pObject->EndedWithCollisionPosition.z - CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[ (*psNewGridNo) ].sHeight ) ); } @@ -1781,7 +1799,7 @@ INT32 ChanceToGetThroughObjectTrajectory( INT16 sTargetZ, OBJECTTYPE *pItem, vec return( 0 ); } return( 100 ); - + } @@ -1823,17 +1841,17 @@ void CalculateLaunchItemBasicParams( SOLDIERTYPE *pSoldier, OBJECTTYPE *pItem, I // Are we armed, and are we throwing a LAUNCHABLE? usLauncher = GetLauncherFromLaunchable( pItem->usItem ); -DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 1741")); + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 1741")); if ( fArmed && ( Item[usLauncher].mortar || Item[pItem->usItem].mortar ) ) { - // Start at 0.... - sStartZ = ( pSoldier->bLevel * 256 ); - fMortar = TRUE; - sMinRange = MIN_MORTAR_RANGE; - //fLauncher = TRUE; + // Start at 0.... + sStartZ = ( pSoldier->bLevel * 256 ); + fMortar = TRUE; + sMinRange = MIN_MORTAR_RANGE; + //fLauncher = TRUE; } -DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 1750")); - + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 1750")); + if ( fArmed && ( Item[usLauncher].grenadelauncher || Item[pItem->usItem].grenadelauncher ) ) { // OK, look at target level and decide angle to use... @@ -1903,10 +1921,10 @@ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 1750")); if ( sInterGridNo != NOWHERE ) { - // IF so, adjust target height, gridno.... - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Through a window!" ); + // IF so, adjust target height, gridno.... + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Through a window!" ); - fThroughIntermediateGridNo = TRUE; + fThroughIntermediateGridNo = TRUE; } if ( !fLauncher ) @@ -1954,7 +1972,7 @@ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 1750")); { dMagForce = (float)( dMagForce * 1.25 ); } - + FindTrajectory( pSoldier->sGridNo, sGridNo, sStartZ, sEndZ, dMagForce, dDegrees, pItem, psFinalGridNo ); if ( ubLevel == 1 && !fThroughIntermediateGridNo ) @@ -1965,12 +1983,12 @@ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 1750")); dMagForce = (float)( dMagForce * 0.85 ); // Yep, try to get angle... - dNewDegrees = FindBestAngleForTrajectory( pSoldier->sGridNo, sGridNo, GET_SOLDIER_THROW_HEIGHT( pSoldier->bLevel ), 150, dMagForce, pItem, psFinalGridNo ); + dNewDegrees = FindBestAngleForTrajectory( pSoldier->sGridNo, sGridNo, GET_SOLDIER_THROW_HEIGHT( pSoldier->bLevel ), 150, dMagForce, pItem, psFinalGridNo ); - if ( dNewDegrees != 0 ) - { - dDegrees = dNewDegrees; - } + if ( dNewDegrees != 0 ) + { + dDegrees = dNewDegrees; + } } } @@ -2032,10 +2050,10 @@ BOOLEAN CalculateLaunchItemChanceToGetThrough( SOLDIERTYPE *pSoldier, OBJECTTYPE return( FALSE ); } - if ( !fFromUI && (*psFinalGridNo) != sGridNo ) - { - return( FALSE ); - } + if ( !fFromUI && (*psFinalGridNo) != sGridNo ) + { + return( FALSE ); + } return( TRUE ); } @@ -2069,7 +2087,7 @@ FLOAT CalculateSoldierMaxForce( SOLDIERTYPE *pSoldier, FLOAT dDegrees , OBJECTTY INT32 uiMaxRange; FLOAT dMagForce; - + dDegrees = (FLOAT)( PI/4 ); uiMaxRange = CalcMaxTossRange( pSoldier, pItem->usItem, fArmed ); @@ -2094,10 +2112,10 @@ void CalculateLaunchItemParamsForThrow( SOLDIERTYPE *pSoldier, INT16 sGridNo, UI BOOLEAN fArmed = FALSE; UINT16 usLauncher; INT16 sStartZ; - INT8 bMinMissRadius, bMaxMissRadius, bMaxRadius; - FLOAT fScale; + INT8 bMinMissRadius, bMaxMissRadius, bMaxRadius; + FLOAT fScale; - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalculateLaunchItemParamsForThrow"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalculateLaunchItemParamsForThrow"); // Set target ID if anyone pSoldier->ubTargetID = WhoIsThere2( sGridNo, ubLevel ); @@ -2113,10 +2131,10 @@ void CalculateLaunchItemParamsForThrow( SOLDIERTYPE *pSoldier, INT16 sGridNo, UI bMissBy = 0; } - //if ( 0 ) + //if ( 0 ) if ( bMissBy > 0 ) { - // Max the miss variance + // Max the miss variance if ( bMissBy > MAX_MISS_BY ) { bMissBy = MAX_MISS_BY; @@ -2133,43 +2151,43 @@ void CalculateLaunchItemParamsForThrow( SOLDIERTYPE *pSoldier, INT16 sGridNo, UI ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Throw miss by: %d", bMissBy ); #endif - // Default to max radius... - bMaxRadius = 5; + // Default to max radius... + bMaxRadius = 5; - // scale if pyth spaces away is too far - if ( PythSpacesAway( sGridNo, pSoldier->sGridNo ) < ( (float)bMaxRadius / (float)1.5 ) ) - { - bMaxRadius = PythSpacesAway( sGridNo, pSoldier->sGridNo ) / 2; - } + // scale if pyth spaces away is too far + if ( PythSpacesAway( sGridNo, pSoldier->sGridNo ) < ( (float)bMaxRadius / (float)1.5 ) ) + { + bMaxRadius = PythSpacesAway( sGridNo, pSoldier->sGridNo ) / 2; + } - // Get radius - fScale = ( (float)bMissBy / (float) MAX_MISS_BY ); + // Get radius + fScale = ( (float)bMissBy / (float) MAX_MISS_BY ); - bMaxMissRadius = (INT8)( bMaxRadius * fScale ); + bMaxMissRadius = (INT8)( bMaxRadius * fScale ); - // Limit max radius... - if ( bMaxMissRadius > 4 ) - { - bMaxMissRadius = 4; - } + // Limit max radius... + if ( bMaxMissRadius > 4 ) + { + bMaxMissRadius = 4; + } - bMinMissRadius = bMaxMissRadius - 1; + bMinMissRadius = bMaxMissRadius - 1; - if ( bMinMissRadius < 2 ) - { - bMinMissRadius = 2; - } + if ( bMinMissRadius < 2 ) + { + bMinMissRadius = 2; + } - if ( bMaxMissRadius < bMinMissRadius ) - { - bMaxMissRadius = bMinMissRadius; - } + if ( bMaxMissRadius < bMinMissRadius ) + { + bMaxMissRadius = bMinMissRadius; + } - sGridNo = RandomGridFromRadius( sGridNo, bMinMissRadius, bMaxMissRadius ); + sGridNo = RandomGridFromRadius( sGridNo, bMinMissRadius, bMaxMissRadius ); } - + // Get basic launch params... CalculateLaunchItemBasicParams( pSoldier, pItem, sGridNo, ubLevel, sEndZ, &dForce, &dDegrees, &sFinalGridNo, fArmed ); @@ -2207,11 +2225,12 @@ void CalculateLaunchItemParamsForThrow( SOLDIERTYPE *pSoldier, INT16 sGridNo, UI sStartZ = GET_SOLDIER_THROW_HEIGHT( pSoldier->bLevel ); usLauncher = GetLauncherFromLaunchable( pItem->usItem ); -DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 2103")); + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 2103")); + if ( fArmed && Item[usLauncher].mortar ) { - // Start at 0.... - sStartZ = ( pSoldier->bLevel * 256 ) + 50; + // Start at 0.... + sStartZ = ( pSoldier->bLevel * 256 ) + 50; } pSoldier->pThrowParams->dZ = (float)sStartZ; @@ -2225,7 +2244,7 @@ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 2103")); // Dirty interface DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalculateLaunchItemParamsForThrow done"); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalculateLaunchItemParamsForThrow done"); } @@ -2258,7 +2277,7 @@ BOOLEAN CheckForCatcher( REAL_OBJECT *pObject, UINT16 usStructureID ) void CheckForObjectHittingMerc( REAL_OBJECT *pObject, UINT16 usStructureID ) { SOLDIERTYPE *pSoldier; - INT16 sDamage, sBreath; + INT16 sDamage, sBreath; // Do we want to catch? if ( pObject->fTestObject == NO_TEST_OBJECT ) @@ -2266,17 +2285,17 @@ void CheckForObjectHittingMerc( REAL_OBJECT *pObject, UINT16 usStructureID ) // Is it a guy? if ( usStructureID < INVALID_STRUCTURE_ID ) { - if ( pObject->ubLastTargetTakenDamage != (UINT8)usStructureID ) - { - pSoldier = MercPtrs[ usStructureID ]; + if ( pObject->ubLastTargetTakenDamage != (UINT8)usStructureID ) + { + pSoldier = MercPtrs[ usStructureID ]; - sDamage = 1; - sBreath = 0; + sDamage = 1; + sBreath = 0; - EVENT_SoldierGotHit( pSoldier, NOTHING, sDamage, sBreath, pSoldier->bDirection, 0, pObject->ubOwner, FIRE_WEAPON_TOSSED_OBJECT_SPECIAL, 0, 0, NOWHERE ); + EVENT_SoldierGotHit( pSoldier, NOTHING, sDamage, sBreath, pSoldier->bDirection, 0, pObject->ubOwner, FIRE_WEAPON_TOSSED_OBJECT_SPECIAL, 0, 0, NOWHERE ); - pObject->ubLastTargetTakenDamage = (UINT8)( usStructureID ); - } + pObject->ubLastTargetTakenDamage = (UINT8)( usStructureID ); + } } } } @@ -2300,10 +2319,10 @@ BOOLEAN CheckForCatchObject( REAL_OBJECT *pObject ) if ( uiSpacesAway < 4 && !pObject->fAttemptedCatch ) { - if ( pSoldier->usAnimState != CATCH_STANDING && - pSoldier->usAnimState != CATCH_CROUCHED && - pSoldier->usAnimState != LOWER_RIFLE ) - { + if ( pSoldier->usAnimState != CATCH_STANDING && + pSoldier->usAnimState != CATCH_CROUCHED && + pSoldier->usAnimState != LOWER_RIFLE ) + { if ( gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_STAND ) { EVENT_InitNewSoldierAnim( pSoldier, CATCH_STANDING, 0 , FALSE ); @@ -2314,7 +2333,7 @@ BOOLEAN CheckForCatchObject( REAL_OBJECT *pObject ) } pObject->fCatchAnimOn = TRUE; - } + } } pObject->fAttemptedCatch = TRUE; @@ -2375,17 +2394,17 @@ BOOLEAN DoCatchObject( REAL_OBJECT *pObject ) // Catch anim..... switch( gAnimControl[ pSoldier->usAnimState ].ubHeight ) { - case ANIM_STAND: + case ANIM_STAND: - pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; - EVENT_InitNewSoldierAnim( pSoldier, END_CATCH, 0 , FALSE ); - break; + pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; + EVENT_InitNewSoldierAnim( pSoldier, END_CATCH, 0 , FALSE ); + break; - case ANIM_CROUCH: + case ANIM_CROUCH: - pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; - EVENT_InitNewSoldierAnim( pSoldier, END_CROUCH_CATCH, 0 , FALSE ); - break; + pSoldier->usPendingAnimation = NO_PENDING_ANIMATION; + EVENT_InitNewSoldierAnim( pSoldier, END_CROUCH_CATCH, 0 , FALSE ); + break; } PlayJA2Sample( CATCH_OBJECT, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) ); @@ -2433,16 +2452,17 @@ void HandleArmedObjectImpact( REAL_OBJECT *pObject ) // get OBJECTTYPE pObj = &(pObject->Obj); - // ATE: Make sure number of objects is 1... - pObj->ubNumberOfObjects = 1; + // ATE: Make sure number of objects is 1... + pObj->ubNumberOfObjects = 1; if ( Item[ pObj->usItem ].usItemClass & IC_GRENADE ) { fCheckForDuds = TRUE; } -// if ( pObj->usItem == MORTAR_SHELL ) -DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 2337")); + // if ( pObj->usItem == MORTAR_SHELL ) + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 2337")); + if (Item[ pObj->usItem ].usItemClass == IC_BOMB) { fCheckForDuds = TRUE; @@ -2456,21 +2476,21 @@ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 2337")); if ( fCheckForDuds ) { // If we landed on anything other than the floor, always! go off... - #ifdef TESTDUDEXPLOSIVES +#ifdef TESTDUDEXPLOSIVES if ( sZ != 0 || pObject->fInWater ) - #else +#else if ( sZ != 0 || pObject->fInWater || ( pObj->bStatus[0] >= USABLE && ( PreRandom( 100 ) < (UINT32) pObj->bStatus[0] + PreRandom( 50 ) ) ) ) - #endif +#endif { fDoImpact = TRUE; } else // didn't go off! { - #ifdef TESTDUDEXPLOSIVES +#ifdef TESTDUDEXPLOSIVES if ( 1 ) - #else +#else if ( pObj->bStatus[0] >= USABLE && PreRandom(100) < (UINT32) pObj->bStatus[0] + PreRandom( 50 ) ) - #endif +#endif { iTrapped = PreRandom( 4 ) + 2; } @@ -2520,23 +2540,23 @@ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("physics.cpp line 2337")); else { // Add a light effect... - + NewLightEffect( pObject->sGridNo, (UINT8)Explosive[Item[pObject->Obj.usItem].ubClassIndex].ubDuration , (UINT8)Explosive[Item[pObject->Obj.usItem].ubClassIndex].ubStartRadius ); } } else if ( Item[ pObject->Obj.usItem ].usItemClass & IC_GRENADE ) { -/* ARM: Removed. Rewards even missed throws, and pulling a pin doesn't really teach anything about explosives + /* ARM: Removed. Rewards even missed throws, and pulling a pin doesn't really teach anything about explosives if ( MercPtrs[ pObject->ubOwner ]->bTeam == gbPlayerNum && gTacticalStatus.uiFlags & INCOMBAT ) { - // tossed grenade, not a dud, so grant xp - // EXPLOSIVES GAIN (10): Tossing grenade - if ( pObject->ubOwner != NOBODY ) - { - StatChange( MercPtrs[ pObject->ubOwner ], EXPLODEAMT, 10, FALSE ); - } + // tossed grenade, not a dud, so grant xp + // EXPLOSIVES GAIN (10): Tossing grenade + if ( pObject->ubOwner != NOBODY ) + { + StatChange( MercPtrs[ pObject->ubOwner ], EXPLODEAMT, 10, FALSE ); } -*/ + } + */ IgniteExplosion( pObject->ubOwner, (INT16)pObject->Position.x, (INT16)pObject->Position.y, sZ, pObject->sGridNo, pObject->Obj.usItem, GET_OBJECT_LEVEL( pObject->Position.z - CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[ pObject->sGridNo ].sHeight ) ) ); } @@ -2638,42 +2658,42 @@ UINT16 RandomGridFromRadius( INT16 sSweetGridNo, INT8 ubMinRadius, INT8 ubMaxRad BOOLEAN fFound = FALSE; UINT32 cnt = 0; - if ( ubMaxRadius == 0 || ubMinRadius == 0 ) - { - return( sSweetGridNo ); - } + if ( ubMaxRadius == 0 || ubMinRadius == 0 ) + { + return( sSweetGridNo ); + } do { sX = (UINT16)PreRandom( ubMaxRadius ); sY = (UINT16)PreRandom( ubMaxRadius ); - if ( ( sX < ubMinRadius || sY < ubMinRadius ) && ubMaxRadius != ubMinRadius ) - { - continue; - } + if ( ( sX < ubMinRadius || sY < ubMinRadius ) && ubMaxRadius != ubMinRadius ) + { + continue; + } - if ( PreRandom( 2 ) == 0 ) - { - sX = sX * -1; - } + if ( PreRandom( 2 ) == 0 ) + { + sX = sX * -1; + } - if ( PreRandom( 2 ) == 0 ) - { - sY = sY * -1; - } + if ( PreRandom( 2 ) == 0 ) + { + sY = sY * -1; + } leftmost = ( ( sSweetGridNo + ( WORLD_COLS * sY ) )/ WORLD_COLS ) * WORLD_COLS; sGridNo = sSweetGridNo + ( WORLD_COLS * sY ) + sX; - if ( sGridNo == sSweetGridNo ) - { - continue; - } + if ( sGridNo == sSweetGridNo ) + { + continue; + } if ( sGridNo >=0 && sGridNo < WORLD_MAX && - sGridNo >= leftmost && sGridNo < ( leftmost + WORLD_COLS ) ) + sGridNo >= leftmost && sGridNo < ( leftmost + WORLD_COLS ) ) { fFound = TRUE; } diff --git a/TileEngine/physics.h b/TileEngine/physics.h index 35fd9002..ca9943bf 100644 --- a/TileEngine/physics.h +++ b/TileEngine/physics.h @@ -79,7 +79,7 @@ extern REAL_OBJECT ObjectSlots[ NUM_OBJECT_SLOTS ]; // OBJECT LIST STUFF -INT32 CreatePhysicalObject( OBJECTTYPE *pGameObj, real dLifeLength, real xPos, real yPos, real zPos, real xForce, real yForce, real zForce, UINT8 ubOwner, UINT8 ubActionCode, UINT32 uiActionData ); +INT32 CreatePhysicalObject( OBJECTTYPE *pGameObj, real dLifeLength, real xPos, real yPos, real zPos, real xForce, real yForce, real zForce, UINT8 ubOwner, UINT8 ubActionCode, UINT32 uiActionData, BOOLEAN fTestObject ); BOOLEAN RemoveObjectSlot( INT32 iObject ); void RemoveAllPhysicsObjects( ); diff --git a/TileEngine/renderworld.cpp b/TileEngine/renderworld.cpp index 820d82f5..3f115e3f 100644 --- a/TileEngine/renderworld.cpp +++ b/TileEngine/renderworld.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #else @@ -45,6 +47,7 @@ #include "world items.h" #include "GameSettings.h" #include "interface control.h" + #include "Sound Control.h" #endif /////////////////////////// @@ -494,7 +497,7 @@ UINT32 gRenderFlags=0; * any questions? joker */ SGPRect gClippingRect;// = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - INTERFACE_HEIGHT}; -SGPRect gOldClipRect; +SGPRect gOldClipRect = { 0, 0, 1024, 768 }; // 0verhaul: This MUST mirror the gDirtyClipRect init, otherwise funkiness with video overlays will happen INT16 gsRenderCenterX; INT16 gsRenderCenterY; INT16 gsRenderWorldOffsetX = 0; //lal was -1 : bugfix for merc screen position in tactical on high resolution @@ -762,7 +765,7 @@ void RenderSetShadows(BOOLEAN fShadows) else { gRenderFlags&=(~RENDER_FLAG_SHADOWS); - } +} } @@ -4056,222 +4059,222 @@ BOOLEAN ApplyScrolling( INT16 sTempRenderCenterX, INT16 sTempRenderCenterY, BOOL //if ((fAllowScrollingHorizontal || fAllowScrollingVertical) && gfDialogControl) //{ - // Get angles - // TOP LEFT CORNER FIRST - dOpp = sTopLeftWorldY - gsTLY; - dAdj = sTopLeftWorldX - gsTLX; + // Get angles + // TOP LEFT CORNER FIRST + dOpp = sTopLeftWorldY - gsTLY; + dAdj = sTopLeftWorldX - gsTLX; - dAngle = (double)atan2( dAdj, dOpp ); - at1 = dAngle * 180 / PI; + dAngle = (double)atan2( dAdj, dOpp ); + at1 = dAngle * 180 / PI; - if ( dAngle < 0 ) + if ( dAngle < 0 ) + { + fOutLeft = TRUE; + } + else if ( dAngle > PI/2 ) + { + fOutTop = TRUE; + } + + // TOP RIGHT CORNER + dOpp = sTopRightWorldY - gsTRY; + dAdj = gsTRX - sTopRightWorldX; + + dAngle = (double)atan2( dAdj, dOpp ); + at2 = dAngle * 180 / PI; + + if ( dAngle < 0 ) + { + fOutRight = TRUE; + } + else if ( dAngle > PI/2 ) + { + fOutTop = TRUE; + } + + + // BOTTOM LEFT CORNER + dOpp = gsBLY - sBottomLeftWorldY; + dAdj = sBottomLeftWorldX - gsBLX; + + dAngle = (double)atan2( dAdj, dOpp ); + at3 = dAngle * 180 / PI; + + if ( dAngle < 0 ) + { + fOutLeft = TRUE; + } + else if ( dAngle > PI/2 ) + { + fOutBottom = TRUE; + } + + // BOTTOM RIGHT CORNER + dOpp = gsBRY - sBottomRightWorldY; + dAdj = gsBRX - sBottomRightWorldX; + + dAngle = (double)atan2( dAdj, dOpp ); + at4 = dAngle * 180 / PI; + + if ( dAngle < 0 ) + { + fOutRight = TRUE; + } + else if ( dAngle > PI/2 ) + { + fOutBottom = TRUE; + } + + sprintf( gDebugStr, "Angles: %d %d %d %d", (int)at1, (int)at2, (int)at3, (int)at4 ); + + if ( !fOutRight && !fOutLeft && !fOutTop && !fOutBottom ) + { + fScrollGood = TRUE; + } + + // If in editor, anything goes + if ( gfEditMode && _KeyDown( SHIFT ) ) + { + fScrollGood = TRUE; + } + + // Reset some UI flags + gfUIShowExitEast = FALSE; + gfUIShowExitWest = FALSE; + gfUIShowExitNorth = FALSE; + gfUIShowExitSouth = FALSE; + + + if ( !fScrollGood ) + { + // Force adjustment, if true + if ( fForceAdjust ) { - fOutLeft = TRUE; - } - else if ( dAngle > PI/2 ) - { - fOutTop = TRUE; - } - - // TOP RIGHT CORNER - dOpp = sTopRightWorldY - gsTRY; - dAdj = gsTRX - sTopRightWorldX; - - dAngle = (double)atan2( dAdj, dOpp ); - at2 = dAngle * 180 / PI; - - if ( dAngle < 0 ) - { - fOutRight = TRUE; - } - else if ( dAngle > PI/2 ) - { - fOutTop = TRUE; - } - - - // BOTTOM LEFT CORNER - dOpp = gsBLY - sBottomLeftWorldY; - dAdj = sBottomLeftWorldX - gsBLX; - - dAngle = (double)atan2( dAdj, dOpp ); - at3 = dAngle * 180 / PI; - - if ( dAngle < 0 ) - { - fOutLeft = TRUE; - } - else if ( dAngle > PI/2 ) - { - fOutBottom = TRUE; - } - - // BOTTOM RIGHT CORNER - dOpp = gsBRY - sBottomRightWorldY; - dAdj = gsBRX - sBottomRightWorldX; - - dAngle = (double)atan2( dAdj, dOpp ); - at4 = dAngle * 180 / PI; - - if ( dAngle < 0 ) - { - fOutRight = TRUE; - } - else if ( dAngle > PI/2 ) - { - fOutBottom = TRUE; - } - - sprintf( gDebugStr, "Angles: %d %d %d %d", (int)at1, (int)at2, (int)at3, (int)at4 ); - - if ( !fOutRight && !fOutLeft && !fOutTop && !fOutBottom ) - { - fScrollGood = TRUE; - } - - // If in editor, anything goes - if ( gfEditMode && _KeyDown( SHIFT ) ) - { - fScrollGood = TRUE; - } - - // Reset some UI flags - gfUIShowExitEast = FALSE; - gfUIShowExitWest = FALSE; - gfUIShowExitNorth = FALSE; - gfUIShowExitSouth = FALSE; - - - if ( !fScrollGood ) - { - // Force adjustment, if true - if ( fForceAdjust ) + if ( fOutTop ) { - if ( fOutTop ) - { // WANNE: Test - // Adjust screen coordinates on the Y! - CorrectRenderCenter( sScreenCenterX, (INT16)(gsTLY + sY_S ), &sNewScreenX, &sNewScreenY ); - FromScreenToCellCoordinates( sNewScreenX, sNewScreenY , &sTempPosX_W, &sTempPosY_W ); + // Adjust screen coordinates on the Y! + CorrectRenderCenter( sScreenCenterX, (INT16)(gsTLY + sY_S ), &sNewScreenX, &sNewScreenY ); + FromScreenToCellCoordinates( sNewScreenX, sNewScreenY , &sTempPosX_W, &sTempPosY_W ); - sTempRenderCenterX = sTempPosX_W; - sTempRenderCenterY = sTempPosY_W; - - fScrollGood = TRUE; - } - - if ( fOutBottom ) - { - // OK, Ajust this since we get rounding errors in our two different calculations. - CorrectRenderCenter( sScreenCenterX, (INT16)(gsBLY - sY_S - 50 ), &sNewScreenX, &sNewScreenY ); - FromScreenToCellCoordinates( sNewScreenX, sNewScreenY , &sTempPosX_W, &sTempPosY_W ); - - sTempRenderCenterX = sTempPosX_W; - sTempRenderCenterY = sTempPosY_W; - fScrollGood = TRUE; - } - - if ( fOutLeft ) - { - CorrectRenderCenter( (INT16)( gsTLX + sX_S ) , sScreenCenterY , &sNewScreenX, &sNewScreenY ); - FromScreenToCellCoordinates( sNewScreenX, sNewScreenY , &sTempPosX_W, &sTempPosY_W ); - - sTempRenderCenterX = sTempPosX_W; - sTempRenderCenterY = sTempPosY_W; - - fScrollGood = TRUE; - } - - if ( fOutRight ) - { - CorrectRenderCenter( (INT16)( gsTRX - sX_S ) , sScreenCenterY , &sNewScreenX, &sNewScreenY ); - FromScreenToCellCoordinates( sNewScreenX, sNewScreenY , &sTempPosX_W, &sTempPosY_W ); - - sTempRenderCenterX = sTempPosX_W; - sTempRenderCenterY = sTempPosY_W; - fScrollGood = TRUE; - } + sTempRenderCenterX = sTempPosX_W; + sTempRenderCenterY = sTempPosY_W; + fScrollGood = TRUE; } - else + + if ( fOutBottom ) { - if ( fOutRight ) - { - // Check where our cursor is! - if ( gusMouseXPos >= SCREEN_WIDTH - 1 ) - { - gfUIShowExitEast = TRUE; - } - } - - if ( fOutLeft ) - { - // Check where our cursor is! - if ( gusMouseXPos == 0 ) - { - gfUIShowExitWest = TRUE; - } - } - - if ( fOutTop ) - { - // Check where our cursor is! - if ( gusMouseYPos == 0 ) - { - gfUIShowExitNorth = TRUE; - } - } - - if ( fOutBottom ) - { - // Check where our cursor is! - if ( gusMouseYPos >= SCREEN_HEIGHT - 1 ) - { - gfUIShowExitSouth = TRUE; - } - } + // OK, Ajust this since we get rounding errors in our two different calculations. + CorrectRenderCenter( sScreenCenterX, (INT16)(gsBLY - sY_S - 50 ), &sNewScreenX, &sNewScreenY ); + FromScreenToCellCoordinates( sNewScreenX, sNewScreenY , &sTempPosX_W, &sTempPosY_W ); + sTempRenderCenterX = sTempPosX_W; + sTempRenderCenterY = sTempPosY_W; + fScrollGood = TRUE; } + + if ( fOutLeft ) + { + CorrectRenderCenter( (INT16)( gsTLX + sX_S ) , sScreenCenterY , &sNewScreenX, &sNewScreenY ); + FromScreenToCellCoordinates( sNewScreenX, sNewScreenY , &sTempPosX_W, &sTempPosY_W ); + + sTempRenderCenterX = sTempPosX_W; + sTempRenderCenterY = sTempPosY_W; + + fScrollGood = TRUE; + } + + if ( fOutRight ) + { + CorrectRenderCenter( (INT16)( gsTRX - sX_S ) , sScreenCenterY , &sNewScreenX, &sNewScreenY ); + FromScreenToCellCoordinates( sNewScreenX, sNewScreenY , &sTempPosX_W, &sTempPosY_W ); + + sTempRenderCenterX = sTempPosX_W; + sTempRenderCenterY = sTempPosY_W; + fScrollGood = TRUE; + } + } - - - if ( fScrollGood ) + else { - if ( !fCheckOnly ) + if ( fOutRight ) { - sprintf( gDebugStr, "Center: %d %d ", (int)gsRenderCenterX, (int)gsRenderCenterY ); + // Check where our cursor is! + if ( gusMouseXPos >= SCREEN_WIDTH - 1 ) + { + gfUIShowExitEast = TRUE; + } + } - //Makesure it's a multiple of 5 - sMult = sTempRenderCenterX / CELL_X_SIZE; + if ( fOutLeft ) + { + // Check where our cursor is! + if ( gusMouseXPos == 0 ) + { + gfUIShowExitWest = TRUE; + } + } - gsRenderCenterX = ( sMult * CELL_X_SIZE ) + ( CELL_X_SIZE / 2 ); + if ( fOutTop ) + { + // Check where our cursor is! + if ( gusMouseYPos == 0 ) + { + gfUIShowExitNorth = TRUE; + } + } - //Makesure it's a multiple of 5 + if ( fOutBottom ) + { + // Check where our cursor is! + if ( gusMouseYPos >= SCREEN_HEIGHT - 1 ) + { + gfUIShowExitSouth = TRUE; + } + } + + } + } + + + if ( fScrollGood ) + { + if ( !fCheckOnly ) + { + sprintf( gDebugStr, "Center: %d %d ", (int)gsRenderCenterX, (int)gsRenderCenterY ); + + //Makesure it's a multiple of 5 + sMult = sTempRenderCenterX / CELL_X_SIZE; + + gsRenderCenterX = ( sMult * CELL_X_SIZE ) + ( CELL_X_SIZE / 2 ); + + //Makesure it's a multiple of 5 sMult = sTempRenderCenterY / CELL_Y_SIZE; - gsRenderCenterY = ( sMult * CELL_Y_SIZE ) + ( CELL_Y_SIZE / 2 ); + gsRenderCenterY = ( sMult * CELL_Y_SIZE ) + ( CELL_Y_SIZE / 2 ); - //gsRenderCenterX = sTempRenderCenterX; - //gsRenderCenterY = sTempRenderCenterY; + //gsRenderCenterX = sTempRenderCenterX; + //gsRenderCenterY = sTempRenderCenterY; - gsTopLeftWorldX = sTopLeftWorldX - gsTLX; + gsTopLeftWorldX = sTopLeftWorldX - gsTLX; gsTopRightWorldX = sTopRightWorldX - gsTLX; gsBottomLeftWorldX = sBottomLeftWorldX - gsTLX; gsBottomRightWorldX = sBottomRightWorldX - gsTLX; - gsTopLeftWorldY = sTopLeftWorldY - gsTLY; - gsTopRightWorldY = sTopRightWorldY - gsTLY; - gsBottomLeftWorldY = sBottomLeftWorldY - gsTLY; - gsBottomRightWorldY = sBottomRightWorldY - gsTLY; + gsTopLeftWorldY = sTopLeftWorldY - gsTLY; + gsTopRightWorldY = sTopRightWorldY - gsTLY; + gsBottomLeftWorldY = sBottomLeftWorldY - gsTLY; + gsBottomRightWorldY = sBottomRightWorldY - gsTLY; - SetPositionSndsVolumeAndPanning( ); - } - - return( TRUE ); + SetPositionSndsVolumeAndPanning( ); } - return( FALSE ); + return( TRUE ); + } + + return( FALSE ); //} //return ( FALSE ); @@ -7543,4 +7546,4 @@ void RenderGridNoVisibleDebug( ) RenderGridNoVisibleDebugInfo( gsStartPointX_M, gsStartPointY_M, gsStartPointX_S, gsStartPointY_S, gsEndXS, gsEndYS ); } -#endif \ No newline at end of file +#endif diff --git a/TileEngine/structure.cpp b/TileEngine/structure.cpp index a291d850..a8aae64b 100644 --- a/TileEngine/structure.cpp +++ b/TileEngine/structure.cpp @@ -36,6 +36,10 @@ #include "sound control.h" #include "Buildings.h" + + #include "Random.h" + + #include "Tile Animation.h" #endif #ifdef COUNT_PATHS @@ -1650,7 +1654,8 @@ void DebugStructurePage1( void ) STRUCTURE * pStructure; STRUCTURE * pBase; //LEVELNODE * pLand; - INT16 sGridNo, sDesiredLevel; + UINT16 usGridNo; + INT16 sDesiredLevel; INT8 bHeight, bDens0, bDens1, bDens2, bDens3; INT8 bStructures; @@ -1665,7 +1670,7 @@ void DebugStructurePage1( void ) SetFont( LARGEFONT1 ); gprintf( 0, 0, L"DEBUG STRUCTURES PAGE 1 OF 1" ); - if (GetMouseMapPos( &sGridNo ) == FALSE) + if (GetMouseMapPos( &usGridNo ) == FALSE) { return; //gprintf( 0, LINE_HEIGHT * 1, L"No structure selected" ); @@ -1680,14 +1685,14 @@ void DebugStructurePage1( void ) sDesiredLevel = STRUCTURE_ON_ROOF; } - gprintf( 320, 0, L"Building %d", gubBuildingInfo[ sGridNo ] ); + gprintf( 320, 0, L"Building %d", gubBuildingInfo[ usGridNo ] ); /* - pLand = gpWorldLevelData[sGridNo].pLandHead; + pLand = gpWorldLevelData[usGridNo].pLandHead; gprintf( 320, 0, L"Fake light %d", pLand->ubFakeShadeLevel ); - gprintf( 320, LINE_HEIGHT, L"Real light: ground %d roof %d", LightTrueLevel( sGridNo, 0 ), LightTrueLevel( sGridNo, 1 ) ); + gprintf( 320, LINE_HEIGHT, L"Real light: ground %d roof %d", LightTrueLevel( usGridNo, 0 ), LightTrueLevel( usGridNo, 1 ) ); */ - pStructure = gpWorldLevelData[sGridNo].pStructureHead; + pStructure = gpWorldLevelData[usGridNo].pStructureHead; while (pStructure != NULL) { if (pStructure->sCubeOffset == sDesiredLevel) @@ -1762,7 +1767,7 @@ void DebugStructurePage1( void ) gprintf( 0, LINE_HEIGHT * 4, L"Structure ID %d", pStructure->usStructureID ); #endif - pStructure = gpWorldLevelData[sGridNo].pStructureHead; + pStructure = gpWorldLevelData[usGridNo].pStructureHead; for ( bStructures = 0; pStructure != NULL; pStructure = pStructure->pNext) { bStructures++; @@ -1797,18 +1802,18 @@ void DebugStructurePage1( void ) } #endif gprintf( 0, LINE_HEIGHT * 13, L"N %d NE %d E %d SE %d", - gubWorldMovementCosts[ sGridNo ][ NORTH ][ gsInterfaceLevel ], - gubWorldMovementCosts[ sGridNo ][ NORTHEAST ][ gsInterfaceLevel ], - gubWorldMovementCosts[ sGridNo ][ EAST ][ gsInterfaceLevel ], - gubWorldMovementCosts[ sGridNo ][ SOUTHEAST ][ gsInterfaceLevel ] ); + gubWorldMovementCosts[ usGridNo ][ NORTH ][ gsInterfaceLevel ], + gubWorldMovementCosts[ usGridNo ][ NORTHEAST ][ gsInterfaceLevel ], + gubWorldMovementCosts[ usGridNo ][ EAST ][ gsInterfaceLevel ], + gubWorldMovementCosts[ usGridNo ][ SOUTHEAST ][ gsInterfaceLevel ] ); gprintf( 0, LINE_HEIGHT * 14, L"S %d SW %d W %d NW %d", - gubWorldMovementCosts[ sGridNo ][ SOUTH ][ gsInterfaceLevel ], - gubWorldMovementCosts[ sGridNo ][ SOUTHWEST ][ gsInterfaceLevel ], - gubWorldMovementCosts[ sGridNo ][ WEST ][ gsInterfaceLevel ], - gubWorldMovementCosts[ sGridNo ][ NORTHWEST ][ gsInterfaceLevel ] ); + gubWorldMovementCosts[ usGridNo ][ SOUTH ][ gsInterfaceLevel ], + gubWorldMovementCosts[ usGridNo ][ SOUTHWEST ][ gsInterfaceLevel ], + gubWorldMovementCosts[ usGridNo ][ WEST ][ gsInterfaceLevel ], + gubWorldMovementCosts[ usGridNo ][ NORTHWEST ][ gsInterfaceLevel ] ); gprintf( 0, LINE_HEIGHT * 15, L"Ground smell %d strength %d", - SMELL_TYPE( gpWorldLevelData[ sGridNo ].ubSmellInfo ), - SMELL_STRENGTH( gpWorldLevelData[ sGridNo ].ubSmellInfo ) ); + SMELL_TYPE( gpWorldLevelData[ usGridNo ].ubSmellInfo ), + SMELL_STRENGTH( gpWorldLevelData[ usGridNo ].ubSmellInfo ) ); #ifdef COUNT_PATHS if (guiTotalPathChecks > 0) @@ -1823,7 +1828,7 @@ void DebugStructurePage1( void ) } #else gprintf( 0, LINE_HEIGHT * 16, - L"Adj soldiers %d", gpWorldLevelData[sGridNo].ubAdjacentSoldierCnt ); + L"Adj soldiers %d", gpWorldLevelData[usGridNo].ubAdjacentSoldierCnt ); #endif } @@ -2393,4 +2398,4 @@ UINT32 GetStructureOpenSound( STRUCTURE * pStructure, BOOLEAN fClose ) } return( uiSoundID ); -} \ No newline at end of file +} diff --git a/TileEngine/tiledef.cpp b/TileEngine/tiledef.cpp index 95ed3f11..da10f2f8 100644 --- a/TileEngine/tiledef.cpp +++ b/TileEngine/tiledef.cpp @@ -15,6 +15,7 @@ #include "edit_sys.h" #include "pathai.h" #include "tile surface.h" + #include "Tactical Save.h" #endif //#include "editscreen.h" @@ -1206,11 +1207,11 @@ BOOLEAN AnyLowerLand( UINT32 iMapIndex, UINT32 uiSrcType, UINT8 *pubLastLevel ) BOOLEAN GetWallOrientation( UINT16 usIndex, UINT16 *pusWallOrientation ) { - TILE_ELEMENT TileElem; + TILE_ELEMENT TileElem; *pusWallOrientation = 0xffff; - CHECKF( usIndex != NO_TILE ); + CHECKF( usIndex != NO_TILE ); CHECKF( usIndex < NUMBEROFTILES ); //lal bugfix // Get tile element diff --git a/TileEngine/worlddef.cpp b/TileEngine/worlddef.cpp index 53949aa5..3df050ad 100644 --- a/TileEngine/worlddef.cpp +++ b/TileEngine/worlddef.cpp @@ -1,3 +1,5 @@ +#include "builddefines.h" + #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #include "PreBattle Interface.h" @@ -58,6 +60,11 @@ #include "pits.h" #include "Game Clock.h" #include "Buildings.h" + #include "strategicmap.h" + #include "overhead map.h" + #include "SmokeEffects.h" + #include "LightEffects.h" + #include "meanwhile.h" #endif #define SET_MOVEMENTCOST( a, b, c, d ) ( ( gubWorldMovementCosts[ a ][ b ][ c ] < d ) ? ( gubWorldMovementCosts[ a ][ b ][ c ] = d ) : 0 ); diff --git a/TileEngine/worldman.cpp b/TileEngine/worldman.cpp index cf857b14..864dd236 100644 --- a/TileEngine/worldman.cpp +++ b/TileEngine/worldman.cpp @@ -25,6 +25,7 @@ #include "SaveLoadMap.h" #include "random.h" #include "render fun.h" + #include "GameSettings.h" #endif extern BOOLEAN gfBasement; diff --git a/Utils/Animated ProgressBar.cpp b/Utils/Animated ProgressBar.cpp index 0802a8f2..4bb490ea 100644 --- a/Utils/Animated ProgressBar.cpp +++ b/Utils/Animated ProgressBar.cpp @@ -10,6 +10,8 @@ #include "video.h" #include "Render Dirty.h" #include "music control.h" + #include "Timer Control.h" + #include "sysutil.h" #endif double rStart, rEnd; diff --git a/Utils/Cursors.cpp b/Utils/Cursors.cpp index 1dde5689..5da240eb 100644 --- a/Utils/Cursors.cpp +++ b/Utils/Cursors.cpp @@ -2,6 +2,7 @@ #include "Utils All.h" #include "interface items.h" #else + #include "builddefines.h" #include #include "sgp.h" #include "cursors.h" @@ -14,6 +15,7 @@ #include "interface.h" #include "overhead.h" #include "Cursor Control.h" + #include "Sound Control.h" #endif //aim diff --git a/Utils/Event Pump.cpp b/Utils/Event Pump.cpp index 84d69b6b..d9e7aa84 100644 --- a/Utils/Event Pump.cpp +++ b/Utils/Event Pump.cpp @@ -15,6 +15,7 @@ #include "weapons.h" #include "Animation Control.h" #include "opplist.h" + #include "Tactical Save.h" #endif #ifdef NETWORKED diff --git a/Utils/Font Control.cpp b/Utils/Font Control.cpp index 227caad9..3757fbc1 100644 --- a/Utils/Font Control.cpp +++ b/Utils/Font Control.cpp @@ -11,6 +11,7 @@ #include "vsurface_private.h" #include "wcheck.h" #include "Font Control.h" + #include "WinFont.h" #endif INT32 giCurWinFont = 0; diff --git a/Utils/INIReader.cpp b/Utils/INIReader.cpp index e3ff7184..91f986f4 100644 --- a/Utils/INIReader.cpp +++ b/Utils/INIReader.cpp @@ -1,3 +1,4 @@ +#include "builddefines.h" #include "IniReader.h" #include "FileMan.h" #include diff --git a/Utils/Multi Language Graphic Utils.cpp b/Utils/Multi Language Graphic Utils.cpp index 0e9e3322..09d58e1e 100644 --- a/Utils/Multi Language Graphic Utils.cpp +++ b/Utils/Multi Language Graphic Utils.cpp @@ -1,4 +1,13 @@ +#ifdef PRECOMPILEDHEADERS #include "Utils All.h" +#else +#include "builddefines.h" +#include "stdio.h" +#include "Windows.h" +#include "Types.h" +#include "Multi Language Graphic Utils.h" +#endif + #include "Language Defines.h" BOOLEAN GetMLGFilename( SGPFILENAME filename, UINT16 usMLGGraphicID ) @@ -244,7 +253,7 @@ BOOLEAN GetMLGFilename( SGPFILENAME filename, UINT16 usMLGGraphicID ) #elif defined( POLISH ) sprintf( zLanguage, "POLISH" ); #elif defined( RUSSIAN ) - sprintf( (char*)zLanguage, "RUSSIAN" ); + sprintf( zLanguage, "RUSSIAN" ); #elif defined( SPANISH ) sprintf( zLanguage, "SPANISH" ); #elif defined( TAIWANESE ) @@ -356,4 +365,4 @@ BOOLEAN GetMLGFilename( SGPFILENAME filename, UINT16 usMLGGraphicID ) #endif return FALSE; -} \ No newline at end of file +} diff --git a/Utils/Multilingual Text Code Generator.cpp b/Utils/Multilingual Text Code Generator.cpp index a1f5426a..0f13762c 100644 --- a/Utils/Multilingual Text Code Generator.cpp +++ b/Utils/Multilingual Text Code Generator.cpp @@ -29,6 +29,7 @@ CREATED: Feb 16, 1999 #ifdef _DEBUG +#include "builddefines.h" #include #include "types.h" #include "Language Defines.h" diff --git a/Utils/STIConvert.cpp b/Utils/STIConvert.cpp index 5610ec74..3fa7c529 100644 --- a/Utils/STIConvert.cpp +++ b/Utils/STIConvert.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Utils All.h" #else + #include "builddefines.h" #include #include #include diff --git a/Utils/Sound Control.cpp b/Utils/Sound Control.cpp index 4572eaae..024c97db 100644 --- a/Utils/Sound Control.cpp +++ b/Utils/Sound Control.cpp @@ -9,6 +9,8 @@ #include "overhead.h" #include "isometric utils.h" #include "renderworld.h" + #include "GameSettings.h" + #include "math.h" #endif #define SOUND_FAR_VOLUME_MOD 25 diff --git a/Utils/Text Input.cpp b/Utils/Text Input.cpp index dee98926..cfc5f5f5 100644 --- a/Utils/Text Input.cpp +++ b/Utils/Text Input.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "Utils All.h" #else + #include "builddefines.h" #include #include #include diff --git a/Utils/Text Utils.cpp b/Utils/Text Utils.cpp index b497a02e..c9cd5bf2 100644 --- a/Utils/Text Utils.cpp +++ b/Utils/Text Utils.cpp @@ -4,6 +4,7 @@ #include "Language Defines.h" #include "text.h" #include "Fileman.h" + #include "GameSettings.h" #endif BOOLEAN LoadItemInfo(UINT16 ubIndex, STR16 pNameString, STR16 pInfoString ) diff --git a/Utils/Timer Control.cpp b/Utils/Timer Control.cpp index 26bed807..22da562c 100644 --- a/Utils/Timer Control.cpp +++ b/Utils/Timer Control.cpp @@ -14,6 +14,7 @@ #include "handle items.h" #include "worlddef.h" #include "renderworld.h" + #include "interface control.h" #endif #ifndef WIN32_LEAN_AND_MEAN diff --git a/Utils/Utils.vcproj b/Utils/Utils.vcproj index 6682cd64..80e89f70 100644 --- a/Utils/Utils.vcproj +++ b/Utils/Utils.vcproj @@ -1,34 +1,52 @@ + ProjectGUID="{4D4A4AF3-63D1-4C4B-81B5-3EFB3BD574F2}" + > + Name="Win32" + /> + + + ATLMinimizesCRunTimeLibraryUsage="false" + > + + + + + + CompileAs="2" + /> + Name="VCManagedResourceCompilerTool" + /> + + + SuppressStartupBanner="true" + /> + Name="VCALinkTool" + /> + Name="VCXDCMakeTool" + /> + Name="VCBscMakeTool" + /> + Name="VCFxCopTool" + /> - - - - + Name="VCPostBuildEventTool" + /> + ATLMinimizesCRunTimeLibraryUsage="false" + > + + + + + + DisableSpecificWarnings="4292" + /> + Name="VCManagedResourceCompilerTool" + /> + + + SuppressStartupBanner="true" + /> + Name="VCALinkTool" + /> + Name="VCXDCMakeTool" + /> + Name="VCBscMakeTool" + /> + Name="VCFxCopTool" + /> - - - - + Name="VCPostBuildEventTool" + /> + ATLMinimizesCRunTimeLibraryUsage="false" + > + + + + + + CompileAs="2" + /> + Name="VCManagedResourceCompilerTool" + /> + + + SuppressStartupBanner="true" + /> + Name="VCALinkTool" + /> + Name="VCXDCMakeTool" + /> + Name="VCBscMakeTool" + /> + Name="VCFxCopTool" + /> - - - - + Name="VCPostBuildEventTool" + /> + ATLMinimizesCRunTimeLibraryUsage="false" + > + + + + + + SuppressStartupBanner="true" + CompileAs="2" + /> + Name="VCManagedResourceCompilerTool" + /> + + + SuppressStartupBanner="true" + /> + Name="VCALinkTool" + /> + Name="VCXDCMakeTool" + /> + Name="VCBscMakeTool" + /> + Name="VCFxCopTool" + /> - - - - + Name="VCPostBuildEventTool" + /> + ATLMinimizesCRunTimeLibraryUsage="false" + > + + + + + + DisableSpecificWarnings="4292;4189" + /> + Name="VCManagedResourceCompilerTool" + /> + + + SuppressStartupBanner="true" + /> + Name="VCALinkTool" + /> + Name="VCXDCMakeTool" + /> + Name="VCBscMakeTool" + /> + Name="VCFxCopTool" + /> - - - - + Name="VCPostBuildEventTool" + /> + ATLMinimizesCRunTimeLibraryUsage="false" + > + + + + + + DisableSpecificWarnings="4292" + /> + Name="VCManagedResourceCompilerTool" + /> + + + SuppressStartupBanner="true" + /> + Name="VCALinkTool" + /> + Name="VCXDCMakeTool" + /> + Name="VCBscMakeTool" + /> + Name="VCFxCopTool" + /> - - - - + Name="VCPostBuildEventTool" + /> + ATLMinimizesCRunTimeLibraryUsage="false" + > + + + + + + CompileAs="2" + /> + Name="VCManagedResourceCompilerTool" + /> + + + SuppressStartupBanner="true" + /> + Name="VCALinkTool" + /> + Name="VCXDCMakeTool" + /> + Name="VCBscMakeTool" + /> + Name="VCFxCopTool" + /> - - - - + Name="VCPostBuildEventTool" + /> + ATLMinimizesCRunTimeLibraryUsage="false" + > + + + + + + CompileAs="2" + /> + Name="VCManagedResourceCompilerTool" + /> + + + SuppressStartupBanner="true" + /> + Name="VCALinkTool" + /> + Name="VCXDCMakeTool" + /> + Name="VCBscMakeTool" + /> + Name="VCFxCopTool" + /> - - - - + Name="VCPostBuildEventTool" + /> @@ -440,2707 +622,3328 @@ + Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" + > + RelativePath="_DutchText.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="_EnglishText.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="_FrenchText.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="_GermanText.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="_ItalianText.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="_Ja25EnglishText.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="_Ja25GermanText.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath=".\_Ja25RussianText.cpp" + > + RelativePath="_PolishText.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="_RussianText.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Animated ProgressBar.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Cinematics.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Cursors.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Debug Control.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="dsutil.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Encrypted File.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Event Manager.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Event Pump.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Font Control.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath=".\INIReader.cpp" + > + RelativePath="MapUtility.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="MercTextBox.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="message.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Multi Language Graphic Utils.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Multilingual Text Code Generator.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Music Control.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="PopUpBox.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Quantize Wrap.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Quantize.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Slider.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Sound Control.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="STIConvert.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Text Input.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Text Utils.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Timer Control.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="Utilities.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath="WordWrap.cpp" + > + Name="Demo Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Debug|Win32" + > + BrowseInformation="1" + /> + Name="Debug Demo|Win32" + > + BrowseInformation="1" + /> + Name="Release|Win32" + > + BrowseInformation="1" + /> + Name="Release with Debug Info|Win32" + > + BrowseInformation="1" + /> + Name="Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Demo Bounds Checker|Win32" + > + BrowseInformation="1" + /> + Name="Release Demo|Win32" + > + BrowseInformation="1" + /> + RelativePath=".\XML_Strings.cpp" + > + Filter="h;hpp;hxx;hm;inl;fi;fd" + > + RelativePath=".\_Ja25EnglishText.h" + > + RelativePath="_Ja25GermanText.h" + > + RelativePath=".\_Ja25RussianText.h" + > + RelativePath="Animated ProgressBar.h" + > + RelativePath="cursors.h" + > + RelativePath="Debug Control.h" + > + RelativePath="dsutil.h" + > + RelativePath="Event Manager.h" + > + RelativePath="Event Pump.h" + > + RelativePath="Font Control.h" + > + RelativePath=".\INIReader.h" + > + RelativePath="message.h" + > + RelativePath="Multi Language Graphic Utils.h" + > + RelativePath="Multilingual Text Code Generator.h" + > + RelativePath="Music Control.h" + > + RelativePath="Sound Control.h" + > + RelativePath="Text Input.h" + > + RelativePath="Text.h" + > + RelativePath="Timer Control.h" + > + RelativePath="utilities.h" + > + RelativePath="Utils All.h" + > diff --git a/Utils/WordWrap.cpp b/Utils/WordWrap.cpp index 7318b0ec..48d42d00 100644 --- a/Utils/WordWrap.cpp +++ b/Utils/WordWrap.cpp @@ -7,6 +7,7 @@ #include "Render Dirty.h" #include "Font Control.h" #include "Stdio.h" + #include "WinFont.h" #endif diff --git a/Utils/XML_Items.cpp b/Utils/XML_Items.cpp index bb684b84..ce154586 100644 --- a/Utils/XML_Items.cpp +++ b/Utils/XML_Items.cpp @@ -43,6 +43,7 @@ #include "expat.h" #include "XML.h" #include "utilities.h" + #include "store inventory.h" #endif struct diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index 0b3c3180..9417102a 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -1,4 +1,7 @@ +#ifdef PRECOMPILEDHEADERS #include "Utils All.h" +#else +#endif #include "Language Defines.h" #ifdef RUSSIAN diff --git a/aniviewscreen.cpp b/aniviewscreen.cpp index 7436ea47..f645fb9e 100644 --- a/aniviewscreen.cpp +++ b/aniviewscreen.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "JA2 All.h" #else + #include "builddefines.h" #include #include #include diff --git a/builddefines.h b/builddefines.h index 2d83759c..7030689b 100644 --- a/builddefines.h +++ b/builddefines.h @@ -4,12 +4,18 @@ #include "Language Defines.h" // Remove comment to build Beta version (with lot of debug infos) including the Editor -//#define JA2BETAVERSION +// #define JA2BETAVERSION // Normal test version -//#define JA2TESTVERSION +// #define JA2TESTVERSION -//#define JA2EDITOR +// #define JA2EDITOR + +// #define DEBUG_ATTACKBUSY + +// #define LUA_CONSOLE + +// #define ROBOT_ALWAYS_READY //#ifdef _DEBUG // #ifndef JA2TESTVERSION @@ -38,4 +44,11 @@ // Huge speed and memory hog, but thorough -- will work with release builds. // #define EXTREME_MEMORY_DEBUGGING +// 0verhaul +// These squelch warnings in VC2K5 about printf's and string operations being unsafe. Maybe we should work on building a better +// system that gives buffer sizes for copies (which would prevent future problems like a stack corruption issue I fixed a while back), +// but for now, just tell the compiler to shut up so I can see the real errors. +#define _CRT_SECURE_NO_WARNINGS +#define _CRT_NON_CONFORMING_SWPRINTFS + #endif \ No newline at end of file diff --git a/gameloop.cpp b/gameloop.cpp index b5a2816c..c4803e9a 100644 --- a/gameloop.cpp +++ b/gameloop.cpp @@ -4,6 +4,7 @@ #include "Prebattle Interface.h" #else #include + #include #include "sgp.h" #include "Gameloop.h" #include "Screens.h" @@ -27,8 +28,12 @@ #include "fade screen.h" #include "text.h" #include "HelpScreen.h" + #include "PreBattle Interface.h" #endif +#include "Console.h" +#include "Lua Interpreter.h" + // rain #include "Rain.h" // end rain @@ -88,6 +93,7 @@ BOOLEAN InitializeGame(void) giStartingMemValue = MemGetFree( ); + InitializeLua(); ClearAllDebugTopics(); RegisterJA2DebugTopic( TOPIC_JA2OPPLIST, "Reg" ); @@ -161,6 +167,8 @@ void ShutdownGame(void) //Deletes all the Temp files in the Maps\Temp directory InitTacticalSave( FALSE ); + + ShutdownLua( ); } diff --git a/gamescreen.cpp b/gamescreen.cpp index 18575636..dbf9f521 100644 --- a/gamescreen.cpp +++ b/gamescreen.cpp @@ -3,6 +3,7 @@ #include "HelpScreen.h" #include "PreBattle Interface.h" #else + #include "builddefines.h" #include #include #include @@ -78,6 +79,13 @@ #include "strategic ai.h" #include "HelpScreen.h" #include "PreBattle Interface.h" + #include "Sound Control.h" + #include "MessageBoxScreen.h" + #include "Text.h" + #include "GameSettings.h" + #include "Random.h" + #include "editscreen.h" + #include "Scheduling.h" #endif diff --git a/gamescreen.h b/gamescreen.h index 1f127c2c..38403749 100644 --- a/gamescreen.h +++ b/gamescreen.h @@ -2,7 +2,7 @@ #define _GAMESCREEN_H - +#include "fade screen.h" #define ARE_IN_FADE_IN( ) ( gfFadeIn || gfFadeInitialized ) diff --git a/jascreens.cpp b/jascreens.cpp index 6e0f44c0..cad0ecba 100644 --- a/jascreens.cpp +++ b/jascreens.cpp @@ -1,6 +1,7 @@ #ifdef PRECOMPILEDHEADERS #include "JA2 All.h" #else + #include "builddefines.h" #include #include #include diff --git a/lua/Console.cpp b/lua/Console.cpp new file mode 100644 index 00000000..29437e85 --- /dev/null +++ b/lua/Console.cpp @@ -0,0 +1,126 @@ +#define _WIN32_WINNT 0x0500 + +#include +#include +#include +#include +#include +#include +#include +#include "Console.h" +#include "Lua Interpreter.h" + +#ifndef _USE_OLD_IOSTREAMS +using namespace std; +#endif + +extern HWND ghWindow; + +// maximum mumber of lines the output console should have +static const WORD MAX_CONSOLE_LINES = 500; + +BOOL WINAPI ControlHandlerRoutine( + DWORD dwCtrlType +) +{ + switch (dwCtrlType) + { + case CTRL_CLOSE_EVENT: + // Tell the main window that the console wants out + PostMessage( ghWindow, WM_USER, 0, 0 ); + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + // Ignore all of these signals. The game itself will handle the important stuff anyway. + return TRUE; + } + + return FALSE; +} + + +void CreateConsole() +{ + int hConHandle; + long lStdHandle; + CONSOLE_SCREEN_BUFFER_INFO coninfo; + FILE *fp; +// HWND hConWindow; + + // allocate a console for this app + AllocConsole(); + + // Eliminate the game-killing control signals + SetConsoleCtrlHandler( ControlHandlerRoutine, TRUE ); + + // set the screen buffer to be big enough to let us scroll text + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), + &coninfo); + coninfo.dwSize.Y = MAX_CONSOLE_LINES; + SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), + coninfo.dwSize); + + // redirect unbuffered STDOUT to the console + lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE); + hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); + fp = _fdopen( hConHandle, "w" ); + *stdout = *fp; + setvbuf( stdout, NULL, _IONBF, 0 ); + + // redirect unbuffered STDIN to the console + lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE); + hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); + fp = _fdopen( hConHandle, "r" ); + *stdin = *fp; + setvbuf( stdin, NULL, _IONBF, 0 ); + + // redirect unbuffered STDERR to the console + lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE); + hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); + fp = _fdopen( hConHandle, "w" ); + *stderr = *fp; + setvbuf( stderr, NULL, _IONBF, 0 ); + + // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog + // point to console as well + ios::sync_with_stdio(); + + // Print the warning message + printf( "Do not close this window!\n"); + printf( "> " ); +} + +void PollConsole () +{ + static int buf_idx = 0; + static char buf[16384]; + + if (_kbhit() ) + { + buf[ buf_idx++ ] = _getche(); + if (buf[ buf_idx-1] == 8) { + _putch( ' '); + buf_idx--; + if (buf_idx > 0) + { + _putch( 8 ); + buf_idx--; + } + } + } + + if (buf[ buf_idx-1] == '\r') + { + buf[ buf_idx-1] = 0; + printf( "\n"); + EvalLua( buf); + printf( "\n> "); + buf_idx = 0; + } +} + +//End of File + + + diff --git a/lua/Console.h b/lua/Console.h new file mode 100644 index 00000000..dc3ee459 --- /dev/null +++ b/lua/Console.h @@ -0,0 +1,9 @@ +#ifndef __CONSOLE_H__ +#define __CONSOLE_H__ + +void CreateConsole(); +void PollConsole(); + +#endif + +/* End of File */ \ No newline at end of file diff --git a/lua/Lua Interpreter.h b/lua/Lua Interpreter.h new file mode 100644 index 00000000..4004b416 --- /dev/null +++ b/lua/Lua Interpreter.h @@ -0,0 +1,19 @@ +extern "C" { +#include +#include +#include +} + +#include "Types.h" + +typedef struct { + STR8 name; + lua_CFunction get; + lua_CFunction set; + lua_CFunction call; +} LuaAttrib; + +void InitializeLua( ); +void EvalLua (STR8 buff) ; +void ShutdownLua( ); + diff --git a/lua/lauxlib.h b/lua/lauxlib.h new file mode 100644 index 00000000..1f343086 --- /dev/null +++ b/lua/lauxlib.h @@ -0,0 +1,174 @@ +/* +** $Id: lauxlib.h,v 1.88 2006/04/12 20:31:15 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "lua.h" + + +#if defined(LUA_COMPAT_GETN) +LUALIB_API int (luaL_getn) (lua_State *L, int t); +LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); +#else +#define luaL_getn(L,i) ((int)lua_objlen(L, i)) +#define luaL_setn(L,i,j) ((void)0) /* no op! */ +#endif + +#if defined(LUA_COMPAT_OPENLIB) +#define luaI_openlib luaL_openlib +#endif + + +/* extra error code for `luaL_load' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + + +LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l); +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); +LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, + lua_Integer def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int narg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); +LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, + const char *name); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + + +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, + const char *r); + +LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, + const char *fname, int szhint); + + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define luaL_argcheck(L, cond,numarg,extramsg) \ + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + + +typedef struct luaL_Buffer { + char *p; /* current position in buffer */ + int lvl; /* number of strings in the stack (level) */ + lua_State *L; + char buffer[LUAL_BUFFERSIZE]; +} luaL_Buffer; + +#define luaL_addchar(B,c) \ + ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ + (*(B)->p++ = (char)(c))) + +/* compatibility only */ +#define luaL_putchar(B,c) luaL_addchar(B,c) + +#define luaL_addsize(B,n) ((B)->p += (n)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); + + +/* }====================================================== */ + + +/* compatibility with ref system */ + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ + (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) + +#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) + +#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) + + +#define luaL_reg luaL_Reg + +#endif + + diff --git a/lua/lua.cpp b/lua/lua.cpp new file mode 100644 index 00000000..b6d2082c --- /dev/null +++ b/lua/lua.cpp @@ -0,0 +1,332 @@ +#include +#include +#include +#include "lwstring.h" + +#include "Overhead.h" +#include "Isometric Utils.h" +#include "soldier tile.h" +#include "Soldier Profile.h" +#include "ai.h" + +lua_State *L; + +#define ARRAY_INDEX " idx" // The space is intentional to make this an out-of-band field + +#define SOLDIER_CLASS "ja2_SoldierClass" + +void CreateLuaType( lua_State *L, STR8 TypeName, luaL_Reg *LuaAccessors ) +{ + luaL_Reg *idx; + + luaL_newmetatable( L, TypeName); + for (idx = LuaAccessors; idx->name; idx++) + { + lua_pushstring( L, idx->name); + lua_pushcfunction( L, idx->func); + lua_rawset( L, -3 ); + } +} + + + + + +static LuaAttrib* LuaCommonGetSet( lua_State *L ) +{ + const CHAR8 *AttrToFind; + LuaAttrib *Attributes; + + Attributes = (LuaAttrib*) lua_touserdata( L, lua_upvalueindex( 1)); + + if (lua_isnumber( L, 2) ) + { + AttrToFind = ARRAY_INDEX; + } + else if (lua_isstring( L, 2) ) + { + AttrToFind = lua_tostring( L, 2); + } + else + { + luaL_argcheck( L, 0, 2, "Invalid index to the table" ); + } + + for ( ; Attributes->name; Attributes++ ) + { + if (!strcmp( Attributes->name, AttrToFind) ) + { + return Attributes; + } + } + + return NULL; +} + +static int LuaGetObject( lua_State *L) +{ + LuaAttrib *Attributes; + + Attributes = LuaCommonGetSet( L); + if (!Attributes) + { + lua_pushnil( L ); + return 1; + } + + if (!Attributes->get) + { + if (!Attributes->call) + { + lua_pushnil( L ); + } + else + { + lua_pushcfunction( L, Attributes->call); + } + return 1; + } + + return Attributes->get( L ); +} + +static int LuaSetObject( lua_State *L) +{ + LuaAttrib *Attributes; + + Attributes = LuaCommonGetSet( L); + + if (!Attributes) + { + lua_rawset( L, 1 ); + return 0; + } + + if (!Attributes->set) + { + luaL_error( L, "The attribute is not writable" ); + } + + return Attributes->set( L); +} + + +luaL_Reg ClassList[] = { + { "__index", LuaGetObject, }, + { "__newindex", LuaSetObject, }, + { NULL, }, +}; + +void CreateLuaClass( lua_State *L, STR8 ClassName, LuaAttrib *Attribs ) +{ + luaL_Reg *i; + + luaL_newmetatable( L, ClassName ); + for (i = ClassList; i->name; i++) + { + lua_pushstring( L, i->name); + lua_pushlightuserdata( L, Attribs); + lua_pushcclosure( L, i->func, 1); + lua_rawset( L, -3); + } +} + + + + + + + +void CreateLuaObject( lua_State *L, void *Ptr ) +{ + void **ud; + + // Create the object and initialize its pointer + ud = (void**)lua_newuserdata( L, sizeof( void*) ); + *ud = Ptr; + // Swap the table and metatable for stack arg purposes + lua_insert( L, -2 ); + lua_setmetatable( L, -2 ); +} + + + + + +void NewLuaObject( lua_State *L, STR8 ClsName, void *Ptr ) +{ + luaL_getmetatable( L, ClsName ); + if (lua_istable( L, -1 ) ) + { + CreateLuaObject( L, Ptr ); + } +} + + + + + + +static int LuaGetMercPtr( lua_State *L) +{ + int v = lua_tointeger( L, 2 ); + luaL_argcheck( L, (v >= 0 && v < TOTAL_SOLDIERS), 2, "The soldier index is out of range"); + if (MercPtrs[ v ] ) + { + NewLuaObject( L, "ja2_SoldierClass", MercPtrs[ v ] ); + } + else + { + lua_pushnil( L ); + } + + return 1; +} + +static luaL_Reg SoldierList[] = { + { "__index", LuaGetMercPtr, }, + { NULL, }, +}; + + + + +int LuaGetSoldierName( lua_State *L ) +{ + SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 ); + SOLDIERTYPE *pSoldier = *ppSoldier; + if (!pSoldier) + { + lua_pushnil( L ); + } + else + { + luaWS_newstr( L, pSoldier->name); + } + return 1; +} + +int LuaGetSoldierFullName( lua_State *L ) +{ + SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 ); + SOLDIERTYPE *pSoldier = *ppSoldier; + if (!pSoldier) + { + lua_pushnil( L ); + } + else + { + if (pSoldier->ubProfile < NUM_PROFILES) + { + luaWS_newstr( L, gMercProfiles[pSoldier->ubProfile].zName ); + } + else + { + return LuaGetSoldierName( L); + } + } + return 1; +} + +int LuaGetSoldierGrid( lua_State *L ) +{ + SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 ); + SOLDIERTYPE *pSoldier = *ppSoldier; + if (!pSoldier) + { + lua_pushnil( L ); + } + else + { + lua_pushinteger( L, pSoldier->sGridNo); + } + return 1; +} + +int LuaSetSoldierGrid( lua_State *L ) +{ + SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) lua_touserdata( L, 1 ); + SOLDIERTYPE *pSoldier = *ppSoldier; + int newgrid = luaL_checkinteger( L, 3); + luaL_argcheck( L, newgrid > 0 && newgrid <= NOWHERE, 2, "The grid number must be on screen!" ); + TeleportSoldier( pSoldier, newgrid, TRUE); + return 0; +} + +int LuaSoldierWalkTo( lua_State *L ) +{ + SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) luaL_checkudata( L, 1, SOLDIER_CLASS ); + SOLDIERTYPE *pSoldier = *ppSoldier; + int newgrid = luaL_checkinteger( L, 2); + luaL_argcheck( L, newgrid > 0 && newgrid <= NOWHERE, 2, "The grid number must be on screen!" ); + pSoldier->bAction = AI_ACTION_WALK; + pSoldier->usActionData = newgrid; + pSoldier->bPathStored = FALSE; + pSoldier->bActionInProgress = ExecuteAction( pSoldier); + return 0; +} + +int LuaSoldierRunTo( lua_State *L ) +{ + SOLDIERTYPE **ppSoldier = (SOLDIERTYPE**) luaL_checkudata( L, 1, SOLDIER_CLASS ); + SOLDIERTYPE *pSoldier = *ppSoldier; + int newgrid = luaL_checkinteger( L, 2); + luaL_argcheck( L, newgrid > 0 && newgrid <= NOWHERE, 2, "The grid number must be on screen!" ); + pSoldier->bAction = AI_ACTION_RUN; + pSoldier->usActionData = newgrid; + pSoldier->bPathStored = FALSE; + pSoldier->bActionInProgress = ExecuteAction( pSoldier); + return 0; +} + +LuaAttrib Soldier[] = { + { "name", LuaGetSoldierName, }, + { "fullname", LuaGetSoldierFullName, }, + { "grid", LuaGetSoldierGrid, LuaSetSoldierGrid }, + { "walkto", NULL, NULL, LuaSoldierWalkTo }, + { "runto", NULL, NULL, LuaSoldierRunTo }, + { NULL, }, +}; + + + +extern luaL_Reg WStringMethods[]; + +void InitializeLua( ) +{ + L = lua_open(); + luaL_openlibs(L); + + // Create the accessor metatable +// CreateLuaType( L, ACCESSOR_TABLE, LuaAccessors); +// lua_setglobal( L, ACCESSOR_TABLE); // We also want this class to be known to the script +// lua_pop(L, 1); + + // Create a wide-character savvy string + CreateLuaType( L, "wstring", WStringMethods); + lua_setglobal( L, "wstring"); // We also want this class to be known to the script + + // Create a soldier type + CreateLuaClass( L, SOLDIER_CLASS, Soldier ); + lua_setglobal( L, SOLDIER_CLASS); // We also want this class to be known to the script + + // Create a soldier list type and create its object + CreateLuaType( L, "ja2_SoldierListClass", SoldierList); + CreateLuaObject( L, NULL ); + // Give this new object a name + lua_setglobal( L, "Soldiers" ); +} + +void EvalLua (STR8 buff) { + int error; + error = luaL_loadbuffer(L, buff, strlen(buff), "line") || + lua_pcall(L, 0, 0, 0); + if (error) { + fprintf(stderr, "%s", lua_tostring(L, -1)); + lua_pop(L, 1); /* pop error message from the stack */ + } +} + +void ShutdownLua( ) { + lua_close(L); +} diff --git a/lua/lua.h b/lua/lua.h new file mode 100644 index 00000000..2865a7fa --- /dev/null +++ b/lua/lua.h @@ -0,0 +1,385 @@ +/* +** $Id: lua.h,v 1.218a 2006/06/02 15:34:00 roberto Exp $ +** Lua - An Extensible Extension Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#include "luaconf.h" + + +#define LUA_VERSION "Lua 5.1" +#define LUA_RELEASE "Lua 5.1.2" +#define LUA_VERSION_NUM 501 +#define LUA_COPYRIGHT "Copyright (C) 1994-2007 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" + + +/* mark for precompiled code (`Lua') */ +#define LUA_SIGNATURE "\033Lua" + +/* option for multiple returns in `lua_pcall' and `lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** pseudo-indices +*/ +#define LUA_REGISTRYINDEX (-10000) +#define LUA_ENVIRONINDEX (-10001) +#define LUA_GLOBALSINDEX (-10002) +#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) + + +/* thread status; 0 is OK */ +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction) (lua_State *L); + + +/* +** functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); + + +/* +** prototype for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_remove) (lua_State *L, int idx); +LUA_API void (lua_insert) (lua_State *L, int idx); +LUA_API void (lua_replace) (lua_State *L, int idx); +LUA_API int (lua_checkstack) (lua_State *L, int sz); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); + +LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); +LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API size_t (lua_objlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); +LUA_API void (lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API void (lua_gettable) (lua_State *L, int idx); +LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawget) (lua_State *L, int idx); +LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API void (lua_getfenv) (lua_State *L, int idx); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API int (lua_setfenv) (lua_State *L, int idx); + + +/* +** `load' and `call' functions (load and run Lua code) +*/ +LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); +LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); +LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yield) (lua_State *L, int nresults); +LUA_API int (lua_resume) (lua_State *L, int narg); +LUA_API int (lua_status) (lua_State *L); + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 + +LUA_API int (lua_gc) (lua_State *L, int what, int data); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_strlen(L,i) lua_objlen(L, (i)) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) + +#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + + +/* +** compatibility macros and functions +*/ + +#define lua_open() luaL_newstate() + +#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) + +#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) + +#define lua_Chunkreader lua_Reader +#define lua_Chunkwriter lua_Writer + + + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILRET 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + + +/* Functions to be called by the debuger in specific events */ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); + +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook lua_gethook (lua_State *L); +LUA_API int lua_gethookmask (lua_State *L); +LUA_API int lua_gethookcount (lua_State *L); + + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) `global', `local', `field', `method' */ + const char *what; /* (S) `Lua', `C', `main', `tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int nups; /* (u) number of upvalues */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + int i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2007 Lua.org, PUC-Rio. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +******************************************************************************/ + + +#endif diff --git a/lua/lua.hpp b/lua/lua.hpp new file mode 100644 index 00000000..ec417f59 --- /dev/null +++ b/lua/lua.hpp @@ -0,0 +1,9 @@ +// lua.hpp +// Lua header files for C++ +// <> not supplied automatically because Lua also compiles as C++ + +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} diff --git a/lua/luaconf.h b/lua/luaconf.h new file mode 100644 index 00000000..8be8338f --- /dev/null +++ b/lua/luaconf.h @@ -0,0 +1,762 @@ +/* +** $Id: luaconf.h,v 1.82a 2006/04/10 18:27:23 roberto Exp $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef lconfig_h +#define lconfig_h + +#include +#include + + +/* +** ================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +@@ LUA_ANSI controls the use of non-ansi features. +** CHANGE it (define it) if you want Lua to avoid the use of any +** non-ansi feature or library. +*/ +#if defined(__STRICT_ANSI__) +#define LUA_ANSI +#endif + + +#if !defined(LUA_ANSI) && defined(_WIN32) +#define LUA_WIN +#endif + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_USE_READLINE /* needs some extra libraries */ +#endif + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_DL_DYLD /* does not need extra library */ +#endif + + + +/* +@@ LUA_USE_POSIX includes all functionallity listed as X/Open System +@* Interfaces Extension (XSI). +** CHANGE it (define it) if your system is XSI compatible. +*/ +#if defined(LUA_USE_POSIX) +#define LUA_USE_MKSTEMP +#define LUA_USE_ISATTY +#define LUA_USE_POPEN +#define LUA_USE_ULONGJMP +#endif + + +/* +@@ LUA_PATH and LUA_CPATH are the names of the environment variables that +@* Lua check to set its paths. +@@ LUA_INIT is the name of the environment variable that Lua +@* checks for initialization code. +** CHANGE them if you want different names. +*/ +#define LUA_PATH "LUA_PATH" +#define LUA_CPATH "LUA_CPATH" +#define LUA_INIT "LUA_INIT" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +@* Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +@* C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ +#if defined(_WIN32) +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_PATH_DEFAULT \ + ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" +#define LUA_CPATH_DEFAULT \ + ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll" + +#else +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/5.1/" +#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" +#define LUA_PATH_DEFAULT \ + "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" +#define LUA_CPATH_DEFAULT \ + "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so" +#endif + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + + +/* +@@ LUA_PATHSEP is the character that separates templates in a path. +@@ LUA_PATH_MARK is the string that marks the substitution points in a +@* template. +@@ LUA_EXECDIR in a Windows path is replaced by the executable's +@* directory. +@@ LUA_IGMARK is a mark to ignore all before it when bulding the +@* luaopen_ function name. +** CHANGE them if for some reason your system cannot use those +** characters. (E.g., if one of those characters is a common character +** in file/directory names.) Probably you do not need to change them. +*/ +#define LUA_PATHSEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXECDIR "!" +#define LUA_IGMARK "-" + + +/* +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) +*/ +#define LUA_INTEGER ptrdiff_t + + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all standard library functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) + +#if defined(LUA_CORE) || defined(LUA_LIB) +#define LUA_API __declspec(dllexport) +#else +#define LUA_API __declspec(dllimport) +#endif + +#else + +#define LUA_API extern + +#endif + +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +@* exported to outside modules. +@@ LUAI_DATA is a mark for all extern (const) variables that are not to +@* be exported to outside modules. +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. +*/ +#if defined(luaall_c) +#define LUAI_FUNC static +#define LUAI_DATA /* empty */ + +#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DATA LUAI_FUNC + +#else +#define LUAI_FUNC extern +#define LUAI_DATA extern +#endif + + + +/* +@@ LUA_QL describes how error messages quote program elements. +** CHANGE it if you want a different appearance. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +** {================================================================== +** Stand-alone configuration +** =================================================================== +*/ + +#if defined(lua_c) || defined(luaall_c) + +/* +@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that +@* is, whether we're running lua interactively). +** CHANGE it if you have a better definition for non-POSIX/non-Windows +** systems. +*/ +#if defined(LUA_USE_ISATTY) +#include +#define lua_stdin_is_tty() isatty(0) +#elif defined(LUA_WIN) +#include +#include +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +#else +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ +#endif + + +/* +@@ LUA_PROMPT is the default prompt used by stand-alone Lua. +@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. +** CHANGE them if you want different prompts. (You can also change the +** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) +*/ +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " + + +/* +@@ LUA_PROGNAME is the default name for the stand-alone Lua program. +** CHANGE it if your stand-alone interpreter has a different name and +** your system is not able to detect that name automatically. +*/ +#define LUA_PROGNAME "lua" + + +/* +@@ LUA_MAXINPUT is the maximum length for an input line in the +@* stand-alone interpreter. +** CHANGE it if you need longer lines. +*/ +#define LUA_MAXINPUT 512 + + +/* +@@ lua_readline defines how to show a prompt and then read a line from +@* the standard input. +@@ lua_saveline defines how to "save" a read line in a "history". +@@ lua_freeline defines how to free a line read by lua_readline. +** CHANGE them if you want to improve this functionality (e.g., by using +** GNU readline and history facilities). +*/ +#if defined(LUA_USE_READLINE) +#include +#include +#include +#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) +#define lua_saveline(L,idx) \ + if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L,b) ((void)L, free(b)) +#else +#define lua_readline(L,b,p) \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } +#endif + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles +@* as a percentage. +** CHANGE it if you want the GC to run faster or slower (higher values +** mean larger pauses which mean slower collection.) You can also change +** this value dynamically. +*/ +#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ + + +/* +@@ LUAI_GCMUL defines the default speed of garbage collection relative to +@* memory allocation as a percentage. +** CHANGE it if you want to change the granularity of the garbage +** collection. (Higher values mean coarser collections. 0 represents +** infinity, where each step performs a full collection.) You can also +** change this value dynamically. +*/ +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ + + + +/* +@@ LUA_COMPAT_GETN controls compatibility with old getn behavior. +** CHANGE it (define it) if you want exact compatibility with the +** behavior of setn/getn in Lua 5.0. +*/ +#undef LUA_COMPAT_GETN + +/* +@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. +** CHANGE it to undefined as soon as you do not need a global 'loadlib' +** function (the function is still available as 'package.loadlib'). +*/ +#undef LUA_COMPAT_LOADLIB + +/* +@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. +** CHANGE it to undefined as soon as your programs use only '...' to +** access vararg parameters (instead of the old 'arg' table). +*/ +#define LUA_COMPAT_VARARG + +/* +@@ LUA_COMPAT_MOD controls compatibility with old math.mod function. +** CHANGE it to undefined as soon as your programs use 'math.fmod' or +** the new '%' operator instead of 'math.mod'. +*/ +#define LUA_COMPAT_MOD + +/* +@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting +@* facility. +** CHANGE it to 2 if you want the old behaviour, or undefine it to turn +** off the advisory error when nesting [[...]]. +*/ +#define LUA_COMPAT_LSTR 1 + +/* +@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. +** CHANGE it to undefined as soon as you rename 'string.gfind' to +** 'string.gmatch'. +*/ +#define LUA_COMPAT_GFIND + +/* +@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' +@* behavior. +** CHANGE it to undefined as soon as you replace to 'luaL_register' +** your uses of 'luaL_openlib' +*/ +#define LUA_COMPAT_OPENLIB + + + +/* +@@ luai_apicheck is the assert macro used by the Lua-C API. +** CHANGE luai_apicheck if you want Lua to perform some checks in the +** parameters it gets from API calls. This may slow down the interpreter +** a bit, but may be quite useful when debugging C code that interfaces +** with Lua. A useful redefinition is to use assert.h. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(L,o) { (void)L; assert(o); } +#else +#define luai_apicheck(L,o) { (void)L; } +#endif + + +/* +@@ LUAI_BITSINT defines the number of bits in an int. +** CHANGE here if Lua cannot automatically detect the number of bits of +** your machine. Probably you do not need to change this. +*/ +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 +#define LUAI_BITSINT 16 +#elif INT_MAX > 2147483640L +/* int has at least 32 bits */ +#define LUAI_BITSINT 32 +#else +#error "you must define LUA_BITSINT with number of bits in an integer" +#endif + + +/* +@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. +@@ LUAI_INT32 is an signed integer with at least 32 bits. +@@ LUAI_UMEM is an unsigned integer big enough to count the total +@* memory used by Lua. +@@ LUAI_MEM is a signed integer big enough to count the total memory +@* used by Lua. +** CHANGE here if for some weird reason the default definitions are not +** good enough for your machine. (The definitions in the 'else' +** part always works, but may waste space on machines with 64-bit +** longs.) Probably you do not need to change this. +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_UINT32 unsigned int +#define LUAI_INT32 int +#define LUAI_MAXINT32 INT_MAX +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t +#else +/* 16-bit ints */ +#define LUAI_UINT32 unsigned long +#define LUAI_INT32 long +#define LUAI_MAXINT32 LONG_MAX +#define LUAI_UMEM unsigned long +#define LUAI_MEM long +#endif + + +/* +@@ LUAI_MAXCALLS limits the number of nested calls. +** CHANGE it if you need really deep recursive calls. This limit is +** arbitrary; its only purpose is to stop infinite recursion before +** exhausting memory. +*/ +#define LUAI_MAXCALLS 20000 + + +/* +@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function +@* can use. +** CHANGE it if you need lots of (Lua) stack space for your C +** functions. This limit is arbitrary; its only purpose is to stop C +** functions to consume unlimited stack space. +*/ +#define LUAI_MAXCSTACK 2048 + + + +/* +** {================================================================== +** CHANGE (to smaller values) the following definitions if your system +** has a small C stack. (Or you may want to change them to larger +** values if your system has a large C stack and these limits are +** too rigid for you.) Some of these constants control the size of +** stack-allocated arrays used by the compiler or the interpreter, while +** others limit the maximum number of recursive calls that the compiler +** or the interpreter can perform. Values too large may cause a C stack +** overflow for some forms of deep constructs. +** =================================================================== +*/ + + +/* +@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and +@* syntactical nested non-terminals in a program. +*/ +#define LUAI_MAXCCALLS 200 + + +/* +@@ LUAI_MAXVARS is the maximum number of local variables per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXVARS 200 + + +/* +@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXUPVALUES 60 + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +*/ +#define LUAL_BUFFERSIZE BUFSIZ + +/* }================================================================== */ + + + + +/* +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== +*/ + +#define LUA_NUMBER_DOUBLE +#define LUA_NUMBER double + +/* +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@* over a number. +*/ +#define LUAI_UACNUMBER double + + +/* +@@ LUA_NUMBER_SCAN is the format for reading numbers. +@@ LUA_NUMBER_FMT is the format for writing numbers. +@@ lua_number2str converts a number to a string. +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +@@ lua_str2number converts a string to a number. +*/ +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ +#define lua_str2number(s,p) strtod((s), (p)) + + +/* +@@ The luai_num* macros define the primitive operations over numbers. +*/ +#if defined(LUA_CORE) +#include +#define luai_numadd(a,b) ((a)+(b)) +#define luai_numsub(a,b) ((a)-(b)) +#define luai_nummul(a,b) ((a)*(b)) +#define luai_numdiv(a,b) ((a)/(b)) +#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) +#define luai_numpow(a,b) (pow(a,b)) +#define luai_numunm(a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) +#endif + + +/* +@@ lua_number2int is a macro to convert lua_Number to int. +@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. +** CHANGE them if you know a faster way to convert a lua_Number to +** int (with any rounding method and without throwing errors) in your +** system. In Pentium machines, a naive typecast from double to int +** in C is extremely slow, so any alternative is worth trying. +*/ + +/* On a Pentium, resort to a trick */ +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ + (defined(__i386) || defined (_M_IX86) || defined(__i386__)) + +/* On a Microsoft compiler, use assembler */ +#if defined(_MSC_VER) + +#define lua_number2int(i,d) __asm fld d __asm fistp i +#define lua_number2integer(i,n) lua_number2int(i, n) + +/* the next trick should work on any Pentium, but sometimes clashes + with a DirectX idiosyncrasy */ +#else + +union luai_Cast { double l_d; long l_l; }; +#define lua_number2int(i,d) \ + { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } +#define lua_number2integer(i,n) lua_number2int(i, n) + +#endif + + +/* this option always works, but may be slow */ +#else +#define lua_number2int(i,d) ((i)=(int)(d)) +#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. +** CHANGE it if your system requires alignments larger than double. (For +** instance, if your system supports long doubles and they must be +** aligned in 16-byte boundaries, then you should add long double in the +** union.) Probably you do not need to change this. +*/ +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } + + +/* +@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. +** CHANGE them if you prefer to use longjmp/setjmp even with C++ +** or if want/don't to use _longjmp/_setjmp instead of regular +** longjmp/setjmp. By default, Lua handles errors with exceptions when +** compiling as C++ code, with _longjmp/_setjmp when asked to use them, +** and with longjmp/setjmp otherwise. +*/ +#if defined(__cplusplus) +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) try { a } catch(...) \ + { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_ULONGJMP) +/* in Unix, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else +/* default handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif + + +/* +@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern +@* can do during pattern-matching. +** CHANGE it if you need more captures. This limit is arbitrary. +*/ +#define LUA_MAXCAPTURES 32 + + +/* +@@ lua_tmpnam is the function that the OS library uses to create a +@* temporary name. +@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. +** CHANGE them if you have an alternative to tmpnam (which is considered +** insecure) or if you want the original tmpnam anyway. By default, Lua +** uses tmpnam except when POSIX is available, where it uses mkstemp. +*/ +#if defined(loslib_c) || defined(luaall_c) + +#if defined(LUA_USE_MKSTEMP) +#include +#define LUA_TMPNAMBUFSIZE 32 +#define lua_tmpnam(b,e) { \ + strcpy(b, "/tmp/lua_XXXXXX"); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } + +#else +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } +#endif + +#endif + + +/* +@@ lua_popen spawns a new process connected to the current one through +@* the file streams. +** CHANGE it if you have a way to implement it in your system. +*/ +#if defined(LUA_USE_POPEN) + +#define lua_popen(L,c,m) ((void)L, popen(c,m)) +#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) + +#elif defined(LUA_WIN) + +#define lua_popen(L,c,m) ((void)L, _popen(c,m)) +#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) + +#else + +#define lua_popen(L,c,m) ((void)((void)c, m), \ + luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) +#define lua_pclose(L,file) ((void)((void)L, file), 0) + +#endif + +/* +@@ LUA_DL_* define which dynamic-library system Lua should use. +** CHANGE here if Lua has problems choosing the appropriate +** dynamic-library system for your platform (either Windows' DLL, Mac's +** dyld, or Unix's dlopen). If your system is some kind of Unix, there +** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for +** it. To use dlopen you also need to adapt the src/Makefile (probably +** adding -ldl to the linker options), so Lua does not select it +** automatically. (When you change the makefile to add -ldl, you must +** also add -DLUA_USE_DLOPEN.) +** If you do not want any kind of dynamic library, undefine all these +** options. +** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. +*/ +#if defined(LUA_USE_DLOPEN) +#define LUA_DL_DLOPEN +#endif + +#if defined(LUA_WIN) +#define LUA_DL_DLL +#endif + + +/* +@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State +@* (the data goes just *before* the lua_State pointer). +** CHANGE (define) this if you really need that. This value must be +** a multiple of the maximum alignment required for your machine. +*/ +#define LUAI_EXTRASPACE 0 + + +/* +@@ luai_userstate* allow user-specific actions on threads. +** CHANGE them if you defined LUAI_EXTRASPACE and need to do something +** extra when a thread is created/deleted/resumed/yielded. +*/ +#define luai_userstateopen(L) ((void)L) +#define luai_userstateclose(L) ((void)L) +#define luai_userstatethread(L,L1) ((void)L) +#define luai_userstatefree(L) ((void)L) +#define luai_userstateresume(L,n) ((void)L) +#define luai_userstateyield(L,n) ((void)L) + + +/* +@@ LUA_INTFRMLEN is the length modifier for integer conversions +@* in 'string.format'. +@@ LUA_INTFRM_T is the integer type correspoding to the previous length +@* modifier. +** CHANGE them if your system supports long long or does not support long. +*/ + +#if defined(LUA_USELONGLONG) + +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long + +#else + +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long + +#endif + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + +#endif + diff --git a/lua/lualib.h b/lua/lualib.h new file mode 100644 index 00000000..0c76232c --- /dev/null +++ b/lua/lualib.h @@ -0,0 +1,53 @@ +/* +** $Id: lualib.h,v 1.36 2005/12/27 17:12:00 roberto Exp $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +/* Key to file-handle type */ +#define LUA_FILEHANDLE "FILE*" + + +#define LUA_COLIBNAME "coroutine" +LUALIB_API int (luaopen_base) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUALIB_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUALIB_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUALIB_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUALIB_API int (luaopen_string) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUALIB_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUALIB_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUALIB_API int (luaopen_package) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + + +#ifndef lua_assert +#define lua_assert(x) ((void)0) +#endif + + +#endif diff --git a/lua/lwstring.cpp b/lua/lwstring.cpp new file mode 100644 index 00000000..c542bc9f --- /dev/null +++ b/lua/lwstring.cpp @@ -0,0 +1,269 @@ +#include "builddefines.h" +#include + +#include "MemMan.h" + +#include "lwstring.h" + +void luaWS_newlstr (lua_State *L, const CHAR16 *str, size_t l) +{ + TWString *ts; + + // Create and initialize this data + int size = sizewstring( l); + ts = (TWString*) lua_newuserdata( L, size ); + ts->len = l; + memcpy( ts->data, str, size); + + // Make this data a wstring + luaL_getmetatable(L, "wstring"); + lua_setmetatable(L, -2); +} + +// Create a string from a UTF-8 representation +// Called from LUA code +int LuaWStringFromUTF8( lua_State *L ) +{ + const CHAR8 *utf8 = luaL_checkstring( L, 1 ); + STR16 str = NULL; + int len; + + // Find out how long this needs to be + len = MultiByteToWideChar( CP_UTF8, 0, utf8, -1, str, 0); + str = (STR16) MemAlloc( len * sizeof(CHAR16)); + + // Get the string + MultiByteToWideChar( CP_UTF8, 0, utf8, -1, str, len); + + luaWS_newlstr( L, str, len - 1); + + MemFree( str); + return 1; +} + +int LuaWStringByte( lua_State* L ) +{ + int start; + int stop; + int idx; + TWString *tw; + + tw = (TWString*) luaL_checkudata( L, 1, "wstring" ); + start = luaL_optint( L, 2, 1 ); + stop = luaL_optint( L, 3, 1 ); + + // This function in the char strings will return nothing if the params are out of bounds. + if (start < 1 || start >= tw->len || + stop < start) + { + return 0; + } + if (stop >= tw->len) + { + stop = tw->len; + } + + // Make these 0-based + start--; + + for (idx = start; idx < stop; idx++) + { + lua_pushinteger( L, tw->data[ idx] ); + } + + return stop - start; +} + +static int LuaWStringChar( lua_State *L ) +{ + int len = lua_gettop( L) + 1; + STR16 str = (STR16) MemAlloc( len * sizeof( CHAR16) ); + int idx; + + len--; + for( idx=0; idxlen ); + return 1; +} + +static int LuaWStringLower( lua_State *L ) +{ + TWString *tw = (TWString*) luaL_checkudata( L, 1, "wstring" ); + int len = tw->len + 1; + STR16 str = (STR16) MemAlloc( len * sizeof( CHAR16) ); + int idx; + + for( idx=0; idxdata[ idx ] ); + } + str[ idx ] = 0; + + luaWS_newlstr( L, str, len-1); + + MemFree( str); + return 1; +} + +static int LuaWStringMatch( lua_State *L ) +{ + return 0; +} + +static int LuaWStringRep( lua_State *L ) +{ + TWString *tw = (TWString*) luaL_checkudata( L, 1, "wstring" ); + int num = (luaL_checkint( L, 2) >= 0) ? lua_tointeger( L, 2) : 0; + int len = tw->len * num + 1; + STR16 str = (STR16) MemAlloc( len * sizeof( CHAR16) ); + int idx; + + if (num > 0) + { + wcscpy( str, tw->data); + } + for( idx=1; idxdata); + } + + luaWS_newlstr( L, str, len-1); + + MemFree( str); + return 1; +} + +static int LuaWStringReverse( lua_State *L ) +{ + TWString *tw = (TWString*) luaL_checkudata( L, 1, "wstring" ); + int len = tw->len + 1; + STR16 str = (STR16) MemAlloc( len * sizeof( CHAR16) ); + int idx; + + for( idx=0; idxdata[ tw->len - idx - 1 ]; + } + str[ idx ] = 0; + + luaWS_newlstr( L, str, len-1); + + MemFree( str); + return 1; +} + +static int LuaWStringSub( lua_State *L ) +{ + return 0; +} + +static int LuaWStringUpper( lua_State *L ) +{ + TWString *tw = (TWString*) luaL_checkudata( L, 1, "wstring" ); + int len = tw->len + 1; + STR16 str = (STR16) MemAlloc( len * sizeof( CHAR16) ); + int idx; + + for( idx=0; idxdata[ idx ] ); + } + str[ idx ] = 0; + + luaWS_newlstr( L, str, len-1); + + MemFree( str); + return 1; +} + +static int LuaWStringToString( lua_State *L ) +{ + TWString *tw = (TWString*) luaL_checkudata( L, 1, "wstring" ); + int len = tw->len; + int newlen; + STR8 newstr = NULL; + + newlen = WideCharToMultiByte( CP_UTF8, 0, tw->data, -1, newstr, 0, NULL, NULL); + newstr = (STR8) MemAlloc( newlen); + WideCharToMultiByte( CP_UTF8, 0, tw->data, -1, newstr, newlen, NULL, NULL); + lua_pushstring( L, newstr); + MemFree( newstr); + return 1; +} + +static int LuaWStringIndex( lua_State *L ) +{ + TWString *tw = (TWString*) luaL_checkudata( L, 1, "wstring" ); + const CHAR8 *idx = luaL_checkstring( L, 2 ); + + // Disqualify metafunctions + if ( idx[0] == '_' && idx[1] == '_' ) + { + lua_pushnil( L ); + return 1; + } + + lua_getmetatable( L, 1 ); + lua_insert( L, 2 ); + lua_rawget( L, 2 ); + return 1; +} + +luaL_Reg WStringMethods[] = { + // Constructors + { "fromUTF8", LuaWStringFromUTF8, }, + + // String-specific + { "byte", LuaWStringByte, }, + { "char", LuaWStringChar, }, + { "find", LuaWStringFind, }, + { "format", LuaWStringFormat, }, + { "gmatch", LuaWStringGMatch, }, + { "gsub", LuaWStringGSub, }, + { "len", LuaWStringLen, }, + { "lower", LuaWStringLower, }, + { "match", LuaWStringMatch, }, + { "rep", LuaWStringRep, }, + { "reverse", LuaWStringReverse, }, + { "sub", LuaWStringSub, }, + { "upper", LuaWStringUpper, }, + + // Special functions + { "__tostring", LuaWStringToString, }, + { "__index", LuaWStringIndex, }, + { NULL, }, +}; diff --git a/lua/lwstring.h b/lua/lwstring.h new file mode 100644 index 00000000..91bb47fc --- /dev/null +++ b/lua/lwstring.h @@ -0,0 +1,32 @@ +/* +** $Id: lstring.h,v 1.43 2005/04/25 19:24:10 roberto Exp $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lwstring_h +#define lwstring_h + +#include + +extern "C" { +#include +#include +#include +} + +#include "Types.h" + +typedef struct { + int len; + CHAR16 data[1]; +} TWString; + +#define sizewstring(s) (sizeof(int) + (s) * sizeof(CHAR16) + sizeof(CHAR16)) + +#define luaWS_newstr(L, s) (luaWS_newlstr(L, s, wcslen(s))) + +void luaWS_newlstr (lua_State *L, const CHAR16 *str, size_t l); + + +#endif diff --git a/lua5.1.lib b/lua5.1.lib new file mode 100644 index 0000000000000000000000000000000000000000..6fb4f0559423090562e12e59a90953c43632d29e GIT binary patch literal 472096 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 z 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

Ff;6W5I#kk3`IkiboN$@_rA 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�KjVc)4%TR9TS?UMrWyBu%DhbsUn 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 mh=r5;e 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 literal 0 HcmV?d00001