517 lines
17 KiB
C#
517 lines
17 KiB
C#
using Thousandto.Cfg.Data;
|
|
using Thousandto.Code.Center;
|
|
using Thousandto.Core.Asset;
|
|
|
|
using Thousandto.Core.Base;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using UnityEngine;
|
|
using Thousandto.Code.Global;
|
|
|
|
namespace Thousandto.Code.Logic
|
|
{
|
|
//技能管理器
|
|
public class SkillManager :BaseSystem
|
|
{
|
|
#region id生成器
|
|
private static int InstanceIdGen = 0;
|
|
private static int GenInstanceId()
|
|
{
|
|
return ++InstanceIdGen;
|
|
}
|
|
#endregion
|
|
|
|
|
|
private Character _owner = null;
|
|
private List<Skill> _skillList = new List<Skill>();
|
|
private Skill _curSkill = null;
|
|
private List<SkillFlyVfx> _playingFlyVfx = new List<SkillFlyVfx>();
|
|
|
|
public SkillManager(Character owner)
|
|
{
|
|
_owner = owner;
|
|
}
|
|
|
|
public Character Owner
|
|
{
|
|
get
|
|
{
|
|
return _owner;
|
|
}
|
|
}
|
|
|
|
public Skill CurUseSkill
|
|
{
|
|
get
|
|
{
|
|
return _curSkill;
|
|
}
|
|
}
|
|
|
|
public Skill FindSkillBySerial(int serial)
|
|
{
|
|
for (int i = 0; i < _skillList.Count; ++i)
|
|
{
|
|
if (_skillList[i].Serial == serial)
|
|
return _skillList[i];
|
|
}
|
|
|
|
if (_curSkill != null && _curSkill.Serial == serial)
|
|
{
|
|
return _curSkill;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
//主角使用技能
|
|
public void UseSkill(int skillId, bool isAutoUse)
|
|
{
|
|
if (!Owner.IsLocalPlayer())
|
|
return;
|
|
var skillCfg = DeclareSkill.Get(skillId);
|
|
if (skillCfg == null)
|
|
return;
|
|
|
|
if ((Owner as Player).IsSitDown)
|
|
{
|
|
//如果正在打坐,结束打坐
|
|
var msg = new MSG_Hook.ReqEndSitDown();
|
|
msg.Send();
|
|
}
|
|
|
|
//如果正在使用此技能,直接返回
|
|
if (_curSkill != null && _curSkill.SkillCfg.Id == skillId)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = 0; i < _skillList.Count; ++i)
|
|
{
|
|
if (_skillList[i].SkillCfg.Id == skillId)
|
|
return;
|
|
}
|
|
|
|
//清除缓存的技能
|
|
ClearCacheSkill();
|
|
|
|
LocalPlayer lp = Owner as LocalPlayer;
|
|
lp.MountDown();
|
|
|
|
Skill newSkill = new Skill(GenInstanceId(), Owner, skillCfg, GameCenter.LuaSystem.Adaptor.SkillIsSyncServer(skillId));
|
|
newSkill.UseSelectType = SkillSelectFiledType.None;
|
|
newSkill.ServerResult = false;
|
|
_skillList.Add(newSkill);
|
|
}
|
|
|
|
//主角使用技能
|
|
public void UseSkill(int skillId, SkillSelectFiledType selectType, Vector2 useDir, Vector2 usePos)
|
|
{
|
|
if (!Owner.IsLocalPlayer())
|
|
return;
|
|
var skillCfg = DeclareSkill.Get(skillId);
|
|
if (skillCfg == null)
|
|
return;
|
|
|
|
if ((Owner as Player).IsSitDown)
|
|
{
|
|
//如果正在打坐,结束打坐
|
|
var msg = new MSG_Hook.ReqEndSitDown();
|
|
msg.Send();
|
|
}
|
|
|
|
if (GameCenter.InputSystem.JoystickHandler.Draging && IsSkillUseing())
|
|
{
|
|
//如果正在操作摇杆,只有在没有技能缓存的情况下使用技能
|
|
return;
|
|
}
|
|
|
|
//如果正在使用此技能,直接返回
|
|
if (_curSkill != null && _curSkill.SkillCfg.Id == skillId)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = 0; i < _skillList.Count; ++i)
|
|
{
|
|
if (_skillList[i].SkillCfg.Id == skillId)
|
|
return;
|
|
}
|
|
|
|
//清除缓存的技能
|
|
ClearCacheSkill();
|
|
|
|
LocalPlayer lp = Owner as LocalPlayer;
|
|
lp.MountDown();
|
|
|
|
Skill newSkill = new Skill(GenInstanceId(), Owner, skillCfg, GameCenter.LuaSystem.Adaptor.SkillIsSyncServer(skillId));
|
|
newSkill.UseSelectType = selectType;
|
|
newSkill.UseSelectDir = useDir.normalized;
|
|
newSkill.UseSelectPos = usePos;
|
|
newSkill.ServerResult = false;
|
|
_skillList.Add(newSkill);
|
|
}
|
|
|
|
//主角使用技能返回
|
|
public void HandleLocalPlayerUseSkill(MSG_Fight.ResUseSkill msg)
|
|
{
|
|
if (!Owner.IsLocalPlayer())
|
|
return;
|
|
var skill = FindSkillBySerial(msg.info.serial);
|
|
if(skill != null)
|
|
{
|
|
skill.ServerResult = true;
|
|
if(skill.SkillVisualCfg.WaitServerResult && skill == _curSkill)
|
|
{
|
|
skill.ServerStart();
|
|
}
|
|
}
|
|
GameCenter.PushFixEvent(LogicEventDefine.EID_EVENT_BEGIN_SKILLCD, msg.info.skillID);
|
|
GameCenter.PushFixEvent(Global.LogicEventDefine.EID_EVENT_ON_LP_USE_SKILL, msg.info.skillID);
|
|
}
|
|
|
|
//技能使用失败
|
|
public void HandleLocalPlayerSkillError(MSG_Fight.ResUseSkillError msg)
|
|
{
|
|
if (!Owner.IsLocalPlayer())
|
|
return;
|
|
GameCenter.PushFixEvent(LogicEventDefine.EID_EVENT_END_SKILLCD, msg.skillId);
|
|
if (_curSkill != null && _curSkill.Serial == msg.serial)
|
|
{
|
|
_curSkill.Stop();
|
|
_curSkill = null;
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < _skillList.Count; ++i)
|
|
{
|
|
if (_skillList[i].Serial == msg.serial)
|
|
{
|
|
_skillList[i].Stop();
|
|
_skillList.RemoveAt(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//主角宠物使用技能
|
|
public void LocalPetUseSkill(DeclareSkill skill)
|
|
{
|
|
if (!Owner.IsLocalPet())
|
|
return;
|
|
|
|
//如果正在使用此技能,直接返回
|
|
if (_curSkill != null && _curSkill.SkillCfg.Id == skill.Id)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = 0; i < _skillList.Count; ++i)
|
|
{
|
|
if (_skillList[i].SkillCfg.Id == skill.Id)
|
|
return;
|
|
}
|
|
|
|
//清除缓存的技能
|
|
ClearCacheSkill();
|
|
|
|
LocalPet lp = Owner as LocalPet;
|
|
|
|
Skill newSkill = new Skill(GenInstanceId(), Owner, skill, true);
|
|
newSkill.UseSelectType = SkillSelectFiledType.None;
|
|
newSkill.ServerResult = false;
|
|
_skillList.Add(newSkill);
|
|
}
|
|
//主角宠物使用技能返回
|
|
public void HandleLocalPetUseSkill(MSG_Fight.ResUseSkill msg)
|
|
{
|
|
if (!Owner.IsLocalPet())
|
|
return;
|
|
var skill = FindSkillBySerial(msg.info.serial);
|
|
if (skill != null)
|
|
{
|
|
skill.ServerResult = true;
|
|
if (skill.SkillVisualCfg.WaitServerResult && skill == _curSkill)
|
|
{
|
|
skill.ServerStart();
|
|
}
|
|
}
|
|
}
|
|
|
|
//主角法宝使用技能
|
|
public void LocalFlySwordUseSkill(DeclareSkill skill)
|
|
{
|
|
if (!Owner.IsLocalFlySword())
|
|
return;
|
|
|
|
//如果正在使用此技能,直接返回
|
|
if (_curSkill != null && _curSkill.SkillCfg.Id == skill.Id)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = 0; i < _skillList.Count; ++i)
|
|
{
|
|
if (_skillList[i].SkillCfg.Id == skill.Id)
|
|
return;
|
|
}
|
|
|
|
//清除缓存的技能
|
|
ClearCacheSkill();
|
|
|
|
var lp = Owner as LocalFlySword;
|
|
|
|
Skill newSkill = new Skill(GenInstanceId(), Owner, skill, true);
|
|
newSkill.UseSelectType = SkillSelectFiledType.None;
|
|
newSkill.ServerResult = false;
|
|
_skillList.Add(newSkill);
|
|
}
|
|
//主角法宝使用技能返回
|
|
public void HandleLocalFlySwordUseSkill(MSG_Fight.ResUseSkill msg)
|
|
{
|
|
if (!Owner.IsLocalFlySword())
|
|
return;
|
|
var lf = Owner as LocalFlySword;
|
|
var skill = FindSkillBySerial(msg.info.serial);
|
|
if (skill != null)
|
|
{
|
|
skill.ServerResult = true;
|
|
if (skill.SkillVisualCfg.WaitServerResult && skill == _curSkill)
|
|
{
|
|
skill.ServerStart();
|
|
}
|
|
}
|
|
}
|
|
|
|
//处理其他角色使用技能
|
|
public void UseSkill(MSG_Fight.ResUseSkill msg)
|
|
{
|
|
if (Owner.IsLocalPlayer() || Owner.IsLocalPet() || Owner.IsLocalFlySword())
|
|
return;
|
|
var skillCfg = DeclareSkill.Get(msg.info.skillID);
|
|
if (skillCfg == null)
|
|
return;
|
|
|
|
Skill newSkill = new Skill(msg.info.serial, Owner, skillCfg, false);
|
|
ClearCacheSkill();
|
|
if (Owner is RemotePlayer)
|
|
{
|
|
var rp = Owner as RemotePlayer;
|
|
//下马
|
|
rp.EquipWithType(FSkinPartCode.Mount, 0);
|
|
//其他玩家使用技能,模拟其进入战斗状态
|
|
rp.FightState = true;
|
|
}
|
|
Owner.SetDirection2d(new Vector2(msg.info.dirX, msg.info.dirY), true, false);
|
|
newSkill.ServerResult = true;
|
|
_skillList.Add(newSkill);
|
|
}
|
|
|
|
private void CheckCurSkill()
|
|
{
|
|
if (_curSkill == null && _skillList.Count > 0)
|
|
{
|
|
_curSkill = _skillList[0];
|
|
_curSkill.Start();
|
|
_skillList.RemoveAt(0);
|
|
}
|
|
}
|
|
|
|
protected override bool OnUpdate(float dt)
|
|
{
|
|
CheckCurSkill();
|
|
if (_curSkill != null)
|
|
{
|
|
_curSkill.Update(dt);
|
|
if (_curSkill.IsFinish)
|
|
{
|
|
_curSkill.Stop();
|
|
_curSkill = null;
|
|
}
|
|
}
|
|
CheckCurSkill();
|
|
|
|
for (int i = _playingFlyVfx.Count - 1; i >= 0; --i)
|
|
{
|
|
_playingFlyVfx[i].Update(dt);
|
|
if(_playingFlyVfx[i].IsEnd)
|
|
{
|
|
_playingFlyVfx.RemoveAt(i);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#region 状态函数
|
|
|
|
public void ClearCacheSkill()
|
|
{
|
|
for(int i=0;i< _skillList.Count;++i)
|
|
{
|
|
_skillList[i].Destory();
|
|
}
|
|
_skillList.Clear();
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
ClearCacheSkill();
|
|
if (_curSkill != null)
|
|
{
|
|
_curSkill.Stop(true);
|
|
_curSkill = null;
|
|
}
|
|
|
|
for (int i = 0; i < _playingFlyVfx.Count; ++i)
|
|
{
|
|
_playingFlyVfx[i].Stop();
|
|
}
|
|
_playingFlyVfx.Clear();
|
|
}
|
|
|
|
public bool IsSkillUseing()
|
|
{
|
|
if (_curSkill != null)
|
|
return true;
|
|
if (_skillList.Count > 0)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
public bool HaveCacheSkill()
|
|
{
|
|
return _skillList.Count > 0;
|
|
}
|
|
|
|
public bool CanMove()
|
|
{
|
|
return _curSkill == null || _curSkill.CanMove;
|
|
}
|
|
|
|
//public long RandomDamge(long randomDamage)
|
|
//{
|
|
// long n = (long)Math.Floor((new System.Random()).NextDouble() * 1000000000D);
|
|
// return n % (randomDamage - 1) + 1;
|
|
//}
|
|
////创建伤害数据
|
|
//private Dictionary<int, List<SkillDamageInfo>> CreateDamageInfo(MSG_Fight.ResUseSkill msg)
|
|
//{
|
|
// DeclareSkill skillcfg = DeclareSkill.Get(msg.skillID);
|
|
// if (skillcfg == null)
|
|
// return null;
|
|
// SkillVisualInfo visualCfg = GameCenter.SkillVisualManager.Find(skillcfg.VisualDef);
|
|
// if (skillcfg == null)
|
|
// return null;
|
|
|
|
// //给每一个伤害事件设置伤害数据
|
|
// Dictionary<int, List<SkillDamageInfo>> result = new Dictionary<int, List<SkillDamageInfo>>();
|
|
// for (int i = 0; i < msg.visual.Count; ++i)
|
|
// {
|
|
// var msgInfo = msg.visual[i];
|
|
// var randomDamage = msgInfo.damageHp;
|
|
// if(msgInfo.damageHp > 0 && msgInfo.damageHp < msgInfo.events.Count)
|
|
// {
|
|
// randomDamage = msgInfo.events.Count;
|
|
// }
|
|
// var randomSelfAdd = msgInfo.selfAddHp;
|
|
// if(msgInfo.selfAddHp > 0 && msgInfo.selfAddHp < msgInfo.events.Count)
|
|
// {
|
|
// randomSelfAdd = msgInfo.events.Count;
|
|
// }
|
|
// var randomSelfDec = msgInfo.selfDecHp;
|
|
// if(msgInfo.selfDecHp > 0 && msgInfo.selfDecHp < msgInfo.events.Count)
|
|
// {
|
|
// randomSelfDec = msgInfo.events.Count;
|
|
// }
|
|
|
|
// for (int j = 0; j < msgInfo.events.Count; ++j)
|
|
// {
|
|
// var eventInfo = msgInfo.events[j];
|
|
|
|
// SkillDamageInfo skillTarget = SkillDamageInfo.Get();
|
|
// skillTarget.AttackerID = Owner.ID;
|
|
// skillTarget.TargetID = msgInfo.targetID;
|
|
// skillTarget.TargetPos = new Vector2(eventInfo.posx, eventInfo.posy);
|
|
// skillTarget.EffectType = eventInfo.effect;
|
|
// skillTarget.HitType = CombatUtil.ConvertToHitType(skillTarget.EffectType);
|
|
|
|
// if(randomDamage > 0)
|
|
// {
|
|
// if(j >= msgInfo.events.Count - 1)
|
|
// {
|
|
// skillTarget.DamageHp = randomDamage;
|
|
// }
|
|
// else
|
|
// {
|
|
// skillTarget.DamageHp = RandomDamge(randomDamage / (msgInfo.events.Count - j));
|
|
// randomDamage -= skillTarget.DamageHp;
|
|
// }
|
|
// }
|
|
|
|
// if(randomSelfAdd > 0)
|
|
// {
|
|
// if(j >= msgInfo.events.Count - 1)
|
|
// {
|
|
// skillTarget.SelfAddHp = randomSelfAdd;
|
|
// }
|
|
// else
|
|
// {
|
|
// skillTarget.SelfAddHp = RandomDamge(randomSelfAdd / (msgInfo.events.Count - j));
|
|
// randomSelfAdd -= skillTarget.SelfAddHp;
|
|
// }
|
|
// }
|
|
|
|
// if(randomSelfDec > 0)
|
|
// {
|
|
// if(j >= msgInfo.events.Count - 1)
|
|
// {
|
|
// skillTarget.SelfDecHp = randomSelfDec;
|
|
// }
|
|
// else
|
|
// {
|
|
// skillTarget.SelfDecHp = RandomDamge(randomSelfDec / (msgInfo.events.Count - j));
|
|
// randomSelfDec -= skillTarget.SelfDecHp;
|
|
// }
|
|
// }
|
|
|
|
// skillTarget.IsDead = msgInfo.isDead;
|
|
// skillTarget.MastShowDamage = visualCfg.MastShowDamage;
|
|
|
|
// List<SkillDamageInfo> damageInfo = null;
|
|
// if (result.TryGetValue(eventInfo.eventID, out damageInfo))
|
|
// {
|
|
// damageInfo.Add(skillTarget);
|
|
// }
|
|
// else
|
|
// {
|
|
// damageInfo = new List<SkillDamageInfo>();
|
|
// damageInfo.Add(skillTarget);
|
|
// result.Add(eventInfo.eventID, damageInfo);
|
|
// }
|
|
// }
|
|
// }
|
|
// return result;
|
|
//}
|
|
|
|
////播放飞行特效
|
|
//public void PlayFlyVfx(Vector2 pos, PlayFlyVfxEventInfo info)
|
|
//{
|
|
// //判断技能特效开关
|
|
// if (!GameObjectLimit.CanPlayVfx(Owner))
|
|
// return;
|
|
// var ownerSlot = Owner.GetSlotTransform(SlotUtils.GetSlotName((Slot)info.SlotID));
|
|
// if (ownerSlot == null)
|
|
// return;
|
|
// if (info.VfxID <= 0)
|
|
// return;
|
|
// var pos3d = Owner.Scene.GetTerrainPosition(pos.x, pos.y);
|
|
// var vfx = new FGameObjectVFX(ModelTypeCode.SkillVFX, info.VfxID);
|
|
// vfx.SetPosition(ownerSlot.position);
|
|
// vfx.SetLayer(Owner.Layer);
|
|
// vfx.Play(1f, true);
|
|
// if (vfx != null)
|
|
// {
|
|
// _playingFlyVfx.Add(new SkillFlyVfx(vfx, ownerSlot.position, pos3d, info.FlyTime, info.FlyWaitTime));
|
|
// }
|
|
//}
|
|
#endregion
|
|
}
|
|
}
|