268 lines
9.4 KiB
C#
268 lines
9.4 KiB
C#
using System.Collections.Generic;
|
|
using Thousandto.Cfg.Data;
|
|
using Thousandto.Code.Center;
|
|
using Thousandto.Code.Global;
|
|
using Thousandto.Core.Asset;
|
|
using UnityEngine;
|
|
|
|
namespace Thousandto.Code.Logic
|
|
{
|
|
public class FeiJianBuff : Buff
|
|
{
|
|
//飞剑实例列表
|
|
private List<FeiJianInst> _vfxList = new List<FeiJianInst>();
|
|
//飞剑出生倒计时
|
|
private float _bornTimer = 0f;
|
|
//查找目标辅助列表
|
|
private List<Monster> _helpList = new List<Monster>();
|
|
//闪烁曲线
|
|
private AnimationCurve _curve = null;
|
|
//使用的配置
|
|
private DeclareCloneDaneng _useCfg = null;
|
|
|
|
protected override void OnAddBuffSpecial(Character inOwner = null)
|
|
{
|
|
base.OnAddBuffSpecial(inOwner);
|
|
_bornTimer = 0.5f;
|
|
var lpLv = GameCenter.GameSceneSystem.GetLocalPlayerLevel();
|
|
|
|
DeclareCloneDaneng.Foreach((cfg) =>
|
|
{
|
|
if (lpLv >= cfg.MinLv && lpLv <= cfg.MaxLv)
|
|
{
|
|
_useCfg = cfg;
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
}
|
|
|
|
protected override void OnDeleteBuffSpecial(Character owner)
|
|
{
|
|
base.OnDeleteBuffSpecial(owner);
|
|
if (!owner.IsLocalPlayer())
|
|
return;
|
|
for (int i = _vfxList.Count - 1; i >= 0; --i)
|
|
{
|
|
_vfxList[i].Destroy();
|
|
}
|
|
_vfxList.Clear();
|
|
|
|
var monsters = GameCenter.GameSceneSystem.FindEntityAll<Monster>();
|
|
if(monsters != null && monsters.Count > 0)
|
|
{
|
|
for(int i = 0; i < monsters.Count; ++i)
|
|
{
|
|
monsters[i].LockCurHP = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void OnUpdate()
|
|
{
|
|
base.OnUpdate();
|
|
|
|
var owner = GameCenter.GameSceneSystem.FindEntity<Character>(OwenId);
|
|
if(owner == null || !owner.IsLocalPlayer())
|
|
{
|
|
return;
|
|
}
|
|
_bornTimer -= Time.deltaTime;
|
|
if (_bornTimer <= 0f)
|
|
{
|
|
_bornTimer = 0.25f;
|
|
for (int i = 0; i < 5; ++i)
|
|
{
|
|
var monster = FindMonster();
|
|
if(monster != null)
|
|
{
|
|
_vfxList.Add(new FeiJianInst(999, owner, this, monster, _useCfg));
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i = _vfxList.Count - 1; i >= 0; --i)
|
|
{
|
|
if (_vfxList[i].Update(Time.deltaTime))
|
|
{
|
|
_vfxList.RemoveAt(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void AtkMonster(Monster m)
|
|
{
|
|
if (m == null || m.IsDead() || m.CurHP <= 0 || _useCfg == null)
|
|
{
|
|
return;
|
|
}
|
|
if (_curve == null)
|
|
{
|
|
_curve = new AnimationCurve();
|
|
_curve.AddKey(0, 0);
|
|
_curve.AddKey(0, 1);
|
|
}
|
|
|
|
m.ShowHUD();
|
|
GameCenter.PushFixEvent(LogicEventDefine.EID_EVENT_HUD_SHOWMONSTER_HP, m);
|
|
//播放闪烁效果
|
|
m.Blinker.Start(0.2f, 1f, Color.white, _curve, m.Skin);
|
|
long damageHP = GameCenter.GameSceneSystem.GetLocalPlayerFightPower();
|
|
|
|
m.LockCurHP = false;
|
|
if (m.PropMoudle.CurHP > (ulong)damageHP)
|
|
{
|
|
m.PropMoudle.CurHP = m.PropMoudle.CurHP - (ulong)damageHP;
|
|
}
|
|
else
|
|
{
|
|
m.PropMoudle.CurHP = 0;
|
|
}
|
|
m.LockCurHP = true;
|
|
|
|
var damage = new MSG_Fight.HitEffectInfo();
|
|
damage.effect = 0;
|
|
damage.targetID = m.ID;
|
|
damage.isDead = false;
|
|
damage.damageHp = damageHP;
|
|
damage.damageWaken = 0;
|
|
GameCenter.PushFixEvent(LogicEventDefine.EID_EVENT_HUD_POPUP_DAMAGE, damage, GameCenter.GameSceneSystem.GetLocalPlayer());
|
|
|
|
if (m.PropMoudle.CurHP <= 0)
|
|
{
|
|
MSG_copyMap.ReqKillMonster msg = new MSG_copyMap.ReqKillMonster();
|
|
msg.monsterId = (long)m.ID;
|
|
msg.Send();
|
|
}
|
|
}
|
|
|
|
private Monster FindMonster()
|
|
{
|
|
_helpList.Clear();
|
|
var lp = GameCenter.GameSceneSystem.GetLocalPlayer();
|
|
var monsterList = GameCenter.GameSceneSystem.FindEntityAll<Monster>();
|
|
for (int i = 0; i < monsterList.Count; ++i)
|
|
{
|
|
if (monsterList[i].CurHP > 0 && CombatUtil.CanAttackTarget(lp, monsterList[i], false) && lp.GetSqrDistance2d(monsterList[i].Position2d) <= 225f)
|
|
{
|
|
_helpList.Add(monsterList[i]);
|
|
}
|
|
}
|
|
if (_helpList.Count > 0)
|
|
{
|
|
return _helpList[Random.Range(0, _helpList.Count)];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
#region//私有类
|
|
private class FeiJianInst
|
|
{
|
|
public FGameObjectVFX Vfx = null;
|
|
//计时器
|
|
private float _timer = 0f;
|
|
private float _maxTime = 2f;
|
|
|
|
private Vector3 _ownerPos = Vector3.zero;
|
|
private Vector3 _oriDir = Vector3.zero;
|
|
private Vector3 _tarDir = Vector3.zero;
|
|
private float _tarRadius = 0f;
|
|
private float _timeSpeed = 1f;
|
|
//上一帧的位置,用于计算方向
|
|
private Vector3 _frontPos = Vector3.zero;
|
|
//目标怪物
|
|
private Monster _target = null;
|
|
//父buff
|
|
private FeiJianBuff _parent;
|
|
|
|
public FeiJianInst(int vfxId, Character owner, FeiJianBuff parrnt, Monster target, DeclareCloneDaneng useCfg)
|
|
{
|
|
_parent = parrnt;
|
|
_target = target;
|
|
_oriDir = new Vector3(Random.Range(-1f, 1f), 0f, Random.Range(-1f, 1f)).normalized;
|
|
if (_target != null)
|
|
{
|
|
_tarDir = (_target.Position - owner.Position).normalized;
|
|
_tarRadius = Vector3.Distance(_target.Position, owner.Position);
|
|
if(!_target.LockCurHP)
|
|
{
|
|
switch (_target.PropMoudle.Cfg.MonsterType)
|
|
{
|
|
case 1:
|
|
_target.PropMoudle.CurHP = (ulong)useCfg.MonsterMaxHp1;
|
|
_target.PropMoudle.SetBattleProp(AllBattleProp.MaxHP, useCfg.MonsterMaxHp1);
|
|
break;
|
|
case 2:
|
|
_target.PropMoudle.CurHP = (ulong)useCfg.MonsterMaxHp2;
|
|
_target.PropMoudle.SetBattleProp(AllBattleProp.MaxHP, useCfg.MonsterMaxHp2);
|
|
break;
|
|
default:
|
|
_target.PropMoudle.CurHP = (ulong)useCfg.MonsterMaxHp3;
|
|
_target.PropMoudle.SetBattleProp(AllBattleProp.MaxHP, useCfg.MonsterMaxHp3);
|
|
break;
|
|
}
|
|
}
|
|
_target.LockCurHP = true;
|
|
}
|
|
else
|
|
{
|
|
_tarDir = owner.GetFacingDirection();
|
|
_tarRadius = 10f;
|
|
}
|
|
_frontPos = owner.Position + Vector3.up * 1f;
|
|
_ownerPos = _frontPos;
|
|
|
|
var lod = 0;
|
|
if (!owner.IsLocalPlayer())
|
|
{//只针对其他玩家
|
|
//这里因为GameSettingKeyCode.OtherPlayerSkillVfxLevel的值是:0屏蔽全部,1弱,2中,3强.
|
|
//而lod是0最强,往下最弱.
|
|
lod = FGameObjectVFXRoot.CN_VFX_LEVEL_MAX - GameCenter.GameSetting[GameSettingKeyCode.OtherPlayerSkillVfxLevel]; ;
|
|
}
|
|
_timeSpeed = 1f;
|
|
Vfx = new FGameObjectVFX(ModelTypeCode.SkillVFX, 606, true, false, lod);
|
|
Vfx.SetLayer(owner.Layer);
|
|
Vfx.SetPosition(_frontPos);
|
|
Vfx.Play();
|
|
Vfx.SetForward(_oriDir);
|
|
_timer = 0f;
|
|
Update(0f);
|
|
}
|
|
|
|
public void Destroy()
|
|
{
|
|
Vfx.Destroy();
|
|
Vfx = null;
|
|
}
|
|
|
|
public bool Update(float dt)
|
|
{
|
|
if (Vfx == null)
|
|
return true;
|
|
_timeSpeed += dt * 1f;
|
|
_timer += dt * _timeSpeed;
|
|
if (_timer >= _maxTime)
|
|
{
|
|
_parent.AtkMonster(_target);
|
|
Vfx.Destroy();
|
|
Vfx = null;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
var lerpValue = _timer / _maxTime;
|
|
var newPos = _ownerPos + Mathf.Lerp(0f, _tarRadius, lerpValue) * Vector3.Slerp(_oriDir, _tarDir, lerpValue).normalized;
|
|
if (newPos != _frontPos)
|
|
{
|
|
Vfx.SetForward(newPos - _frontPos);
|
|
_frontPos = newPos;
|
|
}
|
|
Vfx.SetPosition(newPos);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|