From be61e8163720044938205f23e1c035c1347f24be Mon Sep 17 00:00:00 2001 From: Dcrclub Date: Wed, 1 Jan 2025 02:45:22 +0800 Subject: [PATCH] =?UTF-8?q?update:=20=E6=B7=BB=E5=8A=A0=E7=8E=A9=E5=AE=B6?= =?UTF-8?q?=E5=A4=8D=E6=B4=BB=E5=A5=97=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mod/RespawnEqument/README.md | 25 +++ .../Scripts/CustomRevivalSuit/config.c | 109 ++++++++++++ Mod/RespawnEqument/init.c | 166 ++++++++++++++++++ 3 files changed, 300 insertions(+) create mode 100644 Mod/RespawnEqument/README.md create mode 100644 Mod/RespawnEqument/Scripts/CustomRevivalSuit/config.c create mode 100644 Mod/RespawnEqument/init.c diff --git a/Mod/RespawnEqument/README.md b/Mod/RespawnEqument/README.md new file mode 100644 index 0000000..b100fe0 --- /dev/null +++ b/Mod/RespawnEqument/README.md @@ -0,0 +1,25 @@ +基于init.c的玩家复活装备模组 + +#### 模组说明: + +本模组算是一个示例代码, 旨在告诉开发者如何正确的使用init.c加载自己的代码. + +在init.c中.通常都是将大堆的代码直接带入到文件中, 导致init.c中的代码臃肿不堪,难以维护,对于此种情况,请参考本代码示例, 正确的处理在init.c中的代码逻辑 + +擅于使用 #include 标签来引入外部的.c文件, 将一些方法封装成一个类,进行调用, 而不是所有的代码都插入到init.c中. 参阅Scripts文件夹中的代码, 已经init.c的第一行. + +#### 代码的功能: + +代码编写了一个服主常用的功能, 给指定ID的玩家创建一套复活时穿戴的装备, 支持枪械配件的组装. + +可行的尝试: + +对于懂代码的服主,可以尝试自行修改代码,实现一些额外的功能. + +- 玩家进入游戏时的状态处理 + +- 玩家退出游戏时的物品处理 + +- 利用invoke进行实时的监控玩家. + +- 监控客户端的RPC通讯 \ No newline at end of file diff --git a/Mod/RespawnEqument/Scripts/CustomRevivalSuit/config.c b/Mod/RespawnEqument/Scripts/CustomRevivalSuit/config.c new file mode 100644 index 0000000..1aa125f --- /dev/null +++ b/Mod/RespawnEqument/Scripts/CustomRevivalSuit/config.c @@ -0,0 +1,109 @@ +/** + * @file config.c + * @author 稻草人 + * @version 1.0 + * @date 2025-00-01 + * @copyright Copyright (c) 2025 + * + * @brief This file contains the configuration for the custom revival suit feature. + */ +static ref CustomRevivalSuitCfg g_CustomRevivalSuitCfg; +static ref CustomRevivalSuitCfg GetCustomRevivalSuitCfg() +{ + if ( !g_CustomRevivalSuitCfg ) + { + g_CustomRevivalSuitCfg = new ref CustomRevivalSuitCfg(); + g_CustomRevivalSuitCfg.loadConfig(); + } + return g_CustomRevivalSuitCfg; +} + +class CustomRevivalSuitCfg +{ + protected static string profileDir = "$profile:DcrServerModCfg\\CustomRevivalSuitCfg"; + protected static string profileName = "\\CustomRevivalSuitCfg.json"; + protected static string profilePath = profileDir + profileName; + + ref array< ref PlayerRevivalEquipmentData > PlayerRevivalEquipmentDataList; + + void loadConfig() + { + if ( !FileExist( profilePath ) ) + makeConfig(); + + JsonFileLoader< ref CustomRevivalSuitCfg >.JsonLoadFile( profilePath, this ); + } + + void makeConfig() + { + PlayerRevivalEquipmentDataList = new ref array< ref PlayerRevivalEquipmentData >(); + ref PlayerRevivalEquipmentData playerData = new ref PlayerRevivalEquipmentData( "76561198422667486" ); + PlayerRevivalEquipmentDataList.Insert( playerData ); + + MakeDirectory( "$profile:DcrServerModCfg/" ); + MakeDirectory( profileDir + "/" ); + + SaveConfig(); + } + + void SaveConfig() + JsonFileLoader< ref CustomRevivalSuitCfg >.JsonSaveFile( profilePath, this ); + + ref PlayerRevivalEquipmentData GetPlayerRevivalEquipmentData( string steamid ) + { + foreach ( ref PlayerRevivalEquipmentData playerData : PlayerRevivalEquipmentDataList ) + if ( playerData.SteamId == steamid ) + return playerData; + + return NULL; + } + + void RemovePlayerRevivalEquipmentData( string steamid ) + { + foreach ( ref PlayerRevivalEquipmentData playerData : PlayerRevivalEquipmentDataList ) + { + if ( playerData.SteamId == steamid ) + { + PlayerRevivalEquipmentDataList.RemoveItem( playerData ); + SaveConfig() + } + } + } +} + +class PlayerRevivalEquipmentData +{ + string SteamId; + + ref TStringArray Equipments; + ref TStringArray ItemList; + ref WeaponCfg WeaponData; + + void PlayerRevivalEquipmentData( string steamid ) + { + SteamId = steamid; + Equipments = { "WoolGloves_White", "BaseballCap_Black", + "Jeans_Blue", "Wellies_Black", "TShirt_Black" + }; + ItemList = { "Apple" }; + WeaponData = new ref WeaponCfg(); + } +} + +class WeaponCfg +{ + string WeaponName; + string Desc; + + ref TStringArray WeaponComponents; + + void WeaponCfg() + { + WeaponName = "FAL"; + Desc = "武器配件中,一级配件(比如枪托,弹夹)放在前排,二级配件(比如电池)其次 以此类推" + WeaponComponents = { + "Fal_FoldingBttstck", + "Mag_FAL_20Rnd" + }; + } +} \ No newline at end of file diff --git a/Mod/RespawnEqument/init.c b/Mod/RespawnEqument/init.c new file mode 100644 index 0000000..3e8e003 --- /dev/null +++ b/Mod/RespawnEqument/init.c @@ -0,0 +1,166 @@ +#include "$mission:Scripts/CustomRevivalSuit/config.c" + +void main() +{ + //INIT ECONOMY-------------------------------------- + Hive ce = CreateHive(); + if ( ce ) + ce.InitOffline(); + + //DATE RESET AFTER ECONOMY INIT------------------------- + int year, month, day, hour, minute; + int reset_month = 9, reset_day = 20; + GetGame().GetWorld().GetDate(year, month, day, hour, minute); + + if ((month == reset_month) && (day < reset_day)) + { + GetGame().GetWorld().SetDate(year, reset_month, reset_day, hour, minute); + } + else + { + if ((month == reset_month + 1) && (day > reset_day)) + { + GetGame().GetWorld().SetDate(year, reset_month, reset_day, hour, minute); + } + else + { + if ((month < reset_month) || (month > reset_month + 1)) + { + GetGame().GetWorld().SetDate(year, reset_month, reset_day, hour, minute); + } + } + } +} + +class CustomMission: MissionServer +{ + override void OnInit() + { + super.OnInit(); + + GetCustomRevivalSuitCfg(); + if ( g_CustomRevivalSuitCfg ) + Print( "[复活套装]: 已加载" ); + } + + override PlayerBase CreateCharacter(PlayerIdentity identity, vector pos, ParamsReadContext ctx, string characterName) + { + Entity playerEnt; + playerEnt = GetGame().CreatePlayer( identity, characterName, pos, 0, "NONE" ); + Class.CastTo( m_player, playerEnt ); + + GetGame().SelectPlayer( identity, m_player ); + + return m_player; + } + + override void StartingEquipSetup( PlayerBase player, bool clothesChosen ) + { + GetCustomRevivalSuitCfg(); + if ( !player || !player.GetIdentity() ) return; + + string steamid = player.GetIdentity().GetPlainId(); + ref PlayerRevivalEquipmentData rev = g_CustomRevivalSuitCfg.GetPlayerRevivalEquipmentData( steamid ); + if ( rev ) + ProcessVIPEquipment( player, rev ); + + DefaultPlayerEquipment( player, clothesChosen ); + } + + void ProcessVIPEquipment( PlayerBase player, ref PlayerRevivalEquipmentData equ_data ) + { + if ( !equ_data ) return; + + player.RemoveAllItems(); + + ItemBase equipment; + foreach ( string equ : equ_data.Equipments ) + player.GetInventory().CreateInInventory( equ ); + + foreach ( string item : equ_data.ItemList ) + player.GetInventory().CreateInInventory( item ); + + if ( !equ_data.WeaponData || equ_data.WeaponData.WeaponName == "" ) return; + Weapon_Base weapon = Weapon_Base.Cast( player.GetInventory().CreateInInventory( equ_data.WeaponData.WeaponName ) ); + if ( !weapon ) return + + foreach ( string attachment : equ_data.WeaponData.WeaponComponents ) + { + if ( String( attachment ).ToType().IsInherited( Magazine ) ) + { + Magazine wpn_mag = weapon.SpawnAttachedMagazine( attachment ); + if ( wpn_mag ) + wpn_mag.SetSynchDirty(); + + continue; + } + + if ( weapon.GetInventory() ) + ItemBase.Cast( weapon.GetInventory().CreateInInventory( attachment ) ); + } + } + + void SetRandomHealth(EntityAI itemEnt) + { + if (itemEnt) + { + float rndHlt = Math.RandomFloat( 0.50, 0.85 ); + itemEnt.SetHealth01( "", "", rndHlt ); + } + } + + void DefaultPlayerEquipment( PlayerBase player, bool clothesChosen ) + { + EntityAI itemClothing; + EntityAI itemEnt; + ItemBase itemBs; + float rand; + + itemClothing = player.FindAttachmentBySlotName( "Body" ); + if ( itemClothing ) + { + SetRandomHealth( itemClothing ); + + itemEnt = itemClothing.GetInventory().CreateInInventory( "BandageDressing" ); + if ( Class.CastTo( itemBs, itemEnt ) ) + itemBs.SetQuantity( 2 ); + + string chemlightArray[] = { "Chemlight_White", "Chemlight_Yellow", "Chemlight_Green", "Chemlight_Red" }; + int rndIndex = Math.RandomInt( 0, 4 ); + itemEnt = itemClothing.GetInventory().CreateInInventory( chemlightArray[rndIndex] ); + SetRandomHealth( itemEnt ); + + ItemBase itemTop; + rand = Math.RandomFloatInclusive( 0.0, 1.0 ); + if ( rand < 0.35 ) + { + itemEnt = player.GetInventory().CreateInInventory( "Rag" ); + itemTop = ItemBase.Cast( itemEnt ); + itemTop.RemoveAllAgentsExcept(eAgents.BRAIN | eAgents.SALMONELLA | eAgents.CHOLERA); + itemTop.SetCleanness(1); + } + else if ( rand > 0.65 ) + { + itemEnt = player.GetInventory().CreateInInventory( "Rag" ); + itemTop = ItemBase.Cast( itemEnt ); + itemTop.RemoveAllAgentsExcept(eAgents.BRAIN | eAgents.SALMONELLA | eAgents.CHOLERA); + itemTop.SetCleanness(1); + } + else + itemEnt = player.GetInventory().CreateInInventory( "Rag" ); + + // SetRandomHealth( itemEnt ); + } + + itemClothing = player.FindAttachmentBySlotName( "Legs" ); + if ( itemClothing ) + SetRandomHealth( itemClothing ); + + itemClothing = player.FindAttachmentBySlotName( "Feet" ); + } +}; + +Mission CreateCustomMission(string path) +{ + return new CustomMission(); +} \ No newline at end of file