Jelajahi Sumber

update: 添加玩家复活套装

Dcrclub 3 bulan lalu
induk
melakukan
be61e81637

+ 25 - 0
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通讯

+ 109 - 0
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"
+        };
+    }
+}

+ 166 - 0
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();
+}