mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-06-12 23:44:34 +02:00
Combat additions
Added formulas for base EXP gain and chain experience Added basic scripts for most player abilities and effects Added stat gains for some abilities Changed status flags Fixed bug with player death Fixed bug where auto attacks didnt work when not locked on Added traits
This commit is contained in:
parent
b8d6a943aa
commit
c5ce2ec771
239 changed files with 5125 additions and 1237 deletions
|
@ -117,7 +117,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
|
||||
public Pet pet;
|
||||
|
||||
private Dictionary<Modifier, Int64> modifiers = new Dictionary<Modifier, long>();
|
||||
private Dictionary<Modifier, double> modifiers = new Dictionary<Modifier, double>();
|
||||
|
||||
protected ushort hpBase, hpMaxBase, mpBase, mpMaxBase, tpBase;
|
||||
protected BattleTemp baseStats = new BattleTemp();
|
||||
|
@ -191,6 +191,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
zone.BroadcastPacketsAroundActor(this, propPacketUtil.Done());
|
||||
}
|
||||
|
||||
//This logic isn't correct, order of GetStatusEffects() is not necessarily the same as the actual effects in game. Also sending every time at once isn't needed
|
||||
public List<SubPacket> GetActorStatusPackets()
|
||||
{
|
||||
var propPacketUtil = new ActorPropertyPacketUtil("charaWork/status", this);
|
||||
|
@ -260,7 +261,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
|
||||
public void DoBattleAction(ushort commandId, uint animationId, List<BattleAction> actions)
|
||||
{
|
||||
int currentIndex = 0;
|
||||
int currentIndex = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -275,7 +276,11 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
}
|
||||
else
|
||||
break;
|
||||
animationId = 0; //If more than one packet is sent out, only send the animation once to avoid double playing.
|
||||
|
||||
//Sending multiple packets at once causes some issues. Setting any combination of these to zero changes what breaks
|
||||
//animationId = 0; //If more than one packet is sent out, only send the animation once to avoid double playing.
|
||||
//commandId = 0;
|
||||
//sourceActorId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,20 +296,51 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
PathTo(target.positionX, target.positionY, target.positionZ, stepSize, maxPath, radius);
|
||||
}
|
||||
|
||||
public Int64 GetMod(uint modifier)
|
||||
public double GetMod(Modifier modifier)
|
||||
{
|
||||
Int64 res;
|
||||
return GetMod((uint)modifier);
|
||||
}
|
||||
|
||||
public double GetMod(uint modifier)
|
||||
{
|
||||
double res;
|
||||
if (modifiers.TryGetValue((Modifier)modifier, out res))
|
||||
return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void SetMod(uint modifier, Int64 val)
|
||||
public void SetMod(uint modifier, double val)
|
||||
{
|
||||
if (modifiers.ContainsKey((Modifier)modifier))
|
||||
modifiers[(Modifier)modifier] = val;
|
||||
else
|
||||
modifiers.Add((Modifier)modifier, val);
|
||||
|
||||
if (modifier <= 35)
|
||||
updateFlags |= ActorUpdateFlags.Stats;
|
||||
}
|
||||
|
||||
public void AddMod(Modifier modifier, double val)
|
||||
{
|
||||
AddMod((uint)modifier, val);
|
||||
}
|
||||
|
||||
public void AddMod(uint modifier, double val)
|
||||
{
|
||||
|
||||
double newVal = GetMod(modifier) + val;
|
||||
SetMod(modifier, newVal);
|
||||
}
|
||||
|
||||
public void SubtractMod(Modifier modifier, double val)
|
||||
{
|
||||
AddMod((uint)modifier, val);
|
||||
}
|
||||
|
||||
public void SubtractMod(uint modifier, double val)
|
||||
{
|
||||
double newVal = GetMod(modifier) - val;
|
||||
SetMod(modifier, newVal);
|
||||
}
|
||||
|
||||
public virtual void OnPath(Vector3 point)
|
||||
|
@ -341,6 +377,21 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
//DoBattleAction(21001, 0x7C000062, new BattleAction(this.actorId, 0, 1, 0, 0, 1)); //Attack Mode
|
||||
}
|
||||
|
||||
if ((updateFlags & ActorUpdateFlags.Status) != 0)
|
||||
{
|
||||
List<SubPacket> statusPackets = statusEffects.GetStatusPackets();
|
||||
packets.AddRange(statusPackets);
|
||||
statusPackets.Clear();
|
||||
updateFlags &= ~ActorUpdateFlags.Status;
|
||||
}
|
||||
|
||||
if ((updateFlags & ActorUpdateFlags.StatusTime) != 0)
|
||||
{
|
||||
packets.AddRange(statusEffects.GetStatusTimerPackets());
|
||||
updateFlags &= ~ActorUpdateFlags.StatusTime;
|
||||
|
||||
}
|
||||
|
||||
if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0)
|
||||
{
|
||||
var propPacketUtil = new ActorPropertyPacketUtil("charaWork/stateAtQuicklyForAll", this);
|
||||
|
@ -351,6 +402,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
propPacketUtil.AddProperty("charaWork.parameterTemp.tp");
|
||||
packets.AddRange(propPacketUtil.Done());
|
||||
}
|
||||
|
||||
base.PostUpdate(tick, packets);
|
||||
}
|
||||
}
|
||||
|
@ -393,11 +445,12 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
public virtual bool Engage(uint targid = 0, ushort newMainState = 0xFFFF)
|
||||
{
|
||||
// todo: attack the things
|
||||
if (newMainState != 0xFFFF)
|
||||
/*if (newMainState != 0xFFFF)
|
||||
{
|
||||
this.newMainState = newMainState;
|
||||
currentMainState = newMainState;// this.newMainState = newMainState;
|
||||
updateFlags |= ActorUpdateFlags.State;
|
||||
}
|
||||
else if (aiContainer.CanChangeState())
|
||||
else*/ if (aiContainer.CanChangeState())
|
||||
{
|
||||
if (targid == 0)
|
||||
{
|
||||
|
@ -423,11 +476,12 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
|
||||
public virtual bool Disengage(ushort newMainState = 0xFFFF)
|
||||
{
|
||||
if (newMainState != 0xFFFF)
|
||||
/*if (newMainState != 0xFFFF)
|
||||
{
|
||||
this.newMainState = newMainState;
|
||||
currentMainState = newMainState;// this.newMainState = newMainState;
|
||||
updateFlags |= ActorUpdateFlags.State;
|
||||
}
|
||||
else if (IsEngaged())
|
||||
else*/ if (IsEngaged())
|
||||
{
|
||||
aiContainer.Disengage();
|
||||
return true;
|
||||
|
@ -463,7 +517,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
RecalculateStats();
|
||||
}
|
||||
|
||||
public virtual void Die(DateTime tick)
|
||||
//AdditionalActions is the list of actions that EXP/Chain messages are added to
|
||||
public virtual void Die(DateTime tick, BattleActionContainer actionContainer = null)
|
||||
{
|
||||
// todo: actual despawn timer
|
||||
aiContainer.InternalDie(tick, 10);
|
||||
|
@ -523,7 +578,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
|
||||
public byte GetHPP()
|
||||
{
|
||||
return (byte)(charaWork.parameterSave.hp[0] == 0 ? 0 : (charaWork.parameterSave.hp[0] / charaWork.parameterSave.hpMax[0]) * 100);
|
||||
return (byte)(charaWork.parameterSave.hp[0] == 0 ? 0 : (charaWork.parameterSave.hp[0] / (float) charaWork.parameterSave.hpMax[0]) * 100);
|
||||
}
|
||||
|
||||
public void SetHP(uint hp)
|
||||
|
@ -558,8 +613,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
// todo: the following functions are virtuals since we want to check hidden item bonuses etc on player for certain conditions
|
||||
public virtual void AddHP(int hp)
|
||||
{
|
||||
// dont wanna die ded
|
||||
if (IsAlive())
|
||||
// dont wanna die ded, don't want to send update if hp isn't actually changed
|
||||
if (IsAlive() && hp != 0)
|
||||
{
|
||||
// todo: +/- hp and die
|
||||
// todo: battlenpcs probably have way more hp?
|
||||
|
@ -567,9 +622,6 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
addHp = addHp.Clamp((short)GetMod((uint)Modifier.MinimumHpLock), charaWork.parameterSave.hpMax[0]);
|
||||
charaWork.parameterSave.hp[0] = (short)addHp;
|
||||
|
||||
if (charaWork.parameterSave.hp[0] < 1)
|
||||
Die(Program.Tick);
|
||||
|
||||
updateFlags |= ActorUpdateFlags.HpTpMp;
|
||||
}
|
||||
}
|
||||
|
@ -586,18 +638,24 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
|
||||
public void AddMP(int mp)
|
||||
{
|
||||
charaWork.parameterSave.mp = (short)(charaWork.parameterSave.mp + mp).Clamp(ushort.MinValue, charaWork.parameterSave.mpMax);
|
||||
if (IsAlive() && mp != 0)
|
||||
{
|
||||
charaWork.parameterSave.mp = (short)(charaWork.parameterSave.mp + mp).Clamp(ushort.MinValue, charaWork.parameterSave.mpMax);
|
||||
|
||||
// todo: check hidden effects and shit
|
||||
// todo: check hidden effects and shit
|
||||
|
||||
updateFlags |= ActorUpdateFlags.HpTpMp;
|
||||
updateFlags |= ActorUpdateFlags.HpTpMp;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddTP(int tp)
|
||||
{
|
||||
if (IsAlive())
|
||||
if (IsAlive() && tp != 0)
|
||||
{
|
||||
charaWork.parameterTemp.tp = (short)((charaWork.parameterTemp.tp + tp).Clamp(0, 3000));
|
||||
var addTp = charaWork.parameterTemp.tp + tp;
|
||||
|
||||
addTp = addTp.Clamp((int) GetMod(Modifier.MinimumTpLock), 3000);
|
||||
charaWork.parameterTemp.tp = (short) addTp;
|
||||
tpBase = (ushort)charaWork.parameterTemp.tp;
|
||||
updateFlags |= ActorUpdateFlags.HpTpMp;
|
||||
|
||||
|
@ -661,12 +719,12 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
//CalculateBaseStats();
|
||||
}
|
||||
|
||||
public void SetStat(uint statId, uint val)
|
||||
public void SetStat(uint statId, int val)
|
||||
{
|
||||
charaWork.battleTemp.generalParameter[statId] = (ushort)val;
|
||||
charaWork.battleTemp.generalParameter[statId] = (short)val;
|
||||
}
|
||||
|
||||
public ushort GetStat(uint statId)
|
||||
public short GetStat(uint statId)
|
||||
{
|
||||
return charaWork.battleTemp.generalParameter[statId];
|
||||
}
|
||||
|
@ -674,7 +732,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
public virtual float GetSpeed()
|
||||
{
|
||||
// todo: for battlenpc/player calculate speed
|
||||
return GetMod((uint)Modifier.Speed);
|
||||
return (float) GetMod((uint)Modifier.Speed);
|
||||
}
|
||||
|
||||
public virtual void OnAttack(State state, BattleAction action, ref BattleAction error)
|
||||
|
@ -688,7 +746,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
}
|
||||
|
||||
// todo: call onAttack/onDamageTaken
|
||||
BattleUtils.DamageTarget(this, target, action, DamageTakenType.Attack);
|
||||
//BattleUtils.DamageTarget(this, target, DamageTakenType.Attack, action);
|
||||
AddTP(200);
|
||||
target.AddTP(100);
|
||||
}
|
||||
|
@ -704,7 +762,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
if (zone.FindActorInArea<Character>(action.targetId) is Character chara)
|
||||
{
|
||||
//BattleUtils.HandleHitType(this, chara, action);
|
||||
BattleUtils.DoAction(this, chara, action, DamageTakenType.Magic);
|
||||
//BattleUtils.DoAction(this, chara, action, DamageTakenType.Magic);
|
||||
}
|
||||
}
|
||||
lua.LuaEngine.GetInstance().OnSignal("spellUsed");
|
||||
|
@ -719,14 +777,11 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
//Should we just store the character insteado f having to find it again?
|
||||
if (zone.FindActorInArea<Character>(action.targetId) is Character chara)
|
||||
{
|
||||
BattleUtils.DoAction(this, chara, action, DamageTakenType.Weaponskill);
|
||||
//BattleUtils.DoAction(this, chara, action, DamageTakenType.Weaponskill);
|
||||
}
|
||||
}
|
||||
|
||||
this.DelTP(skill.tpCost);
|
||||
//Do procs reset on weaponskills?
|
||||
ResetProcs();
|
||||
lua.LuaEngine.GetInstance().OnSignal("weaponskillUsed");
|
||||
}
|
||||
|
||||
public virtual void OnAbility(State state, BattleAction[] actions, BattleCommand ability, ref BattleAction[] errors)
|
||||
|
@ -735,7 +790,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
{
|
||||
if (zone.FindActorInArea<Character>(action.targetId) is Character chara)
|
||||
{
|
||||
BattleUtils.DoAction(this, chara, action, DamageTakenType.Ability);
|
||||
//BattleUtils.DoAction(this, chara, action, DamageTakenType.Ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -755,9 +810,55 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
|
||||
}
|
||||
|
||||
public virtual void OnDamageTaken(Character attacker, BattleAction action, DamageTakenType damageTakenType)
|
||||
public virtual void OnDamageDealt(Character defender, BattleAction action, BattleActionContainer actionContainer = null)
|
||||
{
|
||||
switch (action.hitType)
|
||||
{
|
||||
case (HitType.Miss):
|
||||
OnMiss(this, action, actionContainer);
|
||||
break;
|
||||
default:
|
||||
OnHit(defender, action, actionContainer);
|
||||
break;
|
||||
}
|
||||
|
||||
//TP is only gained from autoattacks and abilities
|
||||
if (action.commandType == CommandType.AutoAttack || action.commandType == CommandType.Ability)
|
||||
{
|
||||
//TP gained on an attack is usually 100 * delay.
|
||||
//Store TP seems to add .1% per point.
|
||||
double weaponDelay = GetMod(Modifier.AttackDelay) / 1000.0;
|
||||
var storeTPPercent = 1 + (GetMod(Modifier.StoreTP) * 0.1);
|
||||
AddTP((int)(weaponDelay * 100 * storeTPPercent));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnDamageTaken(Character attacker, BattleAction action, BattleActionContainer actionContainer = null)
|
||||
{
|
||||
switch (action.hitType)
|
||||
{
|
||||
case (HitType.Miss):
|
||||
OnEvade(attacker, action, actionContainer);
|
||||
break;
|
||||
case (HitType.Parry):
|
||||
OnParry(attacker, action, actionContainer);
|
||||
break;
|
||||
case (HitType.Block):
|
||||
OnBlock(attacker, action, actionContainer);
|
||||
break;
|
||||
}
|
||||
|
||||
statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnDamageTaken, "onDamageTaken", attacker, this, action);
|
||||
|
||||
//TP gain formula seems to be something like 5 * e ^ ( -0.667 * [defender's level] ) * damage taken, rounded up
|
||||
//This should be completely accurate at level 50, but isn't totally accurate at lower levels.
|
||||
//Don't know if store tp impacts this
|
||||
double tpModifier = 5 * Math.Pow(Math.E, (-0.0667 * GetLevel()));
|
||||
AddTP((int)Math.Ceiling(tpModifier * action.amount));
|
||||
|
||||
|
||||
if (charaWork.parameterSave.hp[0] < 1)
|
||||
Die(Program.Tick, actionContainer);
|
||||
}
|
||||
|
||||
public UInt64 GetTempVar(string name)
|
||||
|
@ -865,29 +966,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
if (val)
|
||||
{
|
||||
StatusEffect procEffect = Server.GetWorldManager().GetStatusEffect(effectId);
|
||||
procEffect.SetDuration(5000);
|
||||
procEffect.SetDuration(5);
|
||||
statusEffects.AddStatusEffect(procEffect, this, true, true);
|
||||
|
||||
string procFunc = "";
|
||||
|
||||
//is there any reason we need this
|
||||
switch(procId)
|
||||
{
|
||||
case (0):
|
||||
procFunc = "onEvade";
|
||||
break;
|
||||
case (1):
|
||||
procFunc = "onBlock";
|
||||
break;
|
||||
case (2):
|
||||
procFunc = "onParry";
|
||||
break;
|
||||
case (3):
|
||||
procFunc = "onMiss";
|
||||
break;
|
||||
}
|
||||
|
||||
//lua.LuaEngine.CallLuaBattleFunction(this, procFunc, this);
|
||||
}
|
||||
//Otherwise we're reseting a proc, remove the status
|
||||
else
|
||||
|
@ -921,9 +1001,124 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||
}
|
||||
|
||||
//Called when this character evades attacker's action
|
||||
public void OnEvade(Character attacker, BattleAction action)
|
||||
public void OnEvade(Character attacker, BattleAction action, BattleActionContainer actionContainer = null)
|
||||
{
|
||||
SetProc((ushort)HitType.Evade);
|
||||
statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnEvade, "onEvade", attacker, this, action, actionContainer);
|
||||
}
|
||||
|
||||
//Called when this character blocks attacker's action
|
||||
public void OnBlock(Character attacker, BattleAction action, BattleActionContainer actionContainer = null)
|
||||
{
|
||||
SetProc((ushort)HitType.Block);
|
||||
statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnBlock, "onBlock", attacker, this, action, actionContainer);
|
||||
}
|
||||
|
||||
//Called when this character parries attacker's action
|
||||
public void OnParry(Character attacker, BattleAction action, BattleActionContainer actionContainer = null)
|
||||
{
|
||||
SetProc((ushort)HitType.Parry);
|
||||
statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnParry, "onParry", attacker, this, action, actionContainer);
|
||||
}
|
||||
|
||||
//Called when this character misses
|
||||
public void OnMiss(Character defender, BattleAction action, BattleActionContainer actionContainer = null)
|
||||
{
|
||||
SetProc((ushort)HitType.Miss);
|
||||
statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnMiss, "onMiss", this, defender, action, actionContainer);
|
||||
}
|
||||
|
||||
public void OnHit(Character defender, BattleAction action, BattleActionContainer actionContainer = null)
|
||||
{
|
||||
statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnHit, "onHit", this, defender, action, actionContainer);
|
||||
}
|
||||
|
||||
//The order of messages that appears after using a command is:
|
||||
|
||||
//1. Cast start messages. (ie "You begin casting... ")
|
||||
//2. Messages from buffs that activate before the command actually starts, like Power Surge or Presence of Mind. (This may be wrong and these could be the same as 4.)
|
||||
//3. If the command is a multi-hit command, this is where the "You use [command] on [target]" message goes
|
||||
|
||||
//Then, for each hit:
|
||||
//4. Buffs that activate before a command hits, like Blindside
|
||||
//5. The hit itself. For single hit commands this message is "Your [command] hits [target] for x damage" for multi hits it's "[Target] takes x points of damage"
|
||||
//6. Stoneskin falling off
|
||||
//6. Buffs that activate after a command hits, like Aegis Boon and Divine Veil
|
||||
|
||||
//After all hits
|
||||
//7. If it's a multi-hit command there's a "{numhits]fold attack..." message or if all hits miss an "All attacks missed" message
|
||||
//8. Buffs that fall off after the skill ends, like Excruciate
|
||||
|
||||
//For every target defeated:
|
||||
//8. Defeat message
|
||||
//9. EXP message
|
||||
//10. EXP chain message
|
||||
|
||||
|
||||
//folder is probably temporary until move to cached scripts is complete
|
||||
public void DoBattleCommand(BattleCommand command, string folder)
|
||||
{
|
||||
//List<BattleAction> actions = new List<BattleAction>();
|
||||
BattleActionContainer actions = new BattleActionContainer();
|
||||
|
||||
var targets = command.targetFind.GetTargets();
|
||||
bool hitTarget = false;
|
||||
|
||||
if (targets.Count > 0)
|
||||
{
|
||||
statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnCommandStart, "onCommandStart", this, command, actions);
|
||||
|
||||
foreach (var chara in targets)
|
||||
{
|
||||
ushort hitCount = 0;
|
||||
for (int hitNum = 1; hitNum <= command.numHits; hitNum++)
|
||||
{
|
||||
var action = new BattleAction(chara.actorId, command, (byte)GetHitDirection(chara), (byte)hitNum);
|
||||
|
||||
//uncached script
|
||||
lua.LuaEngine.CallLuaBattleCommandFunction(this, command, folder, "onSkillFinish", this, chara, command, action, actions);
|
||||
//cached script
|
||||
//skill.CallLuaFunction(owner, "onSkillFinish", this, chara, command, action, actions);
|
||||
|
||||
if (action.hitType > HitType.Evade && action.hitType != HitType.Resist)
|
||||
{
|
||||
hitTarget = true;
|
||||
hitCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (command.numHits > 1)
|
||||
{
|
||||
//You use [command] on [target].
|
||||
actions.AddAction(new BattleAction(chara.actorId, 30442, 0, 0, (byte)hitCount));
|
||||
}
|
||||
}
|
||||
|
||||
statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnCommandFinish, "onCommandFinish", this, command, actions);
|
||||
}
|
||||
else
|
||||
{
|
||||
actions.AddAction(new BattleAction(target.actorId, 30202, 0));
|
||||
}
|
||||
|
||||
//Now that we know if we hit the target we can check if the combo continues
|
||||
if (this is Player player && command.commandType == CommandType.WeaponSkill)
|
||||
if (command.isCombo && hitTarget)
|
||||
player.SetCombos(command.comboNextCommandId);
|
||||
else
|
||||
player.SetCombos();
|
||||
|
||||
BattleAction error = new BattleAction(actorId, 0, 0);
|
||||
actions.CombineLists();
|
||||
DoBattleAction(command.id, command.battleAnimation, actions.GetList());
|
||||
}
|
||||
|
||||
public List<Character> GetPartyMembersInRange(uint range)
|
||||
{
|
||||
TargetFind targetFind = new TargetFind(this);
|
||||
targetFind.SetAOEType(ValidTarget.PartyMember, TargetFindAOEType.Circle, TargetFindAOETarget.Self, range);
|
||||
targetFind.FindWithinArea(this, ValidTarget.PartyMember, TargetFindAOETarget.Self);
|
||||
return targetFind.GetTargets();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue