/// <summary> /// 对单个目标进行伤害处理 /// </summary> /// <param name="targeter"></param> /// <param name="attackerModel"></param> /// <param name="attacker">技能道具等情况下 attacker 为 null </param> /// <param name="factor"></param> public static void ProcessDamageOneTargeter(TileEntity targeter, EntityModel attackerModel, TileEntity attacker = null, float factor = 1.0f) { if (!targeter.IsDead()) { // 计算伤害 float damage = CalcDamageValue(targeter.model, attackerModel, attacker, factor); // 处理伤害 targeter.MakeDamage(damage); // 没死亡时附加buffer效果 if (!targeter.IsDead()) { GameBufferComponent bufferMgr = targeter.GetComponent <GameBufferComponent>(); if (bufferMgr != null) { bufferMgr.AddBuffer(attackerModel); } } else { // [特殊技能] 死亡后大回复 if (EntityTypeUtil.IsTraitBlessing(targeter.model)) { // TODO: } } // [特殊技能] 吸血 REMARK:考虑是否需要回血光效? if (attacker != null && damage > 0 && EntityTypeUtil.IsTraitSuckBlood(attackerModel)) { attacker.MakeDamage(-damage * Constants.SUCK_BLOOD_RATIO); } } }
/// <summary> /// 准备攻击1(旋转动画对准目标) /// </summary> /// <param name="onlyProcessAnimation"></param> protected void ProcessReadyAttack(bool onlyProcessAnimation = false) { // [速度提升] 动画频率加快 float animatorSpeedRate = 0.0f; GameBufferComponent buffMgr = Entity.GetComponent <GameBufferComponent>(); if (buffMgr != null) { var buffer = buffMgr.GetBuffer(Constants.BUFF_TYPE_SPPEDUP); if (buffer != null) { animatorSpeedRate = buffer.buffDamage; } } //animatorSpeedRate = 2.0f; // DEBUG // REMARK:对准目标动画 仅针对炮塔并且目标数量为1时才有效 if (EntityTypeUtil.IsAnyTower(Entity.entityType) && Entity.AimTarget) { if (AuxIsAllDead()) { // 重新行动 TryAction(); } else { Entity.State = EntityStateType.Rotating; // 旋转对准目标 REMARK:这里Stand就是旋转动画 Entity.PlayAnimationTowardsTarget(AnimationNames.Stand, m_tempTargeters[0], animatorSpeedRate, animationName => { if (Entity.State != EntityStateType.Rotating) { return; } ProcessReadyAttack2(onlyProcessAnimation, animatorSpeedRate); }); } } else { ProcessReadyAttack2(onlyProcessAnimation, animatorSpeedRate); } }
/// <summary> /// 计算目标的伤害值(伤害公式) /// </summary> /// <param name="targeterModel"></param> /// <param name="attackerModel"></param> /// <param name="attacker">技能道具等情况下 attacker 为 null </param> /// <param name="factor">伤害修正系数</param> /// <returns></returns> private static float CalcDamageValue(EntityModel targeterModel, EntityModel attackerModel, TileEntity attacker = null, float factor = 1.0f) { float damage = 0.0f; if (EntityTypeUtil.IsCurer(attackerModel)) { // 回血为负 damage = -factor * attackerModel.cure; } else { // REMARK:伤害公式可以调整 damage = attackerModel.damage - targeterModel.defense; if (attackerModel.additionDamageSubType != Constants.EMPTY && attackerModel.additionDamageSubType == targeterModel.subType) { damage *= attackerModel.additionDamageRatio; } // 技能伤害的时候 attacker 不存在 if (attacker != null) { // [攻击提升] buffer 的情况下乘以伤害倍率 GameBufferComponent attackerBufferMgr = attacker.GetComponent <GameBufferComponent>(); if (attackerBufferMgr != null) { var buffer = attackerBufferMgr.GetBuffer(Constants.BUFF_TYPE_ATTACKUP); if (buffer != null) { damage *= buffer.buffDamage; } } } damage = Mathf.Max(damage * factor, 0); } // 处理伤害 return(damage); }
private void UpdateMove(float dt) { if (path == null) { return; } // TODO:这个时候结束会导致少移动半格 if (currentNode == null) { if (path.Count == 0) { Entity.State = EntityStateType.Idle; enabled = false; if (OnMoveCompleteEvent != null) { OnMoveCompleteEvent(this); } return; } currentNode = path.First.Value; path.RemoveFirst(); // 当前位置到目标位置的向量的单位化*移动速度 CalcNewVelocity(); // 战斗模式下拆墙(否则直接穿墙 if (GameWorld.Instance.worldType == WorldType.Battle || GameWorld.Instance.worldType == WorldType.Replay) { // 不可穿越墙的情况下:转到拆墙 if (!Entity.CanOverTheWall() && IsoMap.Instance.IsWallorLinker(currentNode.X, currentNode.Y)) { // 禁用AI和移动组件并唤醒拆墙AI组件 Entity.GetComponent <ActorComponent>().enabled = false; this.enabled = false; Entity.GetComponent <ActorDestroyWallComponent>().WakeUp(currentNode.X, currentNode.Y); return; } } // 动画方向调整 Entity.PlayAnimationFaceToTile(AnimationNames.Run, new TilePoint(currentNode.X, currentNode.Y)); } // [速度提升] 移动速度倍率 float speedRate = 1.0f; GameBufferComponent buffMgr = Entity.GetComponent <GameBufferComponent>(); if (buffMgr != null) { var buffer = buffMgr.GetBuffer(Constants.BUFF_TYPE_SPPEDUP); if (buffer != null) { speedRate *= buffer.buffDamage; } } // 移动 Entity.tileOffset += velocity * dt * speedRate; #if UNITY_EDITOR if (GameWorld.Instance.worldType == WorldType.Battle || GameWorld.Instance.worldType == WorldType.Replay) { BattleManager.logMoveList.Add(GameRecord.Frame.ToString() + ":" + Entity.tileOffset.ToString()); } #endif // UNITY_EDITOR // 坐标判断(REMARK:这里如果移动速度极快会出BUG 暂时忽略o.o) if (Mathf.Abs(Entity.tileOffset.x) > 0.6f || Mathf.Abs(Entity.tileOffset.y) > 0.6f) { var dx = 0; var dy = 0; if (Entity.tileOffset.x > 0.5f) { dx = 1; } else if (Entity.tileOffset.x < -0.5f) { dx = -1; } if (Entity.tileOffset.y > 0.5f) { dy = 1; } else if (Entity.tileOffset.y < -0.5f) { dy = -1; } var delta = new TilePoint(dx, dy); Entity.tileOffset -= delta; var newpt = Entity.GetTilePos() + delta; Entity.SetTilePosition(newpt); if (newpt.x == currentNode.X && newpt.y == currentNode.Y) { currentNode = null; } else { // 当前位置到目标位置的向量的单位化*移动速度 CalcNewVelocity(); } } }