using System; using System.Collections.Generic; using System.Text; using CommonLang.Log; using System.Xml; using System.IO; using CommonAI.Zone.ZoneEditor; using CommonLang.Concurrent; using CommonLang; using CommonAI.Zone.UnitTriggers; using CommonAI.Zone.Instance; using CommonLang.XCSV; using static CommonAI.Zone.Instance.InstanceUnit; using CommonAI.Data; using CommonAI.Zone.Helper; namespace CommonAI.Zone.Formula { public class AttackSource { /// /// 攻击属性. /// public readonly AttackProp Attack; /// /// 技能模板. /// public readonly SkillTemplate FromSkill; /// /// 法术模板. /// public readonly SpellTemplate FromSpell; /// /// BUFF模板. /// public readonly BuffTemplate FromBuff; /// /// 技能实际状态. /// public readonly InstanceUnit.SkillState FromSkillState; /// /// BUFF实际状态. /// public readonly InstanceUnit.BuffState FromBuffState; /// /// 法术实际状态. /// public readonly InstanceSpell FromSpellUnit; /// /// 如果是技能产生的伤害,就是该技能的类型(就算是法术,也要追根到技能) /// public readonly XmdsSkillType FromSkillType = XmdsSkillType.none; /// /// 是否发送协议 /// public bool OutSendEvent = true; /// /// 是否命中 /// public bool OutHitted; /// /// 是否产生硬直. /// public bool OutIsDamage; /// /// 是否击溃. /// public bool OutIsCrush; /// /// 是否击飞. /// public bool OutHasFly; /// /// 是否击倒. /// public bool OutHasKnockDown; /// /// 击倒时间. /// public int OutKnockDownTimeMS; /// /// 打击特效. /// public LaunchEffect OutHitEffect; public float OutWeight; public StartMove OutHitMove; /// /// 扩展模块用于特殊计算. /// public object OutExtendsResult; /// /// 用于表示攻击特殊状态:招架、闪避、反伤, UnitHitEventState /// public byte OutClientState; public int OutClientStateExt; // 特殊逻辑 public int ignoreDef; // 技能或者法术的一次ATTACK是否有击中,只有有一个击中也算 private bool hasHitted; public bool HasHitted { get { return hasHitted; } set { if(value && !hasHitted) { callHitTarget(); } hasHitted = value; } } public AttackSource(InstanceUnit.SkillState skill, AttackProp attack) { this.Attack = attack; this.FromSkill = skill.Data; this.FromSkillState = skill; this.FromSpell = null; this.FromSpellUnit = null; this.FromBuff = null; this.FromBuffState = null; this.FromSkillType = skill.GetSkillType(); } public AttackSource(InstanceUnit.BuffState buff, AttackProp attack) { this.Attack = attack; this.FromSkill = null; this.FromSkillState = null; this.FromSpell = null; this.FromSpellUnit = null; this.FromBuff = buff.Data; this.FromBuffState = buff; } public AttackSource(InstanceSpell spell, AttackProp attack) { this.Attack = attack; this.FromSkill = null; this.FromSkillState = null; this.FromSpell = spell.Info; this.FromSpellUnit = spell; this.FromBuff = null; this.FromBuffState = null; this.FromSkillType = spell.FromSkillType; } public void Begin(InstanceUnit target) { this.OutIsCrush = CUtils.RandomPercent(target.RandomN, Attack.CrushPercent); this.OutHitEffect = Attack.Effect; this.OutWeight = (Attack.Weight - target.Weight); this.OutIsDamage = (OutWeight > 0) && (Attack.MaskDamage) && (!target.IsNoneBlock); this.OutHitted = true; if (OutIsDamage) { this.OutHasFly = Attack.MaskHitFly; this.OutHasKnockDown = Attack.MaskKnockDown; this.OutKnockDownTimeMS = Attack.KnockOutTimeMS; this.OutHitMove = Attack.HitMove; } else { this.OutHasFly = false; this.OutHasKnockDown = false; this.OutKnockDownTimeMS = 0; this.OutHitMove = null; } if (this.FromSpellUnit != null && this.FromSpellUnit.ChainInfo != null) { this.FromSpellUnit.ChainInfo.AddTarget(target); } } public ITemplateData Weapon { get { if (FromSkill != null) { return FromSkill; } if (FromSpell != null) { return FromSpell; } if (FromBuff != null) { return FromBuff; } return null; } } public AttackSource GenAttackSource(AttackProp attack) { if (FromSkillState != null) { return new AttackSource(this.FromSkillState, attack); } if (FromBuffState != null) { return new AttackSource(this.FromBuffState, attack); } if (FromSpellUnit != null) { return new AttackSource(this.FromSpellUnit, attack); } return null; } public SkillTemplate.CastTarget FromExpectTarget { get { if (FromSkill != null) { return FromSkill.ExpectTarget; } if (FromSpell != null) { return FromSpell.ExpectTarget; } return SkillTemplate.CastTarget.NA; } } public void callHitTarget() { InstanceUnit attacker = null; if (FromSkillState != null) { attacker = FromSkillState.Owner; } else if (FromSpellUnit !=null) { attacker = FromSpellUnit.Launcher; } if (attacker != null) attacker.onSkillHitTarget(); } } public interface IVirtualUnit { void OnInit(InstanceUnit owner, bool pointLv); void OnDispose(InstanceUnit owner); bool ChangeSkill(int oldSkillID, int newSkillID, SkillLevelData data); //设置战斗属性 void SyncBattlePropsFields(ulong mask); ///////////////////////////////////////////////////////////////////////////// //玩家的一些接口暴露给comAI //是否是PVP, PVE状态 BattleStatus GetBattleStatus(); int GetInventorySize(); bool IsInPVP(); bool IsInPVE(); //设置玩家战斗状态 void SetCombatState(BattleStatus value, byte reason = 0); //是否是队友 bool IsAllies(IVirtualUnit target, bool includeSelf = true, bool onlyForTeam = false); //Instance行为调用virtual void doEvent(JSGCustomOpType type); void TakeOffMount(); void SendMsgToClient(string msg); void SendMsgToPlayer(ObjectEvent evt, bool force = false); //获取阵营id int GetForceID(); //获取工会id string GetGuildID(); //是否是工会成员 bool IsGuildMember(string id); //获取pk等级 PKLevel GetCurPKLevel(); //是否是同服务器 bool IsServerMember(int id); //获取服务器id int GetServerID(); //获取基础技能id int GetBaseSkillID(); /** 获取PK模式 */ PKMode GetCurPKMode(); /** 获得被治疗效果 */ int GetHealedEffect(); /** 获得治疗效果 */ int GetHealEffect(); /** 获得单位职业 */ XmdsUnitPro GetUnitPro(); //性别: 0-男,1-女 int GetUnitSex(); /** 获得宠物天赋加成 */ int GetPetTalentAddition(UnitFateType type); /** 获得单位天赋 */ UnitFateType GetUnitFateType(); bool LaunchSkillCheckTalentInfo(InstanceUnit.SkillState skill); /** 分发技能被打断事件(暂时只有移动) */ void DispatchSkillBlockEvent(InstanceUnit.StateSkill skill, InstanceUnit.State newState); /** 分发加血事件 */ void DispatchAddOtherHPEvent(int hp, InstanceUnit sender, out int finalHP); /** 分发扣定力时间 */ void DispatchAddMPEvent(int mp, InstanceUnit sender, out int finalMP, AttackSource source); /** 分发法术释放完毕 */ void DispatchSendSpellOverEvent(LaunchSpell launch, SpellTemplate spt, float startX, float startY); /** 设置技能可用性 */ void SetSkillActive(int skillTemplateID, bool active, bool pause_on_deactive = false); ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// //怪物的一些接口暴露给comAI int GetMaType(); bool IsBoss(); uint GetMasterID(); InstanceUnit GetMasterUnit(); void StartRecoverMP(bool reset = false); bool IsCanReduceMP(bool force); //获取玩家宠物接口 InstanceUnit GetPetUnit(); } public interface IVirtualClientUnit { void OnInit(ZoneClient.ZoneUnit owner); void OnDispose(ZoneClient.ZoneUnit owner); } public abstract class IFormula { //-------------------------------------------------------------------------------------------- #region SYSTEM /// /// 绑定日志系统 /// /// public virtual void BindLogger(Logger log) { } /// /// 游戏加载初始化 /// /// public virtual void InitPluginsData(EditorTemplates data_root) { } /// /// 编辑器保存时 /// /// /// /// /// public virtual void OnEditorSaving(EditorTemplatesData datas, DirectoryInfo data_root, List savedfiles, AtomicFloat progress_percent) { } /// /// 列出所有需要转换的XLS文件 /// /// /// public virtual void ListXCSVFiles(DirectoryInfo data_root, List xls_files) { } /// /// 编辑器xls目录保存时 /// /// /// /// /// public virtual void OnEditorPluginSaved(ZoneEditor.EditorTemplatesData datas, List xls2csv, List savedfiles, AtomicFloat progress_percent) { } #endregion //-------------------------------------------------------------------------------------------- #region HIT_AND_DAMAGE public virtual int OnHit(InstanceUnit attacker, AttackSource attack, InstanceUnit targget) { return attack.Attack.Attack; } public virtual void OnUnitDead(InstanceUnit targget, InstanceUnit killer) { } public virtual void OnUnitRemoved(InstanceUnit unit) { } public virtual bool TryLaunchSkill(InstanceUnit attacker, InstanceUnit.SkillState skill, ref InstanceUnit.LaunchSkillParam param) { return true; } public virtual bool TriggerPetSkill(InstanceUnit attacker, InstanceUnit.SkillState skill, ref InstanceUnit.LaunchSkillParam param) { return true; } public virtual bool TryResetSkill(InstanceUnit owner) { return true; } public virtual bool TryLaunchSpell(InstanceUnit launcher, LaunchSpell launch, ref SpellTemplate spell, out JSGCreateSpellData createData, ref float startX, ref float startY) { createData = null; return true; } public virtual bool TryAddBuff(InstanceUnit owner, InstanceUnit sender, ref BuffTemplate buff, out object tag) { tag = null; return true; } public virtual bool TryLaunchTrigger(InstanceUnit owner, UnitTriggerTemplate trigger, UnitTriggers.BaseTriggerEvent evt, AttackSource source) { return true; } public virtual bool TrySummonUnit(InstanceUnit owner, SummonUnit summon, ref UnitInfo summonUnit, ref string name) { return true; } public virtual bool TryUseItem(InstanceUnit owner, ItemTemplate item, InstanceUnit item_creater) { return true; } public virtual void SendAddBuffEvent(InstanceUnit owner, InstanceUnit sender, BuffTemplate buff) {} #endregion //-------------------------------------------------------------------------------------------- #region STATUS public virtual void OnTriggerStart(InstanceUnit unit, InstanceUnit.TriggerState trigger, InstanceUnit target) { } public virtual void OnUpdateTriggerSkill(InstanceUnit unit, int intervalMS, bool slowRefresh) { } public virtual void OnBuffBegin(InstanceUnit unit, InstanceUnit.BuffState buff, InstanceUnit sender) { } public virtual void OnBuffUpdate(InstanceUnit unit, InstanceUnit.BuffState buff, int time) { } public virtual void OnBuffEnd(InstanceUnit unit, InstanceUnit.BuffState buff, string result, bool replace) { } public virtual void OnGotInventoryItem(InstanceUnit unit, ItemTemplate item) { } public virtual void OnLostInventoryItem(InstanceUnit unit, ItemTemplate item) { } public virtual void OnUseItem(InstanceUnit unit, ItemTemplate item, InstanceUnit item_creater) { } #endregion //-------------------------------------------------------------------------------------------- #region NET public virtual void OnZoneHandleNetMessage(InstanceZone zone, Action action) { } public virtual void OnUnitHandleNetMessage(InstanceUnit unit, ObjectAction action) { } #endregion //-------------------------------------------------------------------------------------------- } }