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); }
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); } } } }
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); }
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); }
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); } } } }
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); }
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); }
// 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); }
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); }
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); }