• 注册
  • 攻略教程 攻略教程 关注:660 内容:206

    【A18】空投附近根据当前游戏阶段生成僵尸

  • 查看作者
  • 打赏作者
  • 当前位置: 七日杀中文网 > 攻略教程 > 正文
  • 攻略教程
  • Lv.2

    话不多说丢源码,有兴趣的作者可以自行修改,比如改成指定刷新的entityGroup,或者其他Entity刷新时。

    using Harmony;

    using System.Collections.Generic;

    using UnityEngine;

    using UniLinq;

    using DMT;

    using System.Reflection;

    public class AirdropSpawnZeds

    {

        // 此函数不用管,加载入内核的

        public class AirdropSpawnZeds_Init : IHarmony

        {

            public void Start()

            {

                Debug.Log(” Loading Patch : ” + GetType().ToString());

                var harmony = HarmonyInstance.Create(GetType().ToString());

                harmony.PatchAll(Assembly.GetExecutingAssembly());

            }

        }

        // 当空投的Entity刷新时执行

        [HarmonyPatch(typeof(EntitySupplyCrate))]

        [HarmonyPatch(“OnUpdateEntity”)]

        class PatchEntitySupplyCrateOnUpdateEntity

        {

            static bool Prefix(EntitySupplyCrate __instance)

            {

                // 判断包为空则销毁,这个是系统源代码的,这里只是复制黏贴了一下

                if (__instance.lootContainer != null && __instance.lootContainer.bTouched && __instance.lootContainer.IsEmpty() && !__instance.bDead)

                {

                    __instance.bDead = true;

                    __instance.Health = 0;

                    return true;

                }

                // 判断包的名字是否叫空投,是否在地上,通过里面的食物计数判断当前最大僵尸量

                if (__instance.EntityName == “sc_General” && __instance.onGround && __instance.classMaxFood < GetMaxZombies() && (__instance.lootContainer == null || (__instance.lootContainer != null && !__instance.lootContainer.bTouched)))

                {

                    var spawnRadius = 30f;

                    

                    // 是否正在血月,如果是的话就算了,血月还在野外捡空投不容易

                    if (__instance.IsBloodMoon)

                    {

                        var closestplayerStill = __instance.world.GetClosestPlayer(__instance, spawnRadius, false);

                        if (closestplayerStill == null)

                        {

                            __instance.IsBloodMoon = false;

                        }

                        else

                            return true;

                    }

                    

                    // 离空投最近的玩家

                    var closestplayer = __instance.world.GetClosestPlayer(__instance, 5f, false);

                    if (closestplayer == null)

                        return true;

                    

                    // 判断附近有没有位置给僵尸刷新,空投掉海里了就算了

                    BiomeSpawnEntityGroupList biomeSpawnEntityGroupList = BiomeSpawningClass.list[“airdrop”];

                    if (biomeSpawnEntityGroupList == null)

                        return true;

                    __instance.IsBloodMoon = true;

                    // 计算并取附近所有玩家中最大的游戏阶段  

                    int partyLevel = GetGamestageFromBounds(__instance.position.x, __instance.position.y, __instance.position.z, “Airdrop”);

                    // 根据附近的环境查找生成的EntityGroup,比如废墟晚上,绿地白天的group

                    int matchingGameStage = 0;

                    List<BiomeSpawnEntityGroupData> list = new List<BiomeSpawnEntityGroupData>();

                    EDaytime edaytime = (!__instance.world.IsDaytime()) ? EDaytime.Night : EDaytime.Day;

                    foreach (var x in biomeSpawnEntityGroupList.list.AsEnumerable().Reverse())

                    {

                        if (matchingGameStage == 0 && x.gameStage <= partyLevel)

                            matchingGameStage = x.gameStage;

                        if (matchingGameStage > 0)

                        {

                            if (x.gameStage != matchingGameStage || x.entityGroupRefName.Contains(“Animals”) || x.entityGroupRefName.Contains(“Bandit”)) break;

                            if (x.daytime == EDaytime.Any || x.daytime == edaytime)

                                list.Add(x);

                        }

                    }

                    // 反转列表方便取表头

                    list.Reverse();

                   

                    // 随机半径生成随机Id的Entity

                    System.Random rnd = new System.Random();

                    var spawnGroup = list.First();

                    var group = EntityGroups.list[spawnGroup.entityGroupRefName];

                    var rndEntityId = new System.Random();

                    for (int i = 0; i < (spawnGroup.maxCount); i++)

                    {

                        // 在空投的坐标系下随机15m的半径生成僵尸

                        var randomPosition = __instance.GetPosition();

                        randomPosition.x = randomPosition.x + rnd.Next(-(int)spawnRadius / 2, (int)spawnRadius / 2);

                        randomPosition.z = randomPosition.z + rnd.Next(-(int)spawnRadius / 2, (int)spawnRadius / 2);

                        randomPosition.y = 0;

                       

                        // 随机坐标中y是当前的高度,生成的僵尸不能在地下埋着,所以计算当前xz坐标下的物块的高度来获取y

                        var blockPos = World.worldToBlockPos(randomPosition);

                        var chunk = (Chunk)__instance.world.GetChunkFromWorldPos(blockPos);

                        blockPos.y = (chunk.GetHeight(World.toBlockXZ((int)randomPosition.x), World.toBlockXZ((int)randomPosition.z)) + 1);

                        randomPosition.y = (float)blockPos.y;

                        Entity entityEnemy = EntityFactory.CreateEntity(group[rndEntityId.Next(group.Count – 1)].entityClassId, randomPosition);

                        GameManager.Instance.World.SpawnEntityInWorld(entityEnemy);

                        entityEnemy.SetSpawnerSource(EnumSpawnerSource.Dynamic);

                        // 通过最大食物来判断是否生成的僵尸太多了

                        __instance.classMaxFood++;

                        // 多了的话就别生成了,小伙子舔个空投不容易

                        if (__instance.classMaxFood >= GetMaxZombies())

                            return true;

                    }

                }

                return true;

            }

            // 计算并取附近所有玩家中最大的游戏阶段

            public static int GetGamestageFromBounds(float x, float y, float z, string source, bool log = false)

            {

                // 物块的点坐标

                var chunkPosition = new Vector3(x, y, z);

                // 在物块坐标范围200的区域内创建包围盒

                var bounds = new Bounds(new Vector3(chunkPosition.x, chunkPosition.y, chunkPosition.z), new Vector3(200f, 200f, 200f));

                // 判断包围盒内有多少个玩家,取出每个玩家的游戏阶段

                List<Entity> playersInBounds = GameManager.Instance.World.GetEntitiesInBounds(typeof(EntityPlayer), bounds, new List<Entity>());

                List<int> partyLevelList = new List<int>();

                foreach (var entityBound in playersInBounds)

                {

                    var player = entityBound as EntityPlayer;

                    partyLevelList.Add(player.gameStage);

                }

                // 取所有玩家中最大的游戏阶段

                return Mathf.Max(GameStageDefinition.CalcPartyLevel(partyLevelList), 1);

            }

            // 获取最大僵尸数,如果最大僵尸数大于100,则取100

            private static int GetMaxZombies()

            {

                return GamePrefs.GetInt(EnumGamePrefs.MaxSpawnedZombies) > 100 ? 100 : GamePrefs.GetInt(EnumGamePrefs.MaxSpawnedZombies);

            }

        }

    }

    "点赞是美意,打赏是鼓励"

    因恶意刷帖用户过多,本版块已取消回帖金币奖励,请签到获取!>>>金币获取指南<<<

    请登录之后再进行评论

    登录
    • 大版主
    • 小版主
  • yichen
  • 柒月白风清
    柒月白风清
    一只小萌新,万年摸鱼党!已经脱坑了。。。
  • Cure_805
    Cure_805
    晚上在睡觉,白天在工作,不一定能及时回复,有事可以留言!
  • 至善丶丶
    至善丶丶
    群:1050040662 定制/开服/地图制作/价格公道
  • 暂没有数据

    赞助广告位

  • 点击展示图片即可一键加入QQ群
    赞助广告:100R/月 目前广告位已满!

    分享网站

  • 繁体中文
  • 任务
  • 动态
  • 到底部
  • 帖子间隔 侧栏位置: