diff -urN sourceold/engine/DBVehicleBypass.cpp source/engine/DBVehicleBypass.cpp --- sourceold/engine/DBVehicleBypass.cpp 1970-01-01 10:00:00.000000000 +1000 +++ source/engine/DBVehicleBypass.cpp 2019-02-15 09:37:36.719000000 +1000 @@ -0,0 +1,183 @@ +/* Renegade Scripts.dll + Copyright 2013 Tiberian Technologies + + This file is part of the Renegade scripts.dll + The Renegade scripts.dll is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2, or (at your option) any later + version. See the file COPYING for more details. + In addition, an exemption is given to allow Run Time Dynamic Linking of this code with any closed source module that does not contain code covered by this licence. + Only the source code to the module(s) containing the licenced code has to be released. +*/ +#include "general.h" +#include "scripts.h" +#include "engine_tt.h" +#include "engine_player.h" +#include "engine_def.h" +#include "engine_script.h" +#include "VehicleGameObj.h" +#include "engine_obj.h" + +void Bypass_Drop_Off(Vector3 Location, float Facing, GameObject *dropObj) +{ + Location.Z += 1; + + GameObject *Drop = Commands->Create_Object("invisible_object", Location); + Commands->Set_Facing(Drop,Facing); + Commands->Attach_Script(Drop,"Bypass_Drop_Off_Control",StringClass::getFormattedString("%i",dropObj->Get_ID())); +} + +class DB_CinematicVehicleFactoryBypass: public JFW_Object_Created_Hook_Base +{ +public: + void ObjectCreateHook(GameObject *obj) + { + if(obj->As_VehicleGameObj()) + { + if(strcmp(Commands->Get_Preset_Name(obj),Get_Parameter("PresetName")) == 0) + { + { + Attach_Script_Once_V(obj,"DB_Check_Airdrop","%i",Owner()->Get_ID()); + } + + } + } + } +}; + +class DB_Check_Airdrop: public ScriptImpClass { + void Created(GameObject *obj) { + Commands->Start_Timer(obj,this,0.0f,12); + } + + void Timer_Expired(GameObject *obj,int Number) + { + if(Number == 12) + { + if(obj->As_VehicleGameObj()->Get_Lock_Owner() && Commands->Get_Player_Type(obj->As_VehicleGameObj()->Get_Lock_Owner()) == 1 && !obj->Find_Observer("DAAirDroppedVehicleObserverClass")) + { + GameObject *DavesArrow = Commands->Find_Object(Get_Int_Parameter("ArrowID")); + if(DavesArrow) + { + Send_Message_Player(obj->As_VehicleGameObj()->Get_Lock_Owner(),150,150,255,"Your Vehicle will be Airdropped nearby."); + Bypass_Drop_Off(Commands->Get_Position(DavesArrow),Commands->Get_Facing(DavesArrow),obj); + } + } + } + } +}; + +ScriptRegistrant DB_CinematicVehicleFactoryBypass_Registrant("DB_CinematicVehicleFactoryBypass","PresetName:string"); +ScriptRegistrant DB_Check_Airdrop_Registrant("DB_Check_Airdrop","ArrowID:int"); + +class Bypass_Drop_Off_Control : public ScriptImpClass +{ + int transbone_id; + int trans_id; + int vehharness_id; + int vehicle_id; + int fakeharness_id; + bool invisible; + void Created(GameObject *obj); + void Timer_Expired(GameObject *obj, int number); +}; + +void Bypass_Drop_Off_Control::Created(GameObject *obj) +{ + + + //SignalFlare_Gold_Phys3 + invisible = false; + int ID = Get_Int_Parameter("ID"); + GameObject* vehicle = Commands->Find_Object(ID); + if(vehicle) + { + int Team = Get_Object_Type(vehicle); + Vector3 pos = Commands->Get_Position(obj); + + GameObject *transbone = Commands->Create_Object("Generic_Cinematic", pos); + Commands->Set_Model(transbone, "XG_TransprtBone"); + Commands->Set_Animation(transbone, "XG_TransprtBone.XG_HD_TTraj", false, "", 2.0, -1.0, false); + + GameObject *trans = Commands->Create_Object_At_Bone(transbone, Team == 1 ? "GDI_Transport_Helicopter" : "Nod_Transport_Helicopter", "BN_Trajectory"); + + Commands->Set_Animation(trans, "v_Nod_Trnspt.v_Nod_Trnspt", true, "", 2.0, -1.0, false); + //Set_Vehicle_Is_Visible(trans, false); + Commands->Set_Shield_Type(trans,"Blamo"); + Commands->Attach_To_Object_Bone(trans, transbone, "BN_Trajectory"); + + GameObject *vehharness = Commands->Create_Object("Generic_Cinematic", pos); + Commands->Set_Model(vehharness, "XG_HD_HTraj"); + Commands->Set_Animation(vehharness, "XG_HD_HTraj.XG_HD_HTraj", false, "", 2.0, -1.0, false); + + GameObject *fakeharness = Commands->Create_Object("Generic_Cinematic", pos); + Commands->Set_Model(fakeharness, "XG_HD_Harness"); + Commands->Set_Animation(fakeharness, "XG_HD_Harness.XG_HD_Harness", false, "", 2.0, -1.0, false); + + Set_Object_Type(vehicle, Team); + if(vehicle->As_VehicleGameObj()) + { + if(vehicle->As_VehicleGameObj()->Get_Is_Scripts_Visible()) + { + Commands->Set_Is_Visible(vehicle, false); + invisible=false; + } + else + { + invisible=true; + } + } + Commands->Attach_To_Object_Bone(vehicle, vehharness, "BN_Trajectory"); + + transbone_id = Commands->Get_ID(transbone); + trans_id = Commands->Get_ID(trans); + vehharness_id = Commands->Get_ID(vehharness); + vehicle_id = Commands->Get_ID(vehicle); + fakeharness_id = Commands->Get_ID(fakeharness); + + Commands->Start_Timer(obj, this, 14.2f, 1); + Commands->Start_Timer(obj, this, 30, 2); + } +} + +void Bypass_Drop_Off_Control::Timer_Expired(GameObject *obj, int number) +{ + if(number == 1) + { + GameObject *Vehicle = Commands->Find_Object(vehicle_id); + if(Vehicle) + { + Commands->Attach_To_Object_Bone(Commands->Find_Object(vehicle_id), 0, 0); + if(Vehicle->As_VehicleGameObj()) + { + if(!invisible) + { + Commands->Set_Is_Visible(Vehicle,true); + } + } + } + } + else if(number == 2) + { + GameObject *TransbonePreset = Commands->Find_Object(transbone_id); + + if(TransbonePreset) Commands->Destroy_Object(TransbonePreset); + + GameObject *HarnessPreset = Commands->Find_Object(vehharness_id); + + if(HarnessPreset) Commands->Destroy_Object(HarnessPreset); + + GameObject *FakeHarnessPreset = Commands->Find_Object(fakeharness_id); + + if(FakeHarnessPreset) Commands->Destroy_Object(FakeHarnessPreset); + + GameObject *TransportPreset = Commands->Find_Object(trans_id); + + if(TransportPreset) Commands->Destroy_Object(TransportPreset); + + Destroy_Script(); + } + +} + +ScriptRegistrant DropOffControlRegistrant("Bypass_Drop_Off_Control", "ID:int"); \ No newline at end of file diff -urN sourceold/scripts/DBIKScripts.cpp source/scripts/DBIKScripts.cpp --- sourceold/scripts/DBIKScripts.cpp 2018-11-11 08:30:08.519600000 +1000 +++ source/scripts/DBIKScripts.cpp 2019-02-15 09:37:36.760000000 +1000 @@ -11,6 +11,7 @@ #include "GameObjManager.h" #include "DB_General.h" #include "PurchaseSettingsDefClass.h" +#include "dp88_custom_timer_defines.h" #ifdef DRAGONADE #include "engine_da.h" #endif // DRAGONADE @@ -1256,6 +1257,7 @@ { Commands->Set_Player_Type(turret,Commands->Get_Player_Type(sender)); Commands->Action_Reset(turret,100); + Commands->Send_Custom_Event(turret,turret,CUSTOM_AI_ENABLEAI,0,0); } } } @@ -1270,6 +1272,7 @@ Commands->Set_Player_Type(turret,Commands->Get_Player_Type(obj)); Commands->Action_Reset(turret,201); bombard=false; + Commands->Send_Custom_Event(turret,turret,CUSTOM_AI_DISABLEAI,0,0); } } } @@ -1295,6 +1298,7 @@ var.Set_Attack(obj->As_VehicleGameObj()->Get_Targeting_Pos(),1000,0,true); Commands->Action_Attack(turret,var); bombard=true; + Commands->Send_Custom_Event(turret,turret,CUSTOM_AI_DISABLEAI,0,0); Set_HUD_Help_Text_Player_Text(sender,7403,"Manual Targeting set, Press 'T' to switch to auto targeting",Vector3(0.3f,0.3f,1.0f)); } } @@ -1305,6 +1309,7 @@ { Commands->Action_Reset(turret,201); bombard=false; + Commands->Send_Custom_Event(turret,turret,CUSTOM_AI_ENABLEAI,0,0); Set_HUD_Help_Text_Player_Text(sender,7403,"Auto Targeting set, Press 'T' to set manual target location",Vector3(0.3f,0.3f,1.0f)); } } @@ -1629,35 +1634,38 @@ void DB_Drop_Wreckage_On_Death::Killed(GameObject *obj,GameObject *killer) { - if(Find_Named_Definition(Get_Parameter("Wreckage_Preset")) && obj->As_VehicleGameObj()) + if(Get_Damage_Warhead()!=25) { - Matrix3D transform = obj->As_PhysicalGameObj()->Get_Transform(); - GameObject *CurTank; - CurTank = Commands->Create_Object(Get_Parameter("Wreckage_Preset"),Commands->Get_Position(obj)); - if(CurTank) + if(Find_Named_Definition(Get_Parameter("Wreckage_Preset")) && obj->As_VehicleGameObj()) { - PhysicalGameObj *Shell = (PhysicalGameObj*)Commands->Create_Object("Mounted",Commands->Get_Position(obj)); - if(Shell) + Matrix3D transform = obj->As_PhysicalGameObj()->Get_Transform(); + GameObject *CurTank; + CurTank = Commands->Create_Object(Get_Parameter("Wreckage_Preset"),Commands->Get_Position(obj)); + if(CurTank) { - Shell->Set_Transform(transform); - Commands->Set_Model(Shell,Get_Model(CurTank)); - Shell->Set_Collision_Group(SOLDIER_GHOST_COLLISION_GROUP); - Shell->Set_Player_Type(-2); - Commands->Enable_Vehicle_Transitions(Shell,false); - DefenseObjectClass *WreckDefense = CurTank->As_DamageableGameObj()->Get_Defense_Object(); - DefenseObjectClass *ShellDefense = Shell->Get_Defense_Object(); - ShellDefense->Set_Health_Max(WreckDefense->Get_Health_Max()); - ShellDefense->Set_Shield_Strength_Max(WreckDefense->Get_Shield_Strength_Max()); - Commands->Set_Health(Shell,WreckDefense->Get_Health()); - Commands->Set_Shield_Strength(Shell,WreckDefense->Get_Shield_Strength()); - ShellDefense->Set_Skin(WreckDefense->Get_Skin()); - ShellDefense->Set_Shield_Type(WreckDefense->Get_Shield_Type()); - ShellDefense->Set_Damage_Points(0.0f); - ShellDefense->Set_Death_Points(0.0f); - CurTank->Set_Delete_Pending(); - Commands->Attach_Script(Shell,"DB_Wreckage_Rebuildable",Commands->Get_Preset_Name(obj)); - Update_Network_Object(Shell); - Force_Orientation_Update(Shell); + PhysicalGameObj *Shell = (PhysicalGameObj*)Commands->Create_Object("Mounted",Commands->Get_Position(obj)); + if(Shell) + { + Shell->Set_Transform(transform); + Commands->Set_Model(Shell,Get_Model(CurTank)); + Shell->Set_Collision_Group(SOLDIER_GHOST_COLLISION_GROUP); + Shell->Set_Player_Type(-2); + Commands->Enable_Vehicle_Transitions(Shell,false); + DefenseObjectClass *WreckDefense = CurTank->As_DamageableGameObj()->Get_Defense_Object(); + DefenseObjectClass *ShellDefense = Shell->Get_Defense_Object(); + ShellDefense->Set_Health_Max(WreckDefense->Get_Health_Max()); + ShellDefense->Set_Shield_Strength_Max(WreckDefense->Get_Shield_Strength_Max()); + Commands->Set_Health(Shell,WreckDefense->Get_Health()); + Commands->Set_Shield_Strength(Shell,WreckDefense->Get_Shield_Strength()); + ShellDefense->Set_Skin(WreckDefense->Get_Skin()); + ShellDefense->Set_Shield_Type(WreckDefense->Get_Shield_Type()); + ShellDefense->Set_Damage_Points(0.0f); + ShellDefense->Set_Death_Points(0.0f); + CurTank->Set_Delete_Pending(); + Commands->Attach_Script(Shell,"DB_Wreckage_Rebuildable",Commands->Get_Preset_Name(obj)); + Update_Network_Object(Shell); + Force_Orientation_Update(Shell); + } } } } @@ -1747,7 +1755,7 @@ { if(Get_Float_Parameter("Damage_Distance")>100) { - Console_Input(StringClass::getFormattedString("msg bad occupant damage settings - %s",Commands->Get_Preset_Name(obj))); + //Console_Input(StringClass::getFormattedString("msg bad occupant damage settings - %s",Commands->Get_Preset_Name(obj))); Set_Parameters_String(",Fire,150,3.5"); } Vector3 pos = Commands->Get_Position(obj); diff -urN sourceold/scripts/DB_Research_Terminals.cpp source/scripts/DB_Research_Terminals.cpp --- sourceold/scripts/DB_Research_Terminals.cpp 2017-11-23 05:41:45.152800000 +1000 +++ source/scripts/DB_Research_Terminals.cpp 2019-02-15 09:37:36.761000000 +1000 @@ -946,6 +946,8 @@ Commands->Send_Custom_Event(obj,obj,UNDEPLOY_BEGIN_CUSTOM,0,0); mode = 3; Set_Model_Custom(obj,dmodel); + Commands->Set_Animation_Frame(obj,deployanim,(int)Get_Float_Parameter("Last_Deploy_Frame")); + Update_Network_Object(obj); Commands->Set_Animation(obj,deployanim,false,0,Get_Float_Parameter("Last_Deploy_Frame"),0,0); Commands->Clear_Weapons(obj); Commands->Give_PowerUp(obj,Get_Parameter("Weapon_Powerup_Name2"),false); diff -urN sourceold/scripts/SoldierGameObj.h source/scripts/SoldierGameObj.h --- sourceold/scripts/SoldierGameObj.h 2018-12-13 16:17:42.213400000 +1000 +++ source/scripts/SoldierGameObj.h 2019-02-15 09:37:36.762000000 +1000 @@ -207,6 +207,10 @@ virtual void Set_Skeleton_Height( float height ); virtual float Get_Skeleton_Width( void ); virtual void Set_Skeleton_Width( float width ); + virtual void Set_Override_Weapon_Hold_Style(int overrideWeaponHoldStyleId); + virtual int Get_Override_Weapon_Hold_Style(); + virtual void Set_Human_Anim_Override(bool enableHumanAnimOverride); + virtual int Get_Human_Anim_Override(); protected: RenderObjClass * WeaponRenderModel; //2416 RenderObjClass * BackWeaponRenderModel; //2420 @@ -282,6 +286,8 @@ float skeletonWidth; float lastSkeletonHeight; float lastSkeletonWidth; + int overrideWeaponHoldStyleId; + bool enableHumanAnimOverride; TT_DEPRECATED("Do not use") int Check(void); }; // size: 3404 diff -urN sourceold/scripts/VehicleGameObj.h source/scripts/VehicleGameObj.h --- sourceold/scripts/VehicleGameObj.h 2018-11-17 10:23:57.117600000 +1000 +++ source/scripts/VehicleGameObj.h 2019-02-15 09:37:36.763000000 +1000 @@ -248,8 +248,8 @@ void Aquire_Turret_Bones( void ); void Release_Turret_Bones( void ); void Reset_Sound_Effects( void ); -protected: void Update_Turret( float weapon_turn, float weapon_tilt ); +protected: void Update_Sound_Effects( void ); void Change_Engine_Sound_State( int new_state ); void Update_Engine_Sound_Pitch( void ); diff -urN sourceold/scripts/dp88_customAI.cpp source/scripts/dp88_customAI.cpp --- sourceold/scripts/dp88_customAI.cpp 2018-11-17 10:23:57.144600000 +1000 +++ source/scripts/dp88_customAI.cpp 2019-02-15 09:37:36.764000000 +1000 @@ -45,11 +45,17 @@ { m_bAiEnabled = false; AIStateChanged(pObj, false); + targetID = 0; + targetPriority = 0.0f; + targetLastSeen = 0; } else if ( message == CUSTOM_AI_ENABLEAI && !m_bAiEnabled ) { m_bAiEnabled = true; + targetID = 0; + targetPriority = 0.0f; + targetLastSeen = 0; AIStateChanged(pObj, true); } } @@ -888,12 +894,12 @@ // Otherwise setup a new action else { + params.AttackObject = 0; // Reset any current attack (note: specifically use the function from THIS // class and not a derived class as we do not know what functionality may // be implemented in a derived class) dp88_AI_Turret::stopAttacking(obj); - params.AttackObject = 0; params.Set_Basic( this, 100.0f, 8951 ); params.Set_Attack( location, (primary)?(float)primary_maxRange:(float)secondary_maxRange, 0.0, primary); params.AttackCheckBlocked = false; diff -urN sourceold/scripts/engine_game.cpp source/scripts/engine_game.cpp --- sourceold/scripts/engine_game.cpp 2018-11-17 10:23:57.158600000 +1000 +++ source/scripts/engine_game.cpp 2019-02-15 09:37:36.765000000 +1000 @@ -81,6 +81,8 @@ cGameDataSinglePlayer SCRIPTS_API *The_Single_Player_Game() AT2(0x00477CB0,0x00477380); +bool AllMapsAreFlying = false; + void BaseControllerClass::Check_Vehicle_Factory() { if (CombatManager::I_Am_Server()) @@ -257,7 +259,7 @@ bool SCRIPTS_API Is_Map_Flying() { - return IsMapVTOL; + return IsMapVTOL || AllMapsAreFlying; } GameObject SCRIPTS_API *Create_Building(const char *preset,const Vector3 & Position) diff -urN sourceold/scripts/jmgUtility.cpp source/scripts/jmgUtility.cpp --- sourceold/scripts/jmgUtility.cpp 2018-12-13 16:17:42.216400000 +1000 +++ source/scripts/jmgUtility.cpp 2019-02-15 09:37:36.768000000 +1000 @@ -10,6 +10,7 @@ #include "SoldierGameObj.h" #include "BuildingGameObj.h" #include "engine_player.h" +#include "DefinitionMgrClass.h" bool JmgUtility::hasStatedDeathMessage[128] = {false}; void JMG_Utility_Check_If_Script_Is_In_Library::Created(GameObject *obj) @@ -2180,7 +2181,7 @@ { if (!enter->As_SoldierGameObj()) return; - if (!Is_Script_Attached(enter,"JMG_Utility_Swimming_Infantry")) + if (!Is_Script_Attached(enter,"JMG_Utility_Swimming_Infantry") && !Is_Script_Attached(enter,"JMG_Utility_Swimming_Infantry_Advanced")) { Commands->Apply_Damage(enter,9999.9f,"Death",obj); if (Commands->Is_A_Star(enter) && !Commands->Get_Health(enter)) @@ -2247,7 +2248,7 @@ HideSoundEmitter(&pantSoundId); if (startedFadeRed) { - Set_Screen_Fade_Color_Player(obj,1.0f,0.0f,0.0f,JmgUtility::MathClamp(Get_Float_Parameter("DrownTime")-drownTime,0,Get_Float_Parameter("StarDrownSequence"))); + Set_Screen_Fade_Color_Player(obj,1.0f,0.0f,0.0f,JmgUtility::MathClamp(Get_Float_Parameter("DrownTime")-drownTime,0,Get_Float_Parameter("StartDrownSequence"))); CreateSoundEmitter(obj,Get_Parameter("HeartBeatSoundEmitterModel"),&heartBeatSoundId); } else @@ -2256,10 +2257,10 @@ Set_Fog_Range_Player(obj,JMG_Utility_Swimming_Zone::waterNode[playerId].waterMinViewDistance,JMG_Utility_Swimming_Zone::waterNode[playerId].waterMaxViewDistance,0.1f); } drownTime += 0.1f; - if (!startedFadeRed && drownTime >= Get_Float_Parameter("DrownTime")-Get_Float_Parameter("StarDrownSequence")) + if (!startedFadeRed && drownTime >= Get_Float_Parameter("DrownTime")-Get_Float_Parameter("StartDrownSequence")) { startedFadeRed = true; - Set_Screen_Fade_Color_Player(obj,1.0f,0.0f,0.0f,Get_Float_Parameter("StarDrownSequence")); + Set_Screen_Fade_Color_Player(obj,1.0f,0.0f,0.0f,Get_Float_Parameter("StartDrownSequence")); CreateSoundEmitter(obj,Get_Parameter("HeartBeatSoundEmitterModel"),&heartBeatSoundId); } if (drownTime >= Get_Float_Parameter("DrownTime")) @@ -2282,7 +2283,7 @@ if (drownTime) { drownTime -= Get_Float_Parameter("CatchBreathRate"); - if (startedFadeRed && drownTime < Get_Float_Parameter("DrownTime")-Get_Float_Parameter("StarDrownSequence")) + if (startedFadeRed && drownTime < Get_Float_Parameter("DrownTime")-Get_Float_Parameter("StartDrownSequence")) startedFadeRed = false; if (drownTime <= 0) { @@ -10444,7 +10445,6 @@ { custom = Get_Int_Parameter("Custom"); width = Get_Float_Parameter("Width"); - Commands->Start_Timer(obj,this,0.1f,1); } void JMG_Utility_Custom_Set_Infantry_Width::Custom(GameObject *obj,int message,int param,GameObject *sender) { @@ -10456,6 +10456,425 @@ obj->As_SoldierGameObj()->Set_Skeleton_Width(width); } } +void JMG_Utility_Custom_Set_Weapon_Hold_Sytle::Created(GameObject *obj) +{ + custom = Get_Int_Parameter("Custom"); + style = Get_Int_Parameter("Style"); +} +void JMG_Utility_Custom_Set_Weapon_Hold_Sytle::Custom(GameObject *obj,int message,int param,GameObject *sender) +{ + if (message == custom) + { + obj->As_SoldierGameObj()->Set_Override_Weapon_Hold_Style(style == -2 ? param : style); + } +} +void JMG_Utility_Custom_Set_Human_Anim_Override::Created(GameObject *obj) +{ + custom = Get_Int_Parameter("Custom"); + enable = Get_Int_Parameter("Enable") ? true : false; +} +void JMG_Utility_Custom_Set_Human_Anim_Override::Custom(GameObject *obj,int message,int param,GameObject *sender) +{ + if (message == custom) + { + obj->As_SoldierGameObj()->Set_Human_Anim_Override(enable); + } +} +void JMG_Utility_Swimming_Infantry_Advanced::Created(GameObject *obj) +{ + lastDisplayTime = NULL; + lastWaterZoneId = 0; + heartBeatSoundId = 0; + pantSoundId = 0; + playerId = JmgUtility::JMG_Get_Player_ID(obj); + underwater = false; + waterZoneCount = 0; + startedFadeRed = false; + drownTime = 0.0f; + defaultSpeed = obj->As_SoldierGameObj()->Get_Max_Speed(); + defaultHoldStyle = Get_Int_Parameter("DefaultHoldStyle"); + defaultSwimSpeedMultiplier = Get_Float_Parameter("DefaultSwimSpeed"); + waterDamageDelayTime = remainingWaterDamageDelay = Get_Int_Parameter("WaterDamageDelayTime"); + waterDamageDelayTimeRecover = Get_Int_Parameter("WaterDamageDelayTimeRecover"); + sprintf(originalSkin,""); + sprintf(originalArmor,""); + sprintf(originalModel,""); + waterSpeedMultiplier = 1.0f; + sprintf(defaultWeaponPreset,"%s",Get_Parameter("WeaponPreset")); + defaultDrownTime = Get_Float_Parameter("DrownTime"); + startDrownSequence = Get_Float_Parameter("StartDrownSequence"); + waterDamageAmount = Get_Float_Parameter("WaterDamageAmount"); + sprintf(waterDamageWarhead,"%s",Get_Parameter("WaterDamageWarhead")); + sprintf(swimmingSkin,"%s",Get_Parameter("SwimmingSkin")); + sprintf(swimmingArmor,"%s",Get_Parameter("SwimmingArmor")); + sprintf(swimmingModel,"%s",Get_Parameter("SwimmingModel")); + enterWaterMessageStringId = Get_Int_Parameter("EnterWaterMessageStringId"); + waterEnterMessageColorRGB = Get_Vector3_Parameter("WaterEnterMessageColor[R|G|B]"); + sprintf(heartBeatSoundEmitterModel,"%s",Get_Parameter("HeartBeatSoundEmitterModel")); + sprintf(pantingSoundEmitterModel,"%s",Get_Parameter("PantingSoundEmitterModel")); + sprintf(gaspForBreath,"%s",Get_Parameter("GaspForBreath")); + catchBreathRate = Get_Float_Parameter("CatchBreathRate"); + forceDefinedWeapons = Get_Int_Parameter("ForceDefinedWeapons") ? true : false; + weaponGroupId = Get_Int_Parameter("WeaponsGroupID"); + swimmingHeightScale = Get_Float_Parameter("SwimmingHeightScale"); + swimmingWidthScale = Get_Float_Parameter("SwimmingWidthScale"); + originalHeightScale = 0.0f; + originalWidthScale = 0.0f; + drownDamageRate = drownDamageRate; + weaponSwitchForward = true; + for (SLNode* node = GameObjManager::ScriptZoneGameObjList.Head(); node; node = node->Next()) + { + GameObject *zone = (GameObject *)node->Data(); + if (Is_Script_Attached(zone,"JMG_Utility_Swimming_Zone") && IsInsideZone(zone,obj)) + Commands->Send_Custom_Event(obj,obj,347341,347341,0.25f); + } + Commands->Start_Timer(obj,this,0.1f,1); +} +void JMG_Utility_Swimming_Infantry_Advanced::Timer_Expired(GameObject *obj,int number) +{ + if (number == 1 && Commands->Get_Health(obj) && !The_Game()->Is_Game_Over()) + { + if (obj->As_SoldierGameObj()->Is_Crouched() && !obj->As_SoldierGameObj()->Is_Airborne() && waterZoneCount) + { + if (!underwater) + { + underwater = true; + JMG_Utility_Swimming_Infantry::isUnderwater[playerId] = true; + HideSoundEmitter(&pantSoundId); + if (startedFadeRed) + { + Set_Screen_Fade_Color_Player(obj,1.0f,0.0f,0.0f,JmgUtility::MathClamp(defaultDrownTime-drownTime,0,startDrownSequence)); + CreateSoundEmitter(obj,heartBeatSoundEmitterModel,&heartBeatSoundId); + } + else + Set_Screen_Fade_Color_Player(obj,JMG_Utility_Swimming_Zone::waterNode[playerId].waterColor.X,JMG_Utility_Swimming_Zone::waterNode[playerId].waterColor.Y,JMG_Utility_Swimming_Zone::waterNode[playerId].waterColor.Z,0.0f); + Set_Screen_Fade_Opacity_Player(obj,JMG_Utility_Swimming_Zone::waterNode[playerId].waterColorOpacity,0.1f); + Set_Fog_Range_Player(obj,JMG_Utility_Swimming_Zone::waterNode[playerId].waterMinViewDistance,JMG_Utility_Swimming_Zone::waterNode[playerId].waterMaxViewDistance,0.1f); + } + drownTime += 0.1f; + if (!startedFadeRed && drownTime >= defaultDrownTime-startDrownSequence) + { + startedFadeRed = true; + Set_Screen_Fade_Color_Player(obj,1.0f,0.0f,0.0f,startDrownSequence); + CreateSoundEmitter(obj,heartBeatSoundEmitterModel,&heartBeatSoundId); + } + if (drownTime >= defaultDrownTime) + Commands->Apply_Damage(obj,drownDamageRate,"None",obj); + } + else + { + if (underwater) + { + underwater = false; + JMG_Utility_Swimming_Infantry::isUnderwater[playerId] = false; + JMG_Utility_Set_Screen_Color_Fade_Controller::Update_Player(obj,0.1f); + Set_Fog_Range_Player(obj,JMG_Utility_Swimming_Zone::fogMinDistance,JMG_Utility_Swimming_Zone::fogMaxDistance,0.1f); + HideSoundEmitter(&heartBeatSoundId); + if (drownTime > 1.0f) + CreateSoundEmitter(obj,pantingSoundEmitterModel,&pantSoundId); + if (drownTime > defaultDrownTime) + Commands->Create_3D_Sound_At_Bone(gaspForBreath,obj,"c head"); + } + if (drownTime) + { + drownTime -= catchBreathRate; + if (startedFadeRed && drownTime < defaultDrownTime-startDrownSequence) + startedFadeRed = false; + if (drownTime <= 0) + { + drownTime = 0.0f; + HideSoundEmitter(&pantSoundId); + } + } + } + if (waterZoneCount) + { + SwitchWeapon(obj); + if (remainingWaterDamageDelay) + remainingWaterDamageDelay--; + if (!remainingWaterDamageDelay && waterDamageAmount) + Commands->Apply_Damage(obj,waterDamageAmount,waterDamageWarhead,Commands->Find_Object(lastWaterZoneId)); + } + else if (!JMG_Utility_Swimming_Infantry::isInWater[playerId] && remainingWaterDamageDelay < waterDamageDelayTime) + { + remainingWaterDamageDelay += waterDamageDelayTimeRecover; + if (remainingWaterDamageDelay > waterDamageDelayTime) + remainingWaterDamageDelay = waterDamageDelayTime; + } + Commands->Start_Timer(obj,this,0.1f,1); + } +} +void JMG_Utility_Swimming_Infantry_Advanced::Custom(GameObject *obj,int message,int param,GameObject *sender) +{ + if (message == 347340) + { + Commands->Send_Custom_Event(sender,obj,347342,param,0.25f); + } + if (message == 347342) + { + if (obj->As_SoldierGameObj()->Is_Airborne()) + { + Commands->Send_Custom_Event(sender,obj,message,param,0.25f); + return; + } + waterZoneCount--; + if (!waterZoneCount) + { + JMG_Utility_Swimming_Infantry::isInWater[playerId] = false; + obj->As_SoldierGameObj()->Set_Can_Play_Damage_Animations(true); + obj->As_SoldierGameObj()->Set_Movement_Loiters_Allowed(true); + obj->As_SoldierGameObj()->Set_Human_Anim_Override(true); + obj->As_SoldierGameObj()->Set_Override_Weapon_Hold_Style(-1); + if (forceDefinedWeapons && Has_Weapon(obj,enterWeapon)) + Commands->Select_Weapon(obj,enterWeapon); + if (Has_Weapon(obj,defaultWeaponPreset)) + Remove_Weapon(obj,defaultWeaponPreset); + obj->As_SoldierGameObj()->Set_Max_Speed(defaultSpeed); + if (_stricmp(swimmingSkin,"")) + Set_Skin(obj,originalSkin); + if (_stricmp(swimmingArmor,"")) + Commands->Set_Shield_Type(obj,originalArmor); + if (_stricmp(swimmingModel,"")) + Commands->Set_Model(obj,originalModel); + if (abs(swimmingHeightScale-999.99f) > 0.1f) + obj->As_SoldierGameObj()->Set_Skeleton_Height(originalHeightScale); + if (abs(swimmingWidthScale-999.99f) > 0.1f) + obj->As_SoldierGameObj()->Set_Skeleton_Width(originalWidthScale); + } + } + if (message == 347341) + { + lastWaterZoneId = Commands->Get_ID(sender); + if (!waterZoneCount) + { + if (enterWaterMessageStringId) + { + time_t currentTime = clock(); + if (difftime(currentTime,lastDisplayTime) > 10000.0f) + { + Set_HUD_Help_Text_Player(obj,enterWaterMessageStringId,waterEnterMessageColorRGB); + lastDisplayTime = currentTime; + } + } + if (abs(swimmingHeightScale-999.99f) > 0.1f) + { + originalHeightScale = obj->As_SoldierGameObj()->Get_Skeleton_Heigth(); + obj->As_SoldierGameObj()->Set_Skeleton_Height(swimmingHeightScale); + } + if (abs(swimmingWidthScale-999.99f) > 0.1f) + { + originalWidthScale = obj->As_SoldierGameObj()->Get_Skeleton_Width(); + obj->As_SoldierGameObj()->Set_Skeleton_Width(swimmingWidthScale); + } + defaultSpeed = obj->As_SoldierGameObj()->Get_Max_Speed(); + waterSpeedMultiplier = (param/100.0f); + JMG_Utility_Swimming_Infantry::isInWater[playerId] = true; + sprintf(enterWeapon,"%s",Get_Current_Weapon(obj) ? Get_Current_Weapon(obj) : ""); + Grant_Weapon(obj,defaultWeaponPreset,true,-1,1); + obj->As_SoldierGameObj()->Set_Can_Play_Damage_Animations(false); + obj->As_SoldierGameObj()->Set_Movement_Loiters_Allowed(false); + obj->As_SoldierGameObj()->Set_Human_Anim_Override(false); + currentWeaponId = 1; + SwitchWeapon(obj); + Commands->Set_Loiters_Allowed(obj,false); + if (_stricmp(swimmingSkin,"")) + { + sprintf(originalSkin,"%s",Get_Skin(obj)); + Set_Skin(obj,swimmingSkin); + } + if (_stricmp(swimmingArmor,"")) + { + sprintf(originalArmor,"%s",Get_Shield_Type(obj)); + Commands->Set_Shield_Type(obj,swimmingArmor); + } + if (_stricmp(swimmingModel,"")) + { + sprintf(originalModel,"%s",Get_Model(obj)); + Commands->Set_Model(obj,swimmingModel); + } + } + waterZoneCount++; + } +} +void JMG_Utility_Swimming_Infantry_Advanced::Killed(GameObject *obj,GameObject *killer) +{ + DestroySoundEmitter(&heartBeatSoundId); + DestroySoundEmitter(&pantSoundId); +} +void JMG_Utility_Swimming_Infantry_Advanced::Destroyed(GameObject *obj) +{ + JMG_Utility_Set_Screen_Color_Fade_Controller::Update_Player(obj,0.0f); + Set_Fog_Range_Player(obj,JMG_Utility_Swimming_Zone::fogMinDistance,JMG_Utility_Swimming_Zone::fogMaxDistance,0.0f); + DestroySoundEmitter(&heartBeatSoundId); + DestroySoundEmitter(&pantSoundId); +} +void JMG_Utility_Swimming_Infantry_Advanced::Detach(GameObject *obj) +{ + if (Exe == 4) + return; + Destroyed(obj); +} +void JMG_Utility_Swimming_Infantry_Advanced::CreateSoundEmitter(GameObject *obj,const char *model,int *soundId) +{ + GameObject *soundEmitter = Commands->Find_Object(*soundId); + if (!soundEmitter) + { + soundEmitter = Commands->Create_Object("Daves Arrow",Commands->Get_Position(obj)); + *soundId = Commands->Get_ID(soundEmitter); + Commands->Attach_To_Object_Bone(soundEmitter,obj,"c head"); + } + Commands->Set_Model(soundEmitter,model); +} +void JMG_Utility_Swimming_Infantry_Advanced::HideSoundEmitter(int *soundId) +{ + GameObject *soundEmitter = Commands->Find_Object(*soundId); + if (soundEmitter) + Commands->Set_Model(soundEmitter,"null"); +} +void JMG_Utility_Swimming_Infantry_Advanced::DestroySoundEmitter(int *soundId) +{ + GameObject *soundEmitter = Commands->Find_Object(*soundId); + if (soundEmitter) + Commands->Destroy_Object(soundEmitter); + *soundId = 0; +} +void JMG_Utility_Swimming_Infantry_Advanced::SwitchWeapon(GameObject *obj) +{ + const WeaponDefinitionClass *weaponDef = Get_Current_Weapon_Definition(obj); + if ((weaponDef && currentWeaponId != weaponDef->Get_ID()) || (!weaponDef && currentWeaponId != 1)) + { + int currentPosition = GetWeaponPosition(obj,currentWeaponId); + GetWeaponId(weaponDef); + if (forceDefinedWeapons) + { + int newPosition = GetWeaponPosition(obj,currentWeaponId); + bool forward = newPosition > currentPosition; + int diff = abs(newPosition-currentPosition); + if ((diff <= 1 && forward) || (diff > 1 && weaponSwitchForward)) + currentWeapon = JMG_Utility_Swimming_Infantry_Advanced_Controller::getNext(obj,weaponGroupId,currentWeapon); + else + currentWeapon = JMG_Utility_Swimming_Infantry_Advanced_Controller::getPrev(obj,weaponGroupId,currentWeapon); + weaponSwitchForward = forward; + if (currentWeapon) + { + Commands->Select_Weapon(obj,currentWeapon->weaponName); + GetWeaponId(Get_Current_Weapon_Definition(obj)); + } + } + else + currentWeapon = JMG_Utility_Swimming_Infantry_Advanced_Controller::getWeapon(weaponGroupId,currentWeaponId); + if (currentWeapon) + { + obj->As_SoldierGameObj()->Set_Override_Weapon_Hold_Style(currentWeapon->holdStyle); + obj->As_SoldierGameObj()->Set_Max_Speed(defaultSpeed*currentWeapon->speed*waterSpeedMultiplier); + } + else + { + obj->As_SoldierGameObj()->Set_Override_Weapon_Hold_Style(defaultHoldStyle); + obj->As_SoldierGameObj()->Set_Max_Speed(defaultSpeed*defaultSwimSpeedMultiplier*waterSpeedMultiplier); + } + } +} +void JMG_Utility_Swimming_Infantry_Advanced::GetWeaponId(const WeaponDefinitionClass *weaponDef) +{ + if (weaponDef) + currentWeaponId = weaponDef->Get_ID(); + else + currentWeaponId = 1; +} +int JMG_Utility_Swimming_Infantry_Advanced::GetWeaponPosition(GameObject *obj,int weaponId) +{ + if (ArmedGameObj *armedGameObj = obj->As_PhysicalGameObj()->As_ArmedGameObj()) + { + WeaponBagClass *weaponBagClass = armedGameObj->Get_Weapon_Bag(); + int x = weaponBagClass->Get_Count(); + for (int i = 0;i < x;i++) + if (weaponBagClass->Peek_Weapon(i)) + if (weaponBagClass->Peek_Weapon(i)->Get_ID() == weaponId) + return i; + } + return -1; +} +JMG_Utility_Swimming_Infantry_Advanced_Controller::WeaponNode *JMG_Utility_Swimming_Infantry_Advanced_Controller::weaponNodeGroups[128] = {NULL}; +JMG_Utility_Swimming_Infantry_Advanced_Controller::WeaponNode *JMG_Utility_Swimming_Infantry_Advanced_Controller::weaponNodeGroupsEnd[128] = {NULL}; +bool JMG_Utility_Swimming_Infantry_Advanced_Controller::exists = false; +void JMG_Utility_Swimming_Infantry_Advanced_Controller::Destroyed(GameObject *obj) +{ + exists = false; + Empty_List(); +} +void JMG_Utility_Swimming_Infantry_Advanced_Add_All_Of_Style::Created(GameObject *obj) +{ + if (!JMG_Utility_Swimming_Infantry_Advanced_Controller::exists) + { + Console_Input("msg JMG_Utility_Swimming_Infantry_Advanced_Add_All_Of_Style ERROR: JMG_Utility_Swimming_Infantry_Advanced_Controller is required to be placed on the map!"); + Destroy_Script(); + return; + } + float delay = Get_Float_Parameter("Delay"); + if (delay) + Commands->Start_Timer(obj,this,delay,1); + else + Timer_Expired(obj,1); +} +void JMG_Utility_Swimming_Infantry_Advanced_Add_All_Of_Style::Timer_Expired(GameObject *obj,int number) +{ + if (number == 1) + { + int weaponGroupId = Get_Int_Parameter("WeaponGroupID"); + if (weaponGroupId < 0 || weaponGroupId > 127) + { + Console_Input("msg JMG_Utility_Swimming_Infantry_Advanced_Add_All_Of_Style ERROR: WeaponGroupID must be 0-127!"); + Destroy_Script(); + return; + } + int holdStyle = Get_Int_Parameter("HoldStyle"); + int animHoldStyle = Get_Int_Parameter("AnimHoldStyle"); + float movementSpeed = Get_Float_Parameter("MovementSpeed"); + for (WeaponDefinitionClass *weaponDef = (WeaponDefinitionClass *)DefinitionMgrClass::Get_First(0xB001);weaponDef != NULL;weaponDef = (WeaponDefinitionClass *)DefinitionMgrClass::Get_Next(weaponDef,0xB001)) + if (weaponDef->Style == holdStyle) + JMG_Utility_Swimming_Infantry_Advanced_Controller::addNode(weaponGroupId,weaponDef->Get_Name(),weaponDef->Get_ID(),weaponDef->KeyNumber,animHoldStyle,movementSpeed); + } +} +void JMG_Utility_Swimming_Infantry_Advanced_Add_Weapon::Created(GameObject *obj) +{ + if (!JMG_Utility_Swimming_Infantry_Advanced_Controller::exists) + { + Console_Input("msg JMG_Utility_Swimming_Infantry_Advanced_Add_Weapon ERROR: JMG_Utility_Swimming_Infantry_Advanced_Controller is required to be placed on the map!"); + Destroy_Script(); + return; + } + float delay = Get_Float_Parameter("Delay"); + if (delay) + Commands->Start_Timer(obj,this,delay,1); + else + Timer_Expired(obj,1); +} +void JMG_Utility_Swimming_Infantry_Advanced_Add_Weapon::Timer_Expired(GameObject *obj,int number) +{ + if (number == 1) + { + int weaponGroupId = Get_Int_Parameter("WeaponGroupID"); + if (weaponGroupId < 0 || weaponGroupId > 127) + { + Console_Input("msg JMG_Utility_Swimming_Infantry_Advanced_Add_Weapon ERROR: WeaponGroupID must be 0-127!"); + Destroy_Script(); + return; + } + const char *weapName = Get_Parameter("WeaponName"); + int animHoldStyle = Get_Int_Parameter("AnimHoldStyle"); + float movementSpeed = Get_Float_Parameter("MovementSpeed"); + for (WeaponDefinitionClass *weaponDef = (WeaponDefinitionClass *)DefinitionMgrClass::Get_First(0xB001);weaponDef != NULL;weaponDef = (WeaponDefinitionClass *)DefinitionMgrClass::Get_Next(weaponDef,0xB001)) + if (!_stricmp(weaponDef->Get_Name(),weapName)) + { + JMG_Utility_Swimming_Infantry_Advanced_Controller::addNode(weaponGroupId,weaponDef->Get_Name(),weaponDef->Get_ID(),weaponDef->KeyNumber,animHoldStyle,movementSpeed); + return; + } + char errorMsg[220]; + sprintf(errorMsg,"msg JMG_Utility_Swimming_Infantry_Advanced_Add_Weapon ERROR: The weapon definition %s could not be found!",weapName); + Console_Input(errorMsg); + } +} ScriptRegistrant JMG_Utility_Check_If_Script_Is_In_Library_Registrant("JMG_Utility_Check_If_Script_Is_In_Library","ScriptName:string,CppName:string"); ScriptRegistrant JMG_Send_Custom_When_Custom_Sequence_Matched_Registrant("JMG_Send_Custom_When_Custom_Sequence_Matched","Success_Custom=0:int,Correct_Step_Custom=0:int,Partial_Failure_Custom=0:int,Failure_Custom=0:int,Send_To_ID=0:int,Custom_0=0:int,Custom_1=0:int,Custom_2=0:int,Custom_3=0:int,Custom_4=0:int,Custom_5=0:int,Custom_6=0:int,Custom_7=0:int,Custom_8=0:int,Custom_9=0:int,Disable_On_Success=1:int,Disable_On_Failure=0:int,Starts_Enabled=1:int,Enable_Custom=0:int,Correct_Step_Saftey=0:int,Failure_Saftey=1:int,Max_Failures=1:int"); ScriptRegistrant JMG_Utility_Change_Model_On_Timer_Registrant("JMG_Utility_Change_Model_On_Timer","Model=null:string,Time=0:float"); @@ -10495,7 +10914,7 @@ ScriptRegistrant JMG_Utility_Lock_Weapon_Selection_While_Script_Attached_Registrant("JMG_Utility_Lock_Weapon_Selection_While_Script_Attached","WeaponPreset:string"); ScriptRegistrant JMG_Utility_Swimming_zDefault_Map_Fog_Values_Registrant("JMG_Utility_Swimming_zDefault_Map_Fog_Values",""); ScriptRegistrant JMG_Utility_Swim_While_In_Zone_Registrant("JMG_Utility_Swimming_Zone","WaterColor[R|G|B]=0.28 0.43 0.55:vector3,WaterOpacity=0.5:float,WaterMinViewDistance=5.0:float,WaterMaxViewDistance=15.0:float,SwimmingSpeedMultiplier=0.75:float"); -ScriptRegistrant JMG_Utility_Swimming_Infantry_Registrant("JMG_Utility_Swimming_Infantry","WeaponPreset=Weapon_Swimming_Animations:string,DrownTime=10.0:float,StarDrownSequence=3.0:float,GaspForBreath=SFX.SwimmingGaspForBreath:string,PantingSoundEmitterModel=s_panting:string,HeartBeatSoundEmitterModel=s_heartBeat:string,DrownDamageRate=2.5:float,CatchBreathRate=0.33:float,WaterDamageAmount=0.0:float,WaterDamageWarhead=None:string,EnterWaterMessageStringId=0:int,WaterEnterMessageColor[R|G|B]=0.25 0.25 1.0:vector3,WaterDamageDelayTime=0:int,WaterDamageDelayTimeRecover=0:int,SwimmingSkin:string,SwimmingArmor:string,SwimmingModel:string"); +ScriptRegistrant JMG_Utility_Swimming_Infantry_Registrant("JMG_Utility_Swimming_Infantry","WeaponPreset=Weapon_Swimming_Animations:string,DrownTime=10.0:float,StartDrownSequence=3.0:float,GaspForBreath=SFX.SwimmingGaspForBreath:string,PantingSoundEmitterModel=s_panting:string,HeartBeatSoundEmitterModel=s_heartBeat:string,DrownDamageRate=2.5:float,CatchBreathRate=0.33:float,WaterDamageAmount=0.0:float,WaterDamageWarhead=None:string,EnterWaterMessageStringId=0:int,WaterEnterMessageColor[R|G|B]=0.25 0.25 1.0:vector3,WaterDamageDelayTime=0:int,WaterDamageDelayTimeRecover=0:int,SwimmingSkin:string,SwimmingArmor:string,SwimmingModel:string"); ScriptRegistrant JMG_Utility_Zone_Enable_Spawners_In_Range_Registrant("JMG_Utility_Zone_Enable_Spawners_In_Range","StartID:int,EndID:int,PlayerType=2:int,Enable=1:int,TriggerOnce=1:int"); ScriptRegistrant JMG_Utility_Display_Message_On_Vehicle_Enter_Registrant("JMG_Utility_Display_Message_On_Vehicle_Enter","StringId:int,MessageOverride=null:string,Color[R|G|B]=0.0 1.0 0.0:vector3,DriverOnly=1:int,ShowOnce=1:int,PlayerType=2:int"); ScriptRegistrant JMG_Utility_Zone_Apply_Damage_On_Enter_Registrant("JMG_Utility_Zone_Apply_Damage_On_Enter","ID:int,DamageAmount:float,Warhead=None:string,DamageOccupants=1:int,PlayerType=2:int,OnlyOnce=0:int"); @@ -10716,3 +11135,9 @@ ScriptRegistrant JMG_Utility_Custom_Grant_Scaled_Score_Registrant("JMG_Utility_Custom_Grant_Scaled_Score","GrantCustom:int,Score:float,ScoreMultiplier:float,EntireTeam=0:int,MaxPlayerCount=-1:int,Repeat=1:int,GrantToSender=0:int,UpdateScaleCustom=0:int,StopUpdateCustom=0:int"); ScriptRegistrant JMG_Utility_Custom_Set_Infantry_Height_Registrant("JMG_Utility_Custom_Set_Infantry_Height","Custom:int,Height=-9999.0:float"); ScriptRegistrant JMG_Utility_Custom_Set_Infantry_Width_Registrant("JMG_Utility_Custom_Set_Infantry_Width","Custom:int,Width=-9999.0:float"); +ScriptRegistrant JMG_Utility_Custom_Set_Weapon_Hold_Sytle_Registrant("JMG_Utility_Custom_Set_Weapon_Hold_Sytle","Custom:int,Style=-1:int"); +ScriptRegistrant JMG_Utility_Custom_Set_Human_Anim_Override_Registrant("JMG_Utility_Custom_Set_Human_Anim_Override","Custom:int,Enable:int"); +ScriptRegistrant JMG_Utility_Swimming_Infantry_Advanced_Registrant("JMG_Utility_Swimming_Infantry_Advanced","WeaponsGroupID=0:int,WeaponPreset=Weapon_Swimming_Animations:string,ForceDefinedWeapons=0:int,DefaultHoldStyle=4:int,DefaultSwimSpeed=1.0:float,DrownTime=10.0:float,StartDrownSequence=3.0:float,GaspForBreath=SFX.SwimmingGaspForBreath:string,PantingSoundEmitterModel=s_panting:string,HeartBeatSoundEmitterModel=s_heartBeat:string,DrownDamageRate=2.5:float,CatchBreathRate=0.33:float,WaterDamageAmount=0.0:float,WaterDamageDelayTime=0:int,WaterDamageDelayTimeRecover=0:int,WaterDamageWarhead=None:string,EnterWaterMessageStringId=0:int,WaterEnterMessageColor[R|G|B]=0.25 0.25 1.0:vector3,SwimmingSkin:string,SwimmingArmor:string,SwimmingModel:string,SwimmingHeightScale=999.99:float,SwimmingWidthScale=999.99:float"); +ScriptRegistrant JMG_Utility_Swimming_Infantry_Advanced_Controller_Registrant("JMG_Utility_Swimming_Infantry_Advanced_Controller",""); +ScriptRegistrant JMG_Utility_Swimming_Infantry_Advanced_Add_All_Of_Style_Registrant("JMG_Utility_Swimming_Infantry_Advanced_Add_All_Of_Style","WeaponGroupID:int,HoldStyle:int,AnimHoldStyle:int,MovementSpeed=1.0:float,Delay=0.0:float"); +ScriptRegistrant JMG_Utility_Swimming_Infantry_Advanced_Add_Weapon_Registrant("JMG_Utility_Swimming_Infantry_Advanced_Add_Weapon","WeaponGroupID:int,WeaponName:string,AnimHoldStyle:int,MovementSpeed=1.0:float,Delay=0.0:float"); diff -urN sourceold/scripts/jmgUtility.h source/scripts/jmgUtility.h --- sourceold/scripts/jmgUtility.h 2018-12-13 16:17:42.218400000 +1000 +++ source/scripts/jmgUtility.h 2019-02-15 09:37:36.770000000 +1000 @@ -6859,4 +6859,299 @@ float width; void Created(GameObject *obj); void Custom(GameObject *obj,int message,int param,GameObject *sender); +}; + +/*! +* \brief Sets the hold style for all weapons, if -1 hold style will not be locked +* \Custom - custom to update the height on +* \Style - -2 = use param, -1 = no override, 0 = A, 1 = A, 2 = C, 3 = D, 4 = E, 5 = F, 6 = A, 7 = A, 8 = B, 9 = A, 10 = J, 11 = K, 12 = L, 13 = M +* \author jgray +* \ingroup JmgUtility +*/ +class JMG_Utility_Custom_Set_Weapon_Hold_Sytle : public ScriptImpClass { + int custom; + int style; + void Created(GameObject *obj); + void Custom(GameObject *obj,int message,int param,GameObject *sender); +}; + +/*! +* \brief Enables or disables the human anim override of a soldier +* \Custom - custom to update the height on +* \Enable - 1 true (default) 0 false +* \author jgray +* \ingroup JmgUtility +*/ +class JMG_Utility_Custom_Set_Human_Anim_Override : public ScriptImpClass { + int custom; + bool enable; + void Created(GameObject *obj); + void Custom(GameObject *obj,int message,int param,GameObject *sender); +}; + +/*! +* \brief Script must be placed on the map in order to control the advanced swimming scripts +* \author jgray +* \ingroup JmgUtility +*/ +class JMG_Utility_Swimming_Infantry_Advanced_Controller : public ScriptImpClass { +public: + struct WeaponNode + { + char weaponName[128]; + unsigned int weaponId; + float sortOrder; + int holdStyle; + float speed; + WeaponNode *next; + WeaponNode *prev; + WeaponNode(const char *weaponName,unsigned int weaponId,float sortOrder,int holdStyle,float speed,WeaponNode *prev,WeaponNode *next) + { + sprintf(this->weaponName,"%s",weaponName); + this->weaponId = weaponId; + this->sortOrder = sortOrder; + this->holdStyle = holdStyle; + this->speed = speed; + this->prev = prev; + this->next = next; + } + }; + static WeaponNode *weaponNodeGroups[128]; + static WeaponNode *weaponNodeGroupsEnd[128]; + static WeaponNode *addNode(int groupId,const char *weaponName,unsigned int weaponId,float sortOrder,int holdStyle,float speed) + { + if (!weaponNodeGroups[groupId]) + return weaponNodeGroups[groupId] = weaponNodeGroupsEnd[groupId] = new WeaponNode(weaponName,weaponId,sortOrder,holdStyle,speed,NULL,NULL); + if (sortOrder < weaponNodeGroups[groupId]->sortOrder) + return weaponNodeGroups[groupId] = weaponNodeGroups[groupId]->prev = new WeaponNode(weaponName,weaponId,sortOrder,holdStyle,speed,NULL,weaponNodeGroups[groupId]); + WeaponNode *current = weaponNodeGroups[groupId],*prev = NULL; + while (current) + { + if (current->weaponId == weaponId) + { + current->holdStyle = holdStyle; + current->sortOrder = sortOrder; + current->speed = speed; + return current; + } + if (prev && prev->sortOrder <= sortOrder && current->sortOrder > sortOrder) + return prev->next = current->prev = new WeaponNode(weaponName,weaponId,sortOrder,holdStyle,speed,prev,current); + if (!current->next) + return current->next = weaponNodeGroupsEnd[groupId] = new WeaponNode(weaponName,weaponId,sortOrder,holdStyle,speed,current,NULL); + prev = current; + current = current->next; + } + return NULL; + }; + static WeaponNode *getNode(int groupId,const char *weaponName) + { + WeaponNode *current = weaponNodeGroups[groupId]; + while (current) + { + if (!_stricmp(weaponName,current->weaponName)) + return current; + current = current->next; + } + return NULL; + }; + static WeaponNode *getWeapon(int groupId,unsigned int weaponId) + { + WeaponNode *current = weaponNodeGroups[groupId]; + while (current) + { + if (weaponId == current->weaponId) + return current; + current = current->next; + } + return NULL; + }; + static WeaponNode *getNext(GameObject *obj,int groupId,WeaponNode *current) + { + if (current) + current = current->next; + if (!current) + current = weaponNodeGroups[groupId]; + for (int x = 0;x < 2;x++) + { + while (current) + { + if (Has_Weapon(obj,current->weaponName)) + return current; + current = current->next; + } + current = weaponNodeGroups[groupId]; + } + return NULL; + }; + static WeaponNode *getPrev(GameObject *obj,int groupId,WeaponNode *current) + { + if (current) + current = current->prev; + if (!current) + current = weaponNodeGroupsEnd[groupId]; + for (int x = 0;x < 2;x++) + { + while (current) + { + if (Has_Weapon(obj,current->weaponName)) + return current; + current = current->prev; + } + current = weaponNodeGroupsEnd[groupId]; + } + return NULL; + }; + static void Empty_List() + { + for (int x = 0;x < 128;x++) + { + WeaponNode *temp = weaponNodeGroups[x],*die; + weaponNodeGroups[x] = NULL; + weaponNodeGroupsEnd[x] = NULL; + while (temp) + { + die = temp; + temp = temp->next; + delete die; + } + } + } +private: + void Destroyed(GameObject *obj); +public: + static bool exists; + JMG_Utility_Swimming_Infantry_Advanced_Controller() + { + exists = true; + for (int x = 0;x < 128;x++) + weaponNodeGroups[x] = NULL; + } +}; + +/*! +* \brief This script allows a soldier to swim when in a swimming zone. +* \ If using my swimming animations make sure there is a plane for infantry +* \ to stand on 1.466 meters below the water surface. The underwater[playerId] can be accessed from anywhere, allowing you to disable +* \ screen fading when underwater from other scripts. +* \WeaponsGroupID - ID to use to look up weapons specified by the weapons group controller +* \WeaponPreset - Weapon to lock the player to while swimming, make sure its type launcher to make use of my animations +* \ForceDefinedWeapons - If 1 the player won't be able to select weapons that haven't been defined for the weapons group. +* \DefaultHoldStyle - Default animation set used for weapons that haven't been defined. 0 = A, 1 = A, 2 = C, 3 = D, 4 = E, 5 = F, 6 = A, 7 = A, 8 = B, 9 = A, 10 = J, 11 = K, 12 = L, 13 = M +* \DefaultSwimSpeed - Default swim speed for weapons that haven't overridden the swim speed. +* \DrownTime - Time it takes before you start taking damage when crouched under water for long periods of time +* \StarDrownSequence - How long before you start taking damage to start fading the screen red and the heart beat sound +* \GaspForBreath - This sound is played when you surface from under water after long periods of time +* \PantingSoundEmitterModel - This 3d object is attached to the player and should be a looped sound effect, it exists while getting close to drowning +* \HeartBeatSoundEmitterModel - This 3d object is attached to the player and should be a looped sound effect, it exists while catching your breath +* \DrownDamageRate - Damage applied 10 times a second while drowning +* \CatchBreathRate - Rate at which a character catches its breath when out of the water, 0.1 would recover 1 second of air every second +* \WaterDamageAmount - Amount of damage to apply to the character while swimming, is applied 10 tiems a second, default is 0 +* \WaterDamageWarhead - Warhead to use when in the water, default is None +* \WaterDamageDelayTime - Amount of time in tenths of a second before the infantry will start taking damage +* \WaterDamageDelayTimeRecover - Amount of time that is recovered while out of the water (added 10 times a second) +* \EnterWaterMessageStringId - ID of the string in strings.tbl to display when a player enters the water, the message only displays once every 10 seconds +* \WaterEnterMessageColor[R|G|B] - Color of the HUD message when entering the water, 0.0-1.0 RGB +* \SwimmingSkin - Skin to use while swimming, blank means ignore +* \SwimmingArmor - Armor to use while swimming, blank means ignore +* \SwimmingModel - Model to use while swimming, blank means ignore +* \SwimmingHeightScale - Scale to adjust the infantry with when they enter the water (999.99 disables) +* \SwimmingWidthScale - Scale to adjust the infantry with when they enter the water (999.99 disables) +* \author jgray +* \ingroup JmgUtility +*/ +class JMG_Utility_Swimming_Infantry_Advanced : public ScriptImpClass { + int heartBeatSoundId; + int pantSoundId; + char enterWeapon[256]; + int playerId; + bool startedFadeRed; + float drownTime; + bool underwater; + int waterZoneCount; + int lastWaterZoneId; + time_t lastDisplayTime; + float defaultSpeed; + int waterDamageDelayTime; + int waterDamageDelayTimeRecover; + int remainingWaterDamageDelay; + char originalSkin[128]; + char originalArmor[128]; + char originalModel[128]; + int weaponGroupId; + unsigned int currentWeaponId; + int defaultHoldStyle; + float defaultSwimSpeedMultiplier; + float waterSpeedMultiplier; + char defaultWeaponPreset[128]; + float defaultDrownTime; + float startDrownSequence; + float waterDamageAmount; + char waterDamageWarhead[128]; + float drownDamageRate; + char swimmingSkin[128]; + char swimmingArmor[128]; + char swimmingModel[128]; + float swimmingHeightScale; + float swimmingWidthScale; + float originalHeightScale; + float originalWidthScale; + int enterWaterMessageStringId; + Vector3 waterEnterMessageColorRGB; + char heartBeatSoundEmitterModel[16]; + char pantingSoundEmitterModel[16]; + char gaspForBreath[128]; + float catchBreathRate; + bool forceDefinedWeapons; + int weaponSwitchForward; + JMG_Utility_Swimming_Infantry_Advanced_Controller::WeaponNode *currentWeapon; + void Created(GameObject *obj); + void Timer_Expired(GameObject *obj,int number); + void Custom(GameObject *obj,int message,int param,GameObject *sender); + void Killed(GameObject *obj,GameObject *killer); + void Destroyed(GameObject *obj); + void Detach(GameObject *obj); + void CreateSoundEmitter(GameObject *obj,const char *model,int *soundId); + void DestroySoundEmitter(int *soundId); + void HideSoundEmitter(int *soundId); + void SwitchWeapon(GameObject *obj); + void UpdateWeaponSwimming(GameObject *obj,const WeaponDefinitionClass *weaponDef); + void GetWeaponId(const WeaponDefinitionClass *weaponDef); + int GetWeaponPosition(GameObject *obj,int weaponId); +public: + JMG_Utility_Swimming_Infantry_Advanced() + { + weaponGroupId = 0; + currentWeaponId = 0; + currentWeapon = NULL; + } +}; + +/*! +* \brief Adds all defined weapons of a specific hold style to the JMG_Utility_Swimming_Infantry_Advanced_Controller +* \WeaponGroupID - Weapon Group to add them to (max of 127) +* \HoldStyle - Hold style to add the weapons from (C4 = 0, UNUSED = 1, SHOLDER = 2, HIP = 3, LAUNCHER = 4, HANDGUN = 5, BEACON = 6, EMPTY_HANDS = 7, CHEST = 8, HANDS DOWN = 9) +* \AnimHoldStyle - Animation hold style to use while swimming (0 = A, 1 = A, 2 = C, 3 = D, 4 = E, 5 = F, 6 = A, 7 = A, 8 = B, 9 = A, 10 = J, 11 = K, 12 = L, 13 = M) +* \MovementSpeed - Movement speed multiplier to use while swimming +* \Delay - Delay before running the script (if a weapon has already been defined and another script runs trying to add that same weapon it will update the definition of the previously defined) +* \author jgray +* \ingroup JmgUtility +*/ +class JMG_Utility_Swimming_Infantry_Advanced_Add_All_Of_Style : public ScriptImpClass { + void Created(GameObject *obj); + void Timer_Expired(GameObject *obj,int number); +}; + +/*! +* \brief Adds a weapon to JMG_Utility_Swimming_Infantry_Advanced_Controller +* \WeaponGroupID - Weapon Group to add them to (max of 127) +* \WeaponName - Name of the weapon definition to add +* \AnimHoldStyle - Animation hold style to use while swimming (0 = A, 1 = A, 2 = C, 3 = D, 4 = E, 5 = F, 6 = A, 7 = A, 8 = B, 9 = A, 10 = J, 11 = K, 12 = L, 13 = M) +* \MovementSpeed - Movement speed multiplier to use while swimming +* \Delay - Delay before running the script (if a weapon has already been defined and another script runs trying to add that same weapon it will update the definition of the previously defined) +* \author jgray +* \ingroup JmgUtility +*/ +class JMG_Utility_Swimming_Infantry_Advanced_Add_Weapon : public ScriptImpClass { + void Created(GameObject *obj); + void Timer_Expired(GameObject *obj,int number); }; \ No newline at end of file diff -urN sourceold/scripts/scripts.vcxproj source/scripts/scripts.vcxproj --- sourceold/scripts/scripts.vcxproj 2018-11-17 10:23:57.260600000 +1000 +++ source/scripts/scripts.vcxproj 2019-02-15 09:37:36.771000000 +1000 @@ -388,6 +388,7 @@ + diff -urN sourceold/scripts/scripts.vcxproj.filters source/scripts/scripts.vcxproj.filters --- sourceold/scripts/scripts.vcxproj.filters 2018-11-17 10:23:57.261600000 +1000 +++ source/scripts/scripts.vcxproj.filters 2019-02-15 09:37:36.773000000 +1000 @@ -374,6 +374,9 @@ 01. Sources + + 01. Sources +