예제 #1
0
    public void OnEat(DinoAiData.Eat.ReceivedRequest request)
    {
        var payload = request.Payload;

        _curFood = attrsWriter.Data.CurrentFood;
        float resTaken = 0;

        if (_curFood > payload.ResNeed)
        {
            resTaken  = payload.ResNeed;
            _curFood -= payload.ResNeed;
        }
        else
        {
            resTaken = _curFood;
            _curFood = 0;
        }

        var update = new EatResponse()
        {
            ResTaken = resTaken
        };

        cmdReceiver.SendEatResponse(request.RequestId, update);
        //Debug.Log("OnHarvest ResourceNeed<"+payload.ResourcesNeed+"> Harvester<"+payload.Harvester.Id+">");

        var update2 = new DinoAttrs.Update
        {
            CurrentFood = _curFood
        };

        attrsWriter.SendUpdate(update2);
    }
예제 #2
0
    void OnAttrsChanged(DinoAttrs.Update update)
    {
        _isDead    = attrsReader.Data.IsDead;
        _curFood   = attrsReader.Data.CurrentFood; // 当前的粮食
        _maxFood   = attrsReader.Data.MaxFood;     // 最大的粮食储量
        _curHealth = health.Data.CurrentHealth;    // 当前生命值
        _maxHealth = health.Data.MaxHealth;        // 最大生命值

        originalScent     = attrsReader.Data.OriginalScent;
        originalAgression = attrsReader.Data.OriginalAgression;
        originalDominance = attrsReader.Data.OriginalDominance;
        origin            = attrsReader.Data.OriginPosition.ToUnityVector();

        // 修改模型颜色
        if (attrsReader.Data.OwnerTokenId != 0)
        {
            if (attrsReader.Data.OwnerTokenId == ClientManager.Instance.TokenId)
            {
                var renderer = GetComponentInChildren <Renderer>();
                if (renderer != null)
                { // 我方恐龙,蓝色
                    renderer.material.color = new Color(17 / 256f, 51 / 256f, 136 / 256f, 1f);
                }
            }
            else
            {
                var renderer = GetComponentInChildren <Renderer>();
                if (renderer != null)
                {
                    renderer.material.color = new Color(231 / 256f, 78 / 256f, 86 / 256f, 1f);
                }
            }
        }
    }
예제 #3
0
    private bool Hatching()
    {
        if (stateMachine.CurrentState == DinoAiFSMState.StateEnum.HATCH)
        {
            return(true);
        }

        // 未成年,不能下蛋
        if (_age < ScriptableAnimalStats.growUpTime)
        {
            return(false);
        }
        _curFood = attrsWriter.Data.CurrentFood;
        if (_curFood / attrsWriter.Data.MaxFood < ScriptableAnimalStats.hatchRate)
        { // 粮食储备不够,不能下蛋
            return(false);
        }

        float deltaTime = Time.time - attrsWriter.Data.LastHatchTime;

        if (deltaTime < ScriptableAnimalStats.hatchDelay)
        { // 距离上次下蛋时间间隔太短,不能下蛋
            return(false);
        }

        var update = new DinoAttrs.Update
        {
            LastHatchTime = Time.time,
        };

        attrsWriter.SendUpdate(update);

        stateMachine.TriggerTransition(DinoAiFSMState.StateEnum.HATCH, new EntityId(), transform.position);
        return(true);
    }
예제 #4
0
    public void GrowUp()
    {
        if (age.Data.Age < age.Data.GrowUpAge)
        {
            return;
        }
        float ratioChild = 1.0f;

        // 恢复小恐龙的粮食,攻击力,生命消耗等属性,变成成人的
        float curFood = attrsWriter.Data.CurrentFood;
        float maxFood = attrsWriter.Data.MaxFood;
        var   update  = new DinoAttrs.Update
        {
            CurrentFood = ScriptableAnimalStats.foodStorage * curFood / maxFood, // 当前的粮食按照比例提升
            MaxFood     = ScriptableAnimalStats.foodStorage,                     // 恢复成人数值
            Power       = ScriptableAnimalStats.power,                           // 恢复成人数值
            LiveCost    = ScriptableAnimalStats.liveCost,                        // 恢复成人数值
        };

        attrsWriter.SendUpdate(update);

        // 恢复小恐龙的生命值,变成成人的
        float curHealth = health.Data.CurrentHealth;
        float maxHealth = health.Data.MaxHealth;
        var   update3   = new Health.Update
        {
            CurrentHealth = ScriptableAnimalStats.toughness * curHealth / maxHealth, // 当前的生命按照比例提升
            CanBeChanged  = true,
            MaxHealth     = ScriptableAnimalStats.toughness
        };

        health.SendUpdate(update3);
    }
