using CommonAI.data;
using CommonAI.Data;
using CommonAI.Zone;
using CommonAI.Zone.Helper;
using CommonAI.Zone.Instance;
using CommonAI.ZoneClient;
using CommonAI.ZoneServer.JSGModule;
using CommonLang;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XmdsCommon.EditorData;
using XmdsCommon.JSGModule.Interface;
using XmdsCommon.Plugin;
using XmdsCommonServer.Message;
using XmdsCommonServer.Plugin.Base;
using XmdsCommonServer.Plugin.Units;
using XmdsCommonServer.Plugin.XmdsSkillTemplate;
using XmdsCommonServer.Plugin.XmdsSkillTemplate.DamageCalculator;
using XmdsCommonServer.Plugin.XmdsSkillTemplate.Skills;
using XmdsCommonServer.XLS.Data;
using XmdsCommonSkill.Plugin.CardSkill;
using static CommonAI.Zone.Instance.InstanceUnit;
namespace XmdsCommonServer.Plugin
{
///
/// FileName: XmdsVirtual.cs
/// Author: Alex.Yu
/// Corporation:...
/// Description:
/// DateTime: 2015/5/12 10:20:46
///
public partial class XmdsVirtual
{
//技能初始化辅助类.
protected XmdsSkillHelper mSkillHelper = null;
///
/// 初始化技能辅助类.
///
public XmdsSkillHelper SkillHelper { get { return mSkillHelper; } }
//卡牌技能类
private IJSCardSkillModule mCardModule;
//玩家本地缓存数据
private IPlayerCache mPlayerCache;
public IJSCardSkillModule CardModule { get { return mCardModule; } }
private HashMap mTrySendBuff = new HashMap();
private HashMap mTrySendSpell = new HashMap();
private HashMap mLaunchSpellOver = new HashMap();
//扩展字段
//法师:标记剑影是否强化过
public int extValue = 0;
#region 技能相关.
private void ReGetUnitSkills(List ls, List retList)
{
GameSkill gs = null;
for (int i = ls.Count - 1; i >= 0; i--)
{
gs = ls[i];
if (gs.SkillID == 0)
{
ls.RemoveAt(i);
}
else if (this.IsPlayerUnit() || getSkillType(ref gs))//玩家的技能来自游戏服,不管表格类型
{
retList.Add(gs);
}
}
}
private void CreateCreateCardModule()
{
// if (this.mCardModule == null)
// {
// if (this.mUnit.IsPlayer)
// {
// this.mCardModule = XmdsGlobalData.GetPlayerCardModule(this);
// }
// else if (this.mUnit.IsMonster && this.IsBoss())
// {
// this.mCardModule = new JSGMonsterCardModule(this);
// }
// else
// {
// this.mCardModule = new JSGOtherCardModule();
// }
// }
}
public void InitCardModule()
{
// this.mCardModule.Init(this);
//
// if(this.mUnit.VisibleInfo != null)
// {
// this.mUnit.VisibleInfo.setVisibleCardData(this.mCardModule.GetCardInterface());
// }
}
protected void checkSkillData(XmdsUnitData data)
{
//过滤data 防止无效的gameSkill.
List retList = new List();
// 常规技能
if (data.Skills != null && data.Skills.UnitSkills != null)
{
this.ReGetUnitSkills(data.Skills.UnitSkills, retList);
}
// 卡牌技能
if(data.CardSkills != null && data.CardSkills.UnitSkills != null)
{
this.ReGetUnitSkills(data.CardSkills.UnitSkills, retList);
}
#region Mock数据.
GameSkill gs = null;
//如果为空判断为编辑器环境,走MOCK数据.
//if (data.Skills == null || data.Skills.UnitSkills == null || data.Skills.UnitSkills.Count == 0)
{
//单位普攻.
if (mInfo.BaseSkillID != null && mInfo.BaseSkillID.SkillID != 0)
{
gs = new GameSkill();
gs.SkillID = this.mInfo.BaseSkillID.SkillID;
gs.SkillType = XmdsSkillType.normalAtk;
gs.SkillLevel = 1;
retList.Add(gs);
}
//单位技能.
for (int i = 0; i < this.mInfo.Skills.Count; i++)
{
gs = new GameSkill();
gs.SkillID = this.mInfo.Skills[i].SkillID;
gs.SkillLevel = 1;
if (getSkillType(ref gs))
{
retList.Add(gs);
}
}
if (data.Skills == null)
{
XmdsUnitSkillInfo info = new XmdsUnitSkillInfo();
info.UnitSkills = retList;
data.Skills = info;
}
else
{
data.Skills.UnitSkills = retList;
}
}
#endregion
if (mSkillHelper == null)
{
mSkillHelper = new XmdsSkillHelper();
}
}
private bool getSkillType(ref GameSkill gs)
{
XmdsSkillData skillData = XmdsDataMgr.GetInstance().GetXmdsSkillData(gs.SkillID);
if (skillData != null && skillData.SkillType > 0)
{
gs.SkillType = (XmdsSkillType)skillData.SkillType;
return true;
}
else
{
SkillTemplate st = XmdsBattleSkill.GetSkillTemplate(gs.SkillID);
if (st != null)
{
gs.SkillType = (st.Properties as XmdsSkillProperties).SkillType;
return true;
}
else
{
log.Warn("checkSkillData 找不到单位:" + this.mUnit.Info.ID + ", 技能ID: " + gs.SkillID);
}
}
return false;
}
//重新调用一下基础技能的initOver
public bool ReInitOverBaseSkill(GameSkill info)
{
AbstractSkill baseSkill = this.SkillHelper.GetPlayerSkillById(this.SkillHelper.GetBaseSkillID());
if (baseSkill == null)
{
log.Error("找不到单位基础技能:" + this.mUnit.PlayerUUID + ", 技能初始化:" + info.SkillID + ", 基础技能: " + this.SkillHelper.GetBaseSkillID());
return false;
}
// 借用一下这个接口,懒得写新的了
baseSkill.InitOver(this, info);
return true;
}
//初始化技能.
protected virtual void InitSkillInfo(XmdsUnitData data)
{
this.checkSkillData(data);
mFinishSkillInit = true;
mSkillHelper.InitSkill(data.Skills, this);
}
public bool ChangeSkill(int oldSkillID, int newSkillID, SkillLevelData skillData)
{
try
{// 同技能只改表数值的话,无需重新init,赋值
if (oldSkillID == newSkillID)
{
GameSkill gs = this.SkillHelper.GetGameSkill(newSkillID);
if (gs == null)
{
log.Warn("相同技能替换,更新数值,技能不存在: " + newSkillID + ", " + this.mUnit.PlayerUUID);
return false;
}
gs.SkillLevel = skillData.SkillLevel;
gs.TalentSkillLevel1 = skillData.TalentSkillLevel1;
gs.TalentSkillLevel2 = skillData.TalentSkillLevel2;
gs.TalentSkillLevel3 = skillData.TalentSkillLevel3;
if (gs.SkillType == XmdsSkillType.passive || gs.SkillType == XmdsSkillType.petGivePassive)
{
UnitPassiveSkill skill = this.mSkillHelper.GetPlayerSkillByIdExt(newSkillID);
skill.SkillDataChange(gs, this);
}
else
{
UnitSkill skill = this.mSkillHelper.GetPlayerSkillById(newSkillID);
skill.SkillDataChange(gs, this);
}
}
else
{
GameSkill oldSkill = null;
long skillCD = 0;
if (oldSkillID > 0)
{
skillCD = this.GetSkillTimestampMS(oldSkillID);
oldSkill = this.RemoveSkill(oldSkillID);
}
if (newSkillID > 0)
{
//激活指定技能.
GameSkill gs = gs = new GameSkill();
gs.SkillID = newSkillID;
gs.SkillType = skillData.skillType;
gs.SkillLevel = skillData.SkillLevel;
gs.TalentSkillLevel1 = skillData.TalentSkillLevel1;
gs.TalentSkillLevel2 = skillData.TalentSkillLevel2;
gs.TalentSkillLevel3 = skillData.TalentSkillLevel3;
gs.SkillTimestampMS = skillCD;
gs.AutoLaunch = gs.SkillType != XmdsSkillType.cardSkill;
if (gs.SkillType == XmdsSkillType.passive || gs.SkillType == XmdsSkillType.petGivePassive)
{
AbstractSkill skill = this.mSkillHelper.AddPassiveSkill(gs);
}
else
{
AbstractSkill skill = this.mSkillHelper.AddActiveSkill(gs, gs.SkillType == XmdsSkillType.normalAtk);
// if (gs.SkillType == XmdsSkillType.cardSkill && this.CardModule != null)
// {
// //this.CardModule.InitSkill
// }
}
//if (skillCD > 0)
//{
// SkillState skillState = this.SetSkillCD(newSkillID, skillCD);
// if (skillState != null)
// {
// skillState.Reset();
// }
//}
}
}
}
catch (Exception e)
{
log.Warn("ChangeSkill catch: " + oldSkillID + ", " + newSkillID + ", " + e);
}
return true;
}
private void UpdateSkillHelper(int intervalMS, bool slowRefresh)
{
if (mSkillHelper != null)
{
mSkillHelper.Update(intervalMS, slowRefresh);
}
}
#endregion
public bool AllowAutoLaunch(int skillid)
{
bool ret = false;
if (mSkillHelper != null)
{
var gs = mSkillHelper.GetGameSkill(skillid);
if (gs != null)
{
ret = gs.AutoLaunch;
}
}
return ret;
}
public bool TryLaunchSpell(LaunchSpell launch, ref SpellTemplate spell, out JSGCreateSpellData createData, ref float startX, ref float startY)
{
SpellTemplate redirect;
if (mTrySendSpell.TryGetValue(spell.ID, out redirect))
{
spell = redirect;
}
DispatchTrySendSpellEvent(launch, ref spell, out createData, ref startX, ref startY);
return true;
}
public bool TrySendBuff(ref BuffTemplate buff, XmdsVirtual target, out object tag)
{
//无敌中,负面BUFF无效.
if (target.IsInvincible && buff.IsHarmful == true)
{
target.SendBattleHintNumberB2C(0, XmdsVirtual.UnitHitEventState.Immunity);
tag = null;
return false;
}
bool ret = true;
tag = null;
if (buff.IsHarmful == true)
{
//给别人施加debuff.
this.OnHitOthter(target);
}
//无敌时不受负面BUFF影响.
//if (target.mUnit.IsInvincible && buff.IsHarmful == true)
//{
// ret = false;
//}
if (ret == true)
{
//重定向buff.
BuffTemplate redirect;
if (mTrySendBuff.TryGetValue(buff.ID, out redirect))
{
buff = redirect;
}
var temp = buff.Properties as XmdsBuffProperties;
List list = temp.GetBuffVirtualList();
//克隆BUFF能力.
if (list != null && list.Count > 0)
{
List cList = new List();
Type ctype = null;
UnitBuff dst = null;
UnitBuff src = null;
for (int i = 0; i < list.Count; i++)
{
src = list[i] as UnitBuff;
ctype = src.GetType();
dst = CommonLang.Property.ReflectionUtil.CreateInstance(ctype) as UnitBuff;
src.CopyTo(dst);
cList.Add(dst);
}
tag = cList;
}
//判断能否添加.
target.DispatchTryAddBuffEvent(ref buff, target, ref ret);
}
return ret;
}
public void SendAddBuffEvent(XmdsVirtual hitter, BuffTemplate buff)
{
//this.DispatchSendBuffEvent(buff, hitter);
}
public void RegistSendBuff(BuffTemplate buff)
{
//if(mTrySendBuff.ContainsKey(buff.ID))
//{
// FormatLog(CommonLang.Log.LoggerLevel.ERROR, "RegistSendBuff 重复利用buff : {0}, {1}", this.mInfo.Name, buff.ID);
//}
mTrySendBuff.Put(buff.ID, buff);
}
public void RegistSendSpell(SpellTemplate spell)
{
mTrySendSpell.Put(spell.ID, spell);
}
public BuffTemplate GetRegistBuff(int id)
{
BuffTemplate ret = null;
if (mTrySendBuff.TryGetValue(id, out ret))
{
return ret;
}
return null;
}
public UnitBuff GetRegisBuffVirtual(int id, int index = 0)
{
if (index < 0) return null;
UnitBuff ret = null;
BuffTemplate bt = GetRegistBuff(id);
XmdsBuffVirtual zbv = null;
if (bt != null)
{
List list = (bt.Properties as XmdsBuffProperties).GetBuffVirtualList();
if (list != null && index < list.Count)
{
zbv = list[index];
if (zbv != null)
{
ret = zbv as UnitBuff;
}
}
}
return ret;
}
///
/// 判断是否可放技能.
///
///
///
public virtual bool TryLaunchSkill(InstanceUnit.SkillState skill, ref InstanceUnit.LaunchSkillParam param)
{
#region
if (!this.mUnit.IsCanLaunchSkill(skill.ID))
{
SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_CAN_NOT_USE_SKILL);
return false;
}
if (this.mUnit.IsCannotMove && skill.Data.ActionPriority < 0)
{
SendMsgToClient(CommonAI.XmdsConstConfig.CANNOT_LAUNCH_DISPACEMENTSKILL);
return false;
}
//需要的能量是否足够(战士某些技能需要怒气)
if(!this.LaunchSkillCheckTalentInfo(skill))
{
return false;
}
#endregion
#region 普攻不能取消普攻.
//TODO 屏蔽普攻不能取消普攻.
/*
if (this.mUnit.CurrentState is InstanceUnit.StateSkill)
{
if ((this.mUnit.CurrentState as InstanceUnit.StateSkill).SkillData.ID == skill.ID)
{
if (skill.Data.IsManuallyCancelable == false)
{
return false;
}
else
{
//直接交由skillstate.tryluanch判断.
return true;
}
}
}
*/
#endregion
//坐骑状态检查,如果是坐骑状态,主动切换骑乘.
MountOnLaunchSkillCheck();
bool ret = false;
//XmdsSkillProperties prop = (XmdsSkillProperties)skill.Data.Properties;
//if (prop.IsRandomNormalAttack)
//{
// skill.SetAutoIncreaseActionIndex(false);
// byte k = (byte)(this.mUnit.RandomN.Next(0, skill.Data.ActionQueue.Count));
// skill.SetActionIndex(k);
//}
DispatchTryLaunchSkillEvent(ref skill, ref ret, ref param);
// 存储多段式技能判定
if (ret && skill.CanStoreTimes)
{
ret = skill.OveryLayer > 0;
}
return ret;
}
/** 检测技能天赋信息 */
public bool LaunchSkillCheckTalentInfo(InstanceUnit.SkillState skill)
{
//需要的能量是否足够(战士某些技能需要怒气)
if (this.mUnit.IsPlayer && skill.ActionIndex == -1 && (this.GetUnitPro() == XmdsUnitPro.Sword || this.GetUnitPro() == XmdsUnitPro.Magic))
{
XmdsSkillValue data = XmdsGlobalData.GetTalentData(skill.Data.ID);
if (data != null)
{
//天赋值
if (data.GetValue(1) > 0 && this.Talent_Value() < data.GetValue(1))
{
return false;
}
//天赋等级
if (!data.IsSingleCfg() && data.GetValue(2) > 0 && this.Talent_Lv() < data.GetValue(2))
{
return false;
}
}
}
return true;
}
#region 技能监听回调.
//技能成功施放回调.
private long mPreLaunchTime;
private void OnLaunchSkillHandler(InstanceUnit obj, CommonAI.Zone.Instance.InstanceUnit.SkillState skill)
{
XmdsSkillProperties skillProp = skill.Data.Properties as XmdsSkillProperties;
//增加Buff判断,部分buff效果可使技能使用效果发生变更.
DispatchLaunchsSkillOverEvent(this, skill);
//天赋点扣除
if (this.mUnit.IsPlayer && skill.ActionIndex <= 0 && (this.GetUnitPro() == XmdsUnitPro.Sword || this.GetUnitPro() == XmdsUnitPro.Magic))
{
XmdsSkillValue data = XmdsGlobalData.GetTalentData(skill.Data.ID);
if (data != null && data.GetValue() > 0)
{
if (!this.Talent_Use(data.GetValue()))
{
long timePass = System.DateTime.Now.Ticks - mPreLaunchTime;
log.Warn("天赋扣除异常:" + this.mUnit.PlayerUUID + ", SceneID: " + this.mUnit.Parent.GetSceneID() + ", " + timePass);
}
}
}
//能量扣除.
//mUnit.AddMP(-cost);
mPreLaunchTime = System.DateTime.Now.Ticks;
}
//回调增加技能.
private void OnSkillAddHandler(InstanceUnit unit, CommonAI.Zone.Instance.InstanceUnit.SkillState sk)
{
}
//回调移除技能.
private void OnSkillRemoveHandler(InstanceUnit unit, CommonAI.Zone.Instance.InstanceUnit.SkillState sk)
{
if (mSkillHelper != null)
{
mSkillHelper.RemoveSkill(sk);
}
}
//状态机切换.
private void OnStateChangedHandler(InstanceUnit obj, InstanceUnit.State old_state, InstanceUnit.State new_state)
{
if (old_state != null && old_state is InstanceUnit.StateSkill)
{
InstanceUnit.StateSkill stateSkill = old_state as InstanceUnit.StateSkill;
//获得技能ID.
int id = stateSkill.SkillData.ID;
DispatchStateSkillEndEvent(this, stateSkill);
}
if (new_state is InstanceUnit.StatePickObject)
{
TakeOffMount();
}
}
private void OnSkillHitTargetHandler()
{
//吸血,待完善
}
#endregion
///
/// 检查当前buff状态,是否可添加.
///
///
private bool CanAddBuff(ref BuffTemplate buff, XmdsVirtual target)
{
bool ret = false;
//获取当前BUFF是哪种能力.
XmdsBuffProperties prop = buff.Properties as XmdsBuffProperties;
//XmdsBuffProperties.XmdsBuffAbility ab = prop.BuffAbilityList;
////判断该种BUFF是否被约束.
//switch (ab)
//{
// case XmdsBuffProperties.XmdsBuffAbility.FROZEN:
// case XmdsBuffProperties.XmdsBuffAbility.STUN:
// case XmdsBuffProperties.XmdsBuffAbility.Silent:
// break;
// default: break;
//}
return ret;
}
///
/// 外部获取当前技能状态信息,排除被动技能
///
///
public XmdsSkillStatusData GetSkillStatusData()
{
XmdsSkillStatusData ret = new XmdsSkillStatusData();
ret.SkillTimestampMSMap = new HashMap();
//生成同步时间戳.
long SkillTimestampMS = TimeUtil.GetTimestampMS();
IEnumerable sslist = mUnit.SkillStatus;
//主动技能.
foreach (InstanceUnit.SkillState s in sslist)
{
if (s.ActionIndex > 0 && s.IsHasNext())
{
s.ForceIntoCD();
}
if(s.GetSkillType() == XmdsSkillType.cardSkill)
{
continue;
}
ret.SkillTimestampMSMap.Add(s.ID, SkillTimestampMS + s.TotalCDTime - s.PassTime);
}
//被动技能.
//if (SkillHelper.mPassiveSkills != null)
//{
// for (int i = 0; i < SkillHelper.mPassiveSkills.Count; i++)
// {
// UnitPassiveSkill ups = SkillHelper.mPassiveSkills[i];
// ret.SkillTimestampMSMap.Add(ups.SkillID, SkillTimestampMS + ups.GetCDTotalTime() - ups.GetCDPassTime());
// }
//}
return ret;
}
public long GetSkillTimestampMS(int skillID)
{
InstanceUnit.SkillState ss = this.mUnit.getSkillState(skillID);
if (ss != null)
{
long SkillTimestampMS = TimeUtil.GetTimestampMS() + ss.TotalCDTime - ss.PassTime;
return SkillTimestampMS;
}
return 0;
}
private int CalSkillCDTime(long timestamp)
{
long curTime = TimeUtil.GetTimestampMS();
long dif = timestamp - curTime;
return (int)dif;
}
private InstanceUnit.SkillState SetSkillCD(int skillid, long timestamp)
{
InstanceUnit.SkillState ss = this.mUnit.getSkillState(skillid);
if (ss == null)
{
return null;
}
int time = CalSkillCDTime(timestamp);
//大于0代表还处于CD中.
if (time > 0 && time <= ss.TotalCDTime)
{
ss.IsInMutilTime = false;
this.mUnit.SetSkillPassTime(skillid, ss.TotalCDTime - time);
}
return ss;
}
private void SetSkillCDDecreasePercent(int skillid, int percent)
{
if (percent == 0)
{
return;
}
InstanceUnit.SkillState ss = this.mUnit.getSkillState(skillid);
if (ss == null)
{
return;
}
int cd = ss.Data.CoolDownMS;
int dt = (int)(cd * (percent * 1.0f / XmdsDamageCalculator.PERER));
ss.AddDecreaseTotalTimeMS(dt);
}
public void DestorySkill()
{
if (mSkillHelper != null)
{
mSkillHelper.Dispose();
mSkillHelper = null;
}
foreach (var buf in mTrySendBuff.Values)
{
var bvlist = (buf.Properties as XmdsBuffProperties).GetBuffVirtualList();
foreach (var bv in bvlist)
{
bv.Dispose();
}
bvlist.Clear();
}
mTrySendBuff.Clear();
mTrySendSpell.Clear();
}
///
/// 技能信息辅助类.
///
public class XmdsSkillHelper
{
//普通技能.
private SkillTemplate mBaseSkill = null;
//单位拥有的技能.
private HashMap mSkillMap = null;
//单位自己的主动技能模板.
private HashMap mActiveSkillTemplateMap = null;
//单位拥有的被动技能.
internal List mPassiveSkills = null;
//单位拥有的主动技能.
internal List mActiveSkills = null;
//宿主.
private XmdsVirtual mOwner = null;
public XmdsSkillHelper()
{
//主动技能表.
if (mActiveSkillTemplateMap == null)
{
mActiveSkillTemplateMap = new HashMap();
}
if (mActiveSkills == null)
{
mActiveSkills = new List();
}
}
public void InitSkill(XmdsUnitSkillInfo sks, XmdsVirtual owner)
{
if (mSkillMap != null) { mSkillMap.Clear(); }
else { mSkillMap = new HashMap(); }
mOwner = owner;
//主动技能初始化.
if (sks != null)
{
InitSkill(sks.UnitSkills);
}
}
public String GetAllSkills()
{
String skillText = "";
foreach (KeyValuePair pair in mSkillMap)
{
skillText += pair.Key + ", ";
}
return skillText;
}
///
/// 获得主动、被动技能列表.
///
///
///
///
private void GetActivePassiveSkillList(List src, ref List active, ref List passive)
{
GameSkill gs = null;
for (int i = 0; i < src.Count; i++)
{
gs = src[i];
if (JSGModule.IsActiveSkill(gs.SkillType))
{
active.Add(gs);
}
else if (JSGModule.IsPassiveSkill(gs.SkillType))
{
passive.Add(gs);
}
}
}
#region 主动技能.
///
/// 初始化主动技能.
///
///
public void InitActiveSkills(List gameSkills)
{
try
{
if (gameSkills == null || gameSkills.Count == 0) { return; }
//需要判断BUFF状态,记录单位技能信息.
GameSkill gs = null;
UnitSkill us = null;
SkillTemplate st = null;
for (int i = 0; i < gameSkills.Count; i++)
{
gs = gameSkills[i];
if (mSkillMap.ContainsKey(gameSkills[i].SkillID))
{
continue;
}
//主动技能初始化只有初始化成功的技能会在技能MAP中.
//存放技能等级信息.
mSkillMap.Add(gameSkills[i].SkillID, gameSkills[i]);
us = InitXmdsSkillScript(gs, ref st);
if (us != null && st != null)
{
mActiveSkillTemplateMap.Add(st.ID, st);
//UnitSkill us = XmdsBattleSkill.GetUnitSkill(gs.SkillID);
mActiveSkills.Add(us);
//if(st.ID != us.SkillID)
//{
// log.Warn("初始化技能,使用脚本不一致, 技能" + st.ID + ", 使用:" + us.SkillID);
//}
}
else
{
FormatLog(string.Format("XmdsVirtual.Skill can not find SkillScript {0},", gs.SkillID));
}
}
#region 重置单位技能.
List temp = new List();
for (int i = 0; i < gameSkills.Count; i++)
{
gs = gameSkills[i];
if (mActiveSkillTemplateMap.TryGetValue(gs.SkillID, out st))
{
//分辨出普通攻击.
if (gs.SkillType == XmdsSkillType.normalAtk)
{
mBaseSkill = st;
}
else
{
temp.Add(st);
}
}
}
if (temp.Count > 0 || mBaseSkill != null)
{
//重置技能.
mOwner.mUnit.InitSkills(mBaseSkill, temp.ToArray());
}
for (int i = 0; i < temp.Count; i++)
{
if (mSkillMap.TryGetValue(temp[i].ID, out gs))
{
mOwner.SetSkillCD(temp[i].ID, gs.SkillTimestampMS);
mOwner.SetSkillCDDecreasePercent(temp[i].ID, gs.SkillCDDecreasePercent);
// 人物, 宠物的技能是否自动释放走配置表
if (mOwner is XmdsVirtual_Player || mOwner is XmdsVirtual_Pet)
{
SkillState skillState = mOwner.mUnit.getSkillState(temp[i].ID);
if (skillState != null)
{
skillState.setAutoLaunch(gs.AutoLaunch);
}
}
}
}
//UnitSkillList.Clear();
//UnitSkillList = null;
#endregion
}
catch (Exception error)
{
FormatLog(CommonLang.Log.LoggerLevel.ERROR, "单位【{0}】初始化技能错误:{1}", mOwner.mInfo.Name, error.ToString());
}
}
public void notifyActiveSkillInitOver(List gameSkills)
{
if (mActiveSkills == null)
{
return;
}
for (int i = 0; i < mActiveSkills.Count; i++)
{
GameSkill gameSkill = null;
for (int j = 0; j < gameSkills.Count; j++)
{
if (mActiveSkills[i].SkillID == gameSkills[j].SkillID)
{
gameSkill = gameSkills[j];
break;
}
}
mActiveSkills[i].InitOver(mOwner, gameSkill);
}
}
public void notifyPassiveSkillInitOver(List gameSkills)
{
if (mPassiveSkills == null)
{
return;
}
for (int i = 0; i < mPassiveSkills.Count; i++)
{
GameSkill gameSkill = null;
for (int j = 0; j < gameSkills.Count; j++)
{
if (mPassiveSkills[i].SkillID == gameSkills[j].SkillID)
{
gameSkill = gameSkills[j];
break;
}
}
mPassiveSkills[i].InitOver(mOwner, gameSkill);
}
}
//public bool changeActiveSkill(int oldSkillID, int newSkillID)
//{
// try
// {
// if (oldSkillID == 0 || oldSkillID == newSkillID)
// {
// return false;
// }
// GameSkill oldSkill = mSkillMap.Get(oldSkillID);
// GameSkill newSkill = mSkillMap.Get(newSkillID);
// if (oldSkill == null || newSkill != null)
// {
// return false;
// }
// oldSkill.SkillID = newSkillID;
// newSkill = oldSkill;
// SkillTemplate st = null;
// UnitSkill us = InitXmdsSkillScript(newSkill, ref st);
// if (us == null || st == null)
// {
// FormatLog(string.Format("XmdsVirtual.Skill can not find SkillScript {0},", newSkill.SkillID));
// return false;
// }
// mSkillMap.Remove(oldSkillID);
// mSkillMap.Add(newSkillID, newSkill);
// mActiveSkillTemplateMap.Remove(oldSkillID);
// mActiveSkillTemplateMap.Add(us.SkillID, st);
// for (int i = 0; i < mActiveSkills.Count; i++)
// {
// if (mActiveSkills[i].SkillID == oldSkillID)
// {
// mActiveSkills.RemoveAt(i);
// mActiveSkills.Add(us);
// break;
// }
// }
// #region 重置单位技能.
// List temp = new List();
// if (mActiveSkillTemplateMap.TryGetValue(newSkillID, out st))
// {
// //分辨出普通攻击.
// if (newSkill.SkillType == XmdsSkillType.normalAtk)
// {
// mBaseSkill = st;
// }
// else
// {
// temp.Add(st);
// }
// }
// if (temp.Count > 0 || mBaseSkill != null)
// {
// //重置技能.
// mOwner.mUnit.InitSkills(mBaseSkill, temp.ToArray());
// }
// // 人物, 宠物的技能是否自动释放走配置表
// if (mOwner is XmdsVirtual_Player || mOwner is XmdsVirtual_Pet)
// {
// SkillState skillState = mOwner.mUnit.getSkillState(newSkill.SkillID);
// if (skillState != null)
// {
// skillState.setAutoLaunch(newSkill.AutoLaunch);
// }
// }
// mOwner.SetSkillCD(st.ID, newSkill.SkillTimestampMS);
// mOwner.SetSkillCDDecreasePercent(st.ID, newSkill.SkillCDDecreasePercent);
// for (int i = 0; i < mActiveSkills.Count; i++)
// {
// if (mActiveSkills[i].SkillID == newSkillID)
// {
// mActiveSkills[i].InitOver(mOwner, newSkill);
// break;
// }
// }
// #endregion
// }
// catch (Exception error)
// {
// FormatLog(CommonLang.Log.LoggerLevel.ERROR, "单位【{0}】初始化技能错误:{1}", mOwner.mInfo.Name, error.ToString());
// return false;
// }
// return true;
//}
private UnitSkill InitXmdsSkillScript(GameSkill gs, ref SkillTemplate st)
{
UnitSkill us = null;
try
{
//获取技能脚本.
us = XmdsBattleSkill.GetUnitSkill(gs.SkillID);
//如果UnitSkill为NULL,则读取默认脚本.
if (us == null)
{
//FormatLog(CommonLang.Log.LoggerLevel.INFO, string.Format("单位{0}主动技能{1}未找到脚本,使用默认脚本代替", mOwner.mInfo.TemplateID, gs.SkillID));
us = XmdsBattleSkill.GetUnitSkill(XmdsBattleSkill.DefaultSkillScriptID);
// 宠物或者人物如果没有配置对应的技能文件,就设置为不自动释放技能
if (this.mOwner is XmdsVirtual_Pet || this.mOwner is XmdsVirtual_Player)
{
gs.AutoLaunch = false;
}
}
//主动技能特殊逻辑初始化.
st = XmdsBattleSkill.GetSkillTemplate(gs.SkillID);
if (st == null)
{
FormatLog(CommonLang.Log.LoggerLevel.ERROR, string.Format("未找到技能模板{0}", gs.SkillID));
}
//对技能进行脚本重铸.
us.Init(gs, mOwner, ref st);
}
catch (Exception err)
{
log.Error("InitXmdsSkillScript异常, 技能id" + gs.SkillID + ", 单位ID: " + mOwner.mInfo.TemplateID + ", e : " + err);
}
return us;
}
#endregion
#region 被动技能技能.
//初始化被动技能.
public void InitPassiveSkills(List skills)
{
try
{
if (skills == null || skills.Count == 0) { return; }
mPassiveSkills = new List();
UnitPassiveSkill sk = null;
for (int i = 0; i < skills.Count; i++)
{
if (mSkillMap.ContainsKey(skills[i].SkillID))
{
continue;
}
sk = InitXmdsPassiveSkillScript(skills[i]);
mSkillMap.Add(skills[i].SkillID, skills[i]);
mPassiveSkills.Add(sk);
SetPassiveSkillCD(sk, skills[i].SkillTimestampMS);
SetPassiveSkillCDDecrease(sk, skills[i].SkillCDDecreasePercent);
}
}
catch (Exception error)
{
FormatLog(CommonLang.Log.LoggerLevel.ERROR, "单位【{0}】初始化被动技能错误:{1}", mOwner.mInfo.Name, error.ToString());
}
}
private void SetPassiveSkillCD(UnitPassiveSkill sk, long timestamp)
{
int time = mOwner.CalSkillCDTime(timestamp);
//大于0代表还处于CD中.
if (time > 0 && time <= sk.GetCDTotalTime())
{
sk.SetCDPassTime(sk.GetCDTotalTime() - time);
}
}
private void SetPassiveSkillCDDecrease(UnitPassiveSkill sk, int timeMS)
{
if (sk != null)
{
int t = (int)(timeMS * 1.0f / XmdsDamageCalculator.PERER);
int oldt = sk.GetDecreaseTotalTimeMS();
int newt = oldt + t;
sk.SetDecreaseTotalTimeMS(newt);
}
}
//初始化被动技能脚本.
private UnitPassiveSkill InitXmdsPassiveSkillScript(GameSkill gs)
{
UnitPassiveSkill ret = null;
try
{
ret = XmdsBattleSkill.GetPassiveSkill(gs.SkillID);
if (ret == null)
{
throw new Exception("被动技能脚本未找到:" + this.mOwner.mUnit.PlayerUUID);
}
else
{
ret.Init(gs, mOwner);
}
}
catch (Exception err)
{
ThrowXmdsException(gs.SkillID, mOwner.mInfo.TemplateID, err.ToString());
}
return ret;
}
///
/// 报错方法.
///
///
///
///
private void ThrowXmdsException(int skill, int unit, string error)
{
string msg = string.Format("XmdsSkill Init Error id : SkillID = {0} UnitID = {1},Error = {2}", skill, unit, error.ToString());
log.Error(msg);
throw new Exception(msg);
}
//更新技能状态.
private void UpdatePassiveSkills(int intervalMS, bool slowRefresh)
{
if (mPassiveSkills != null)
{
for (int i = 0; i < mPassiveSkills.Count; i++)
{
mPassiveSkills[i].Update(intervalMS, slowRefresh);
}
}
}
private void UpdateActiveSkills(int intervalMS, bool slowRefresh)
{
if (mActiveSkills != null)
{
for (int i = 0; i < mActiveSkills.Count; i++)
{
UnitSkill skillInfo = mActiveSkills[i];
if (skillInfo == null || !skillInfo.IsActive)
{
continue;
}
skillInfo.Update(intervalMS, slowRefresh);
}
}
}
#endregion
#region 常用API.
///
/// 是否有该技能.
///
///
///
public bool ContainSkill(int id)
{
return mSkillMap.ContainsKey(id);
}
///
/// 获取技能信息.
///
///
///
public GameSkill GetGameSkill(int id)
{
GameSkill ret = null;
mSkillMap.TryGetValue(id, out ret);
return ret;
}
//获取玩家技能
public UnitSkill GetPlayerSkillById(int skillId)
{
if (mActiveSkills == null)
{
return null;
}
for (int i = 0; i < mActiveSkills.Count; i++)
{
if (mActiveSkills[i].SkillID == skillId)
{
return mActiveSkills[i];
}
}
return null;
}
//获取玩家技能
public UnitPassiveSkill GetPlayerSkillByIdExt(int skillId)
{
if (mPassiveSkills == null)
{
return null;
}
for (int i = 0; i < mPassiveSkills.Count; i++)
{
if (mPassiveSkills[i].SkillID == skillId)
{
return mPassiveSkills[i];
}
}
return null;
}
///
/// 获取主动技能模板.
///
///
///
public SkillTemplate GetUnitSkillTemplate(int id)
{
SkillTemplate ret = null;
mActiveSkillTemplateMap.TryGetValue(id, out ret);
return ret;
}
public void RemoveSkill(CommonAI.Zone.Instance.InstanceUnit.SkillState sk)
{
if (mSkillMap != null)
{
GameSkill gs = null;
if (mSkillMap.TryGetValue(sk.ID, out gs))
{
mOwner.RemoveEventBySkillID(gs.SkillID);
mSkillMap.Remove(sk.ID);
}
for (int i = 0; i < mActiveSkills.Count; i++)
{
if (mActiveSkills[i].SkillID == sk.ID)
{
mActiveSkills.RemoveAt(i);
break;
}
}
}
if (mActiveSkillTemplateMap != null)
{
mActiveSkillTemplateMap.RemoveByKey(sk.ID);
mActiveSkillTemplateMap.Remove(sk.ID);
}
}
public void Update(int intervalMS, bool slowRefresh)
{
UpdatePassiveSkills(intervalMS, slowRefresh);
//2021.11.02优化:主动技能慢刷新,打开需要注明原因
if(slowRefresh)
{
UpdateActiveSkills(intervalMS, slowRefresh);
}
}
public int GetBaseSkillID()
{
if (mBaseSkill != null)
{
return mBaseSkill.ID;
}
return 0;
}
///
/// 增加技能.
///
///
public void AddSkill(List list)
{
if (list != null && list.Count > 0)
{
List active = new List();
List passive = new List();
GetActivePassiveSkillList(list, ref active, ref passive);
GameSkill gs = null;
//主动技能.
for (int i = 0; i < active.Count; i++)
{
gs = active[i];
AddActiveSkill(gs);
}
for (int i = 0; i < passive.Count; i++)
{
gs = passive[i];
AddPassiveSkill(gs);
}
}
}
public UnitSkill AddActiveSkill(GameSkill gs, bool is_default = false)
{
SkillTemplate st = null;
UnitSkill us = null;
//存放技能等级信息.
mSkillMap.Put(gs.SkillID, gs);
us = InitXmdsSkillScript(gs, ref st);
if (st != null)
{
if (mActiveSkillTemplateMap == null)
{
mActiveSkillTemplateMap = new HashMap();
}
mActiveSkillTemplateMap.Put(st.ID, st);
//us = XmdsBattleSkill.GetUnitSkill(gs.SkillID);
mOwner.mUnit.AddSkill(st, gs.AutoLaunch, is_default);
SkillState skillState = mOwner.SetSkillCD(gs.SkillID, gs.SkillTimestampMS);
mOwner.SetSkillCDDecreasePercent(gs.SkillID, gs.SkillCDDecreasePercent);
if (skillState != null)
{
skillState.Reset(true);
}
if (us != null)
{
mActiveSkills.Add(us);
us.InitOver(mOwner, gs);
}
}
return us;
}
public UnitPassiveSkill AddPassiveSkill(GameSkill gs)
{
UnitPassiveSkill ups = InitXmdsPassiveSkillScript(gs);
mSkillMap.Put(gs.SkillID, gs);
SetPassiveSkillCD(ups, gs.SkillTimestampMS);
SetPassiveSkillCDDecrease(ups, gs.SkillCDDecreasePercent);
if (mPassiveSkills == null)
{
mPassiveSkills = new List();
}
mPassiveSkills.Add(ups);
ups.InitOver(mOwner, gs);
return ups;
}
///
/// 减少技能.
///
///
public void RemoveSkill(List list)
{
if (list != null && list.Count > 0)
{
List active = new List();
List passive = new List();
GetActivePassiveSkillList(list, ref active, ref passive);
GameSkill gs = null;
//主动技能.
for (int i = 0; i < active.Count; i++)
{
gs = active[i];
RemoveActiveSkill(gs.SkillID);
}
//删除被动技能.
for (int i = 0; i < passive.Count; i++)
{
if (mSkillMap.TryGetValue(passive[i].SkillID, out gs))
{
RemovePassiveSkill(gs.SkillID);
}
}
}
}
public void RemoveActiveSkill(int skillID)
{
if (mBaseSkill != null && skillID == mBaseSkill.ID)
{
mBaseSkill = null;
}
mOwner.mUnit.RemoveSkill(skillID); //调用该API收到remove事件再删除技能.
}
public void RemovePassiveSkill(int skillID)
{
mSkillMap.RemoveByKey(skillID);
for (int k = 0; k < mPassiveSkills.Count; k++)
{
if (mPassiveSkills[k].SkillID == skillID)
{
mPassiveSkills[k].Dispose(mOwner);
mPassiveSkills.RemoveAt(k);
mOwner.RemoveEventBySkillID(skillID);
break;
}
}
}
///
/// 初始化技能.
///
///
private void InitSkill(List list)
{
List active = new List();
List passive = new List();
if (list.Count == 0)
{
return;
}
else if (this.mOwner.mUnit.IsPlayer)
{
//玩家有一些特殊的逻辑放到天赋被动里面
}
GetActivePassiveSkillList(list, ref active, ref passive);
InitPassiveSkills(passive);
InitActiveSkills(active);
//通知技能,初始化完成
notifyActiveSkillInitOver(active);
notifyPassiveSkillInitOver(passive);
this.mOwner.InitCardModule();
}
///
/// 重置技能.
///
///
public void ResetSkill(List list, XmdsVirtual owner)
{
//1清除所有技能.
ClearSkill();
if (mSkillMap == null)
{
mSkillMap = new HashMap();
}
mOwner = owner;
//2重新初始化技能.
InitSkill(list);
}
public void ReplaceSkill(List list)
{
if (list == null) { return; }
GameSkill gs = null;
GameSkill new_gs = null;
for (int i = 0; i < list.Count; i++)
{
new_gs = list[i];
gs = null;
mSkillMap.TryGetValue(new_gs.SkillID, out gs);
if (gs != null)
{
gs.SkillLevel = new_gs.SkillLevel;
gs.TalentSkillLevel1 = new_gs.TalentSkillLevel1;
gs.TalentSkillLevel2 = new_gs.TalentSkillLevel2;
gs.TalentSkillLevel3 = new_gs.TalentSkillLevel3;
if (gs.SkillType == XmdsSkillType.passive)
{
if (mPassiveSkills != null)
{
for (int k = 0; k < mPassiveSkills.Count; k++)
{
if (mPassiveSkills[k].SkillID == gs.SkillID)
{
//去除原有CD修改值.
SetPassiveSkillCDDecrease(mPassiveSkills[k], -gs.SkillCDDecreasePercent);
//重新设置CD修改值.
SetPassiveSkillCDDecrease(mPassiveSkills[k], new_gs.SkillCDDecreasePercent);
//技能效果变化.
mPassiveSkills[k].SkillDataChange(gs, mOwner);
}
}
}
}
else
{
//去除原有CD修改值.
mOwner.SetSkillCDDecreasePercent(gs.SkillID, -gs.SkillCDDecreasePercent);
//重新设置CD修改值.
mOwner.SetSkillCDDecreasePercent(new_gs.SkillID, new_gs.SkillCDDecreasePercent);
for (int k = 0; k < mActiveSkills.Count; k++)
{
if (mActiveSkills[k].SkillID == new_gs.SkillID)
{
mActiveSkills[k].SkillDataChange(new_gs, mOwner);
break;
}
}
}
gs.SkillCDDecreasePercent = new_gs.SkillCDDecreasePercent;
}
}
}
///
/// 清理技能.
///
public void ClearSkill()
{
List ret = new List();
GameSkill g = null;
if (mSkillMap != null)
{
foreach (KeyValuePair pair in mSkillMap)
{
g = new GameSkill();
g.SkillID = pair.Key;
g.SkillType = pair.Value.SkillType;
ret.Add(g);
}
RemoveSkill(ret);
}
}
public void Dispose()
{
ClearSkill();
mBaseSkill = null;
if (mSkillMap != null)
{
mSkillMap.Clear();
mSkillMap = null;
}
if (mActiveSkillTemplateMap != null)
{
mActiveSkillTemplateMap.Clear();
mActiveSkillTemplateMap = null;
}
if (mPassiveSkills != null)
{
mPassiveSkills.Clear();
mPassiveSkills = null;
}
mOwner = null;
}
#endregion
#region 特殊硬编码技能.
#endregion
}
///
/// 技能状态信息.
///
public class XmdsSkillStatusData
{
///
/// 技能(技能ID,到期时间戳).
/// .
public HashMap SkillTimestampMSMap = null;
}
//-----------------------职业天赋相关的接口-----------------------
public virtual IPlayerCache GetPlayerCache()
{
return this.mPlayerCache;
}
public virtual void SetPlayerCache(IPlayerCache cache)
{
this.mPlayerCache = cache;
}
public virtual void Talent__Add(int value)
{
if (this.mPlayerCache != null)
{
this.mPlayerCache.AddTalentValue(value);
}
}
public virtual bool Talent_Use(int value)
{
if (this.mPlayerCache != null)
{
return this.mPlayerCache.UseTalentValue(value);
}
return false;
}
public virtual int Talent_Value()
{
return mPlayerCache == null ? 0 : mPlayerCache.GetTalentValue();
}
public virtual int Talent_Lv()
{
return mPlayerCache == null ? 0 : mPlayerCache.GetTalentLv();
}
public virtual bool Talent_Refresh(bool notify = true)
{
if (this.mPlayerCache != null)
{
return this.mPlayerCache.Refresh(notify);
}
return false;
}
//---------------------------------------------------------------------
#region BUFF跨场景.
/*
///
/// BUFF信息集合.
///
public class XmdsBuffStatus
{
public List mDatas = null;
}
///
/// Buff状态信息.
///
public class XmdsBuffStatusData
{
///
/// BUFF模板.
///
public int BuffTemplateID = 0;
///
/// BUFF时间戳.
///
public long BuffTimestampMS = 0;
}
*/
#endregion
#region 技能API测试功能.
protected void Mock_RemoveSkill(int skillID)
{
PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B();
evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Remove;
List list = new List();
GameSkill gs = new GameSkill();
gs.SkillID = skillID;
list.Add(gs);
evt.SkillList = list;
OnPlayerSkillsChanged(evt);
}
protected void Mock_AddSkill(int skillID)
{
PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B();
evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Add;
List list = new List();
GameSkill gs = new GameSkill();
gs.SkillID = skillID;
gs.SkillLevel = 1;
gs.SkillType = XmdsSkillType.active;
list.Add(gs);
evt.SkillList = list;
OnPlayerSkillsChanged(evt);
}
protected void Mock_ResetSkill(List list)
{
PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B();
evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Reset;
evt.SkillList = list;
OnPlayerSkillsChanged(evt);
}
protected void Mock_ReplaceSkill(List list)
{
PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B();
evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Replace;
evt.SkillList = list;
OnPlayerSkillsChanged(evt);
}
#endregion
}
}