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
//--------------------------------------------------------------------------------------------
}
}