예제 #5
0
    public void OnAttack(DinoAiData.Attack.ReceivedRequest request)
    {
        var payload = request.Payload;

        _curHealth  = health.Data.CurrentHealth;
        _curHealth -= payload.Damage;
        if (logChanges)
        {
            Debug.Log(string.Format("{0}: Taking Damage {1} HP {2}!", gameObject.name, payload.Damage, _curHealth));
        }

        // 生命减少
        var update = new Health.Update
        {
            CurrentHealth = _curHealth
        };

        health.SendUpdate(update);
        // 把生命减少的一半变成粮食储存起来,便于死后给食肉恐龙提供食物,否则如果食肉恐龙杀死一只饥饿(Food为零)的食草恐龙以后,什么都没得吃
        _curFood = attrsWriter.Data.CurrentFood;
        float addFood = payload.Damage / 2;

        if (addFood + _curFood > attrsWriter.Data.MaxFood)
        {
            addFood = attrsWriter.Data.MaxFood - _curFood;
        }
        var update2 = new DinoAttrs.Update
        {
            CurrentFood = _curFood + addFood
        };

        attrsWriter.SendUpdate(update2);

        // 如果血不够了,立即死亡。不用等到下一个AI周期了。
        if (_curHealth <= 0)
        {
            if (IsAlive)
            {
                Die();
            }
        }
        else
        {// 挨打的一方也进入战斗状态
            DinoBehaviour attacker = null;
            if (allAnimals.TryGetValue(payload.Attacker.Id, out attacker))
            {
                if (IsAlive && stateMachine.CurrentState != DinoAiFSMState.StateEnum.ATTACK)
                {
                    stateMachine.TriggerTransition(DinoAiFSMState.StateEnum.ATTACK, payload.Attacker, attacker.transform.position);
                }
            }
        }
    }
예제 #6
0
    private void OnCreateEggResponse(WorldCommands.CreateEntity.ReceivedResponse response)
    {
        if (response.EntityId.HasValue)
        {
            var entityId = response.EntityId.Value;
            //Debug.Log("Server - new egg created:"+entityId);
        }
        // 下蛋成功,身上的粮食要减半
        _curFood = attrsWriter.Data.CurrentFood;
        var update = new DinoAttrs.Update
        {
            CurrentFood = _curFood / 2,
        };

        attrsWriter.SendUpdate(update);
    }
예제 #7
0
    public void OnHarvestFood(Harvestable.Harvest.ReceivedResponse response)
    {
        // resTaken:实际吃到的粮食,如果树上粮食已经不足了,则剩余多少都给过来,所以不一定是appetite,也不一定是resNeed
        HarvestResponse?payload  = response.ResponsePayload;
        float           resTaken = 0f;

        if (payload.HasValue)
        {
            resTaken = payload.Value.ResourcesTaken;
        }
        //Debug.Log("Command<HarvestRequest> sent! Harvester<"+response.SendingEntity.Index+"> Tree<"+response.EntityId+"> Resource Taken<"+resTaken+"> StatusCode<"+response.StatusCode+"> Message<"+response.Message+">");
        _curFood = attrsWriter.Data.CurrentFood;
        var update = new DinoAttrs.Update
        {
            CurrentFood = _curFood + resTaken
        };

        attrsWriter.SendUpdate(update);
    }
예제 #8
0
    // Start is called before the first frame update
    void Start()
    {
        allAnimals.Add(_entityId.Id, this);
        _id = _entityId.Id;
        var update = new DinoAiData.Update
        {
            CurrentAiState = aiDataReader.Data.CurrentAiState
        };

        OnAiDataChanged(update);

        var update2 = new Age.Update
        {
            Age = age.Data.Age
        };

        OnAgeChanged(update2);

        var update3 = new DinoAttrs.Update
        {
        };

        OnAttrsChanged(update3);
    }
예제 #9
0
    public void newBorn()
    {
        // 如果是儿童,一些属性要适当缩小
        float ratioChild = 1.0f;

        if (age.Data.Age < age.Data.GrowUpAge)
        {
            ratioChild = SimulationSettings.NPCChildhoodMinWeekness;
        }

        var update = new DinoAttrs.Update
        {
            IsDead            = false,
            OriginalAgression = ScriptableAnimalStats.agression,
            OriginalDominance = ScriptableAnimalStats.dominance,
            OriginalScent     = ScriptableAnimalStats.scent,
            OriginPosition    = transform.position.ToVector3f(),
            LastHatchTime     = 0,
            CurrentFood       = Random.Range(ScriptableAnimalStats.foodStorage * SimulationSettings.NPCOriginalMinFoodRate * ratioChild, ScriptableAnimalStats.foodStorage * ratioChild), // 儿童
            MaxFood           = ScriptableAnimalStats.foodStorage * ratioChild,                                                                                                           // 儿童
            Power             = ScriptableAnimalStats.power * ratioChild,                                                                                                                 // 儿童
            LiveCost          = ScriptableAnimalStats.liveCost * ratioChild,                                                                                                              // 儿童
        };

        attrsWriter.SendUpdate(update);

        // 小恐龙的生命值也要打折扣
        var update3 = new Health.Update
        {
            CurrentHealth = ScriptableAnimalStats.toughness * ratioChild, // 儿童
            CanBeChanged  = true,
            MaxHealth     = ScriptableAnimalStats.toughness * ratioChild, // 儿童
        };

        health.SendUpdate(update3);
    }
예제 #10
0
    private bool IfShouldDie()
    {
        // No.1 如果已经死了,就啥都不干了
        if (!IsAlive)
        {
            return(true);
        }

        // No.2 恢复健康
        // BUG:如果服务器算不过来,而导致[UnityGameLogic] Worker disconnected
        // 这时候health,age等变量会被置空,从而抛出异常。这是正常现象。
        // 应该去查找为什么会与服务器断开链接,往往是因为计算量太大了,算不过来了而导致的本问题。Sep.7.2019, Liu Gang.
        _curHealth = health.Data.CurrentHealth;
        _maxHealth = health.Data.MaxHealth;
        if (_curHealth + ScriptableAnimalStats.liveCost < _maxHealth)
        {// 健康的恢复速度是粮食消耗速度的一半,不能大于或者粮食消耗的速度,否则就不会饿死了
            _curHealth += ScriptableAnimalStats.liveCost / 2;
        }

        // No.3 消耗粮食
        float cost = ScriptableAnimalStats.liveCost * _deltaTime;

        _curFood = attrsWriter.Data.CurrentFood;
        if (_curFood >= cost)
        {
            _curFood -= cost;
        }
        else
        {
            _curFood    = 0;
            _curHealth -= cost - _curFood;// 粮食不够,就消耗健康
        }
        var update = new DinoAttrs.Update
        {
            CurrentFood = _curFood,
        };

        attrsWriter.SendUpdate(update);
        var update3 = new Health.Update
        {
            CurrentHealth = _curHealth
        };

        health.SendUpdate(update3);

        // No.4 年龄增加
        float lastAge   = age.Data.Age;
        float nowAge    = age.Data.Age + _deltaTime;
        float growupAge = age.Data.GrowUpAge;

        _age = Mathf.FloorToInt(nowAge); // 仅用于显示
        var update2 = new Age.Update
        {
            Age = nowAge
        };

        age.SendUpdate(update2);

        if (_age >= growupAge && lastAge < growupAge)
        {// 成人以后,血量恢复至原始大小
            GrowUp();
        }

        // No.5 判断是否该死了
        if (_curHealth <= 0)
        {
            Die();
            return(true);
        }

        return(false);
    }