mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-05-20 08:26:59 -04: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:
@@ -48,15 +48,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||
else
|
||||
{
|
||||
//owner.LookAt(target);
|
||||
|
||||
//If owner already has this status effect and it's a stance that gets removed on reuse, remove it and don't continue
|
||||
var effect = owner.statusEffects.GetStatusEffectById(skill.statusId);
|
||||
if (effect!= null && (effect.GetFlags() & (uint) StatusEffectFlags.Stance) != 0)
|
||||
{
|
||||
owner.statusEffects.RemoveStatusEffect(effect);
|
||||
interrupt = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,35 +92,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||
|
||||
skill.targetFind.FindWithinArea(target, skill.validTarget, skill.aoeTarget);
|
||||
isCompleted = true;
|
||||
var targets = skill.targetFind.GetTargets();
|
||||
|
||||
List<BattleAction> actions = new List<BattleAction>();
|
||||
List<StatusEffect> effects = owner.statusEffects.GetStatusEffectsByFlag((uint)StatusEffectFlags.ActivateOnAttack);
|
||||
|
||||
foreach (var chara in targets)
|
||||
{
|
||||
for (int hitNum = 0; hitNum < skill.numHits; hitNum++)
|
||||
{
|
||||
//30328 - Your [ability] grants you the effect of [status]
|
||||
//30320 - You use [ability]. You recover x HP.
|
||||
var action = new BattleAction(chara.actorId, skill.worldMasterTextId, 0, 0, 1, 1);
|
||||
|
||||
//uncached
|
||||
lua.LuaEngine.CallLuaBattleCommandFunction(owner, skill, "ability", "onAbilityFinish", owner, target, skill, action);
|
||||
//cached
|
||||
//skill.CallLuaFunction(owner, "onAbilityFinish", owner, target, skill, action);
|
||||
|
||||
//if hit type isn't evade or miss
|
||||
if (((action.hitType & HitType.Evade) | (action.hitType & HitType.Miss)) == 0)
|
||||
hitTarget = true;
|
||||
|
||||
actions.AddRange(action.GetAllActions());
|
||||
}
|
||||
}
|
||||
// todo: this is fuckin stupid, probably only need *one* error packet, not an error for each action
|
||||
BattleAction[] errors = (BattleAction[])actions.ToArray().Clone();
|
||||
owner.OnAbility(this, actions.ToArray(), skill, ref errors);
|
||||
owner.DoBattleAction(skill.id, skill.battleAnimation, actions);
|
||||
owner.DoBattleCommand(skill, "ability");
|
||||
}
|
||||
|
||||
public override void TryInterrupt()
|
||||
|
@@ -32,9 +32,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||
|
||||
public override bool Update(DateTime tick)
|
||||
{
|
||||
|
||||
if ((target == null || owner.target != target || owner.target?.actorId != owner.currentLockedTarget) && owner.isAutoAttackEnabled)
|
||||
owner.aiContainer.ChangeTarget(target = owner.zone.FindActorInArea<Character>(owner.currentLockedTarget));
|
||||
owner.aiContainer.ChangeTarget(target = owner.zone.FindActorInArea<Character>(owner.currentTarget));
|
||||
|
||||
if (target == null || target.IsDead())
|
||||
{
|
||||
@@ -101,25 +100,30 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||
// handle paralyze/intimidate/sleep/whatever in Character.OnAttack
|
||||
|
||||
|
||||
List<BattleAction> actions = new List<BattleAction>();
|
||||
// todo: Change this to use a BattleCommand like the other states
|
||||
|
||||
//List<BattleAction> actions = new List<BattleAction>();
|
||||
BattleActionContainer actions = new BattleActionContainer();
|
||||
target.SetMod((uint) Modifier.MinimumHpLock, 0);
|
||||
|
||||
var i = 0;
|
||||
for (int hitNum = 0; hitNum < owner.GetMod((uint) Modifier.HitCount); hitNum++)
|
||||
for (int hitNum = 0; hitNum < 1 /* owner.GetMod((uint) Modifier.HitCount)*/; hitNum++)
|
||||
{
|
||||
BattleAction action = new BattleAction(target.actorId, 0x765D, (uint)HitEffect.Hit, 100, (byte)HitDirection.None, (byte) hitNum);
|
||||
action.battleActionType = BattleActionType.AttackPhysical;
|
||||
action.commandType = CommandType.AutoAttack;
|
||||
action.actionType = ActionType.Physical;
|
||||
action.actionProperty = (ActionProperty) owner.GetMod(Modifier.AttackType);
|
||||
// evasion, miss, dodge, etc to be handled in script, calling helpers from scripts/weaponskills.lua
|
||||
// temporary evade/miss/etc function to test hit effects
|
||||
utils.BattleUtils.CalcHitType(owner, target, null, action);
|
||||
actions.AddRange(action.GetAllActions());
|
||||
action.DoAction(owner, target, null, actions);
|
||||
}
|
||||
|
||||
// todo: this is fuckin stupid, probably only need *one* error packet, not an error for each action
|
||||
BattleAction[] errors = (BattleAction[])actions.ToArray().Clone();
|
||||
|
||||
owner.OnAttack(this, actions[0], ref errorResult);
|
||||
owner.DoBattleAction(22104, 0x19001000, actions);
|
||||
target.SetMod((uint) Modifier.MinimumHpLock, 0);
|
||||
BattleAction[] errors = (BattleAction[])actions.GetList().ToArray().Clone();
|
||||
BattleAction error = null;// new BattleAction(0, null, 0, 0);
|
||||
//owner.DoActions(null, actions.GetList(), ref error);
|
||||
//owner.OnAttack(this, actions[0], ref errorResult);
|
||||
owner.DoBattleAction(22104, 0x19001000, actions.GetList());
|
||||
}
|
||||
|
||||
public override void TryInterrupt()
|
||||
@@ -148,7 +152,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||
|
||||
private bool CanAttack()
|
||||
{
|
||||
if (!owner.isAutoAttackEnabled)
|
||||
if (!owner.isAutoAttackEnabled || target.allegiance == owner.allegiance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@@ -64,6 +64,14 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||
lua.LuaEngine.CallLuaBattleCommandFunction(owner, spell, "magic", "onCombo", owner, target, spell);
|
||||
spell.isCombo = true;
|
||||
}
|
||||
|
||||
//Modify spell based on status effects. Need to do it here because they can modify cast times
|
||||
List<StatusEffect> effects = owner.statusEffects.GetStatusEffectsByFlag((uint) (StatusEffectFlags.ActivateOnCastStart));
|
||||
|
||||
//modify skill based on status effects
|
||||
foreach (var effect in effects)
|
||||
lua.LuaEngine.CallLuaStatusEffectFunction(owner, effect, "onMagicCast", owner, effect, spell);
|
||||
|
||||
if (!spell.IsInstantCast())
|
||||
{
|
||||
// command casting duration
|
||||
@@ -124,50 +132,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||
isCompleted = true;
|
||||
var targets = spell.targetFind.GetTargets();
|
||||
|
||||
|
||||
List<BattleAction> actions = new List<BattleAction>();
|
||||
if (targets.Count > 0)
|
||||
{
|
||||
List<StatusEffect> effects = owner.statusEffects.GetStatusEffectsByFlag((uint)StatusEffectFlags.ActivateOnSpell);
|
||||
|
||||
//modify skill based on status effects
|
||||
foreach (var effect in effects)
|
||||
lua.LuaEngine.CallLuaStatusEffectFunction(owner, effect, "onWeaponSkill", owner, effect, spell);
|
||||
|
||||
//Now that combos and positionals bonuses are done, we can calculate hits/crits/etc and damage
|
||||
foreach (var chara in targets)
|
||||
{
|
||||
for (int hitNum = 0; hitNum < spell.numHits; hitNum++)
|
||||
{
|
||||
var action = new BattleAction(chara.actorId, spell.worldMasterTextId, 0, 0, (byte) hitDir, (byte) hitNum);
|
||||
lua.LuaEngine.CallLuaBattleCommandFunction(owner, spell, "magic", "onMagicFinish", owner, chara, spell, action);
|
||||
|
||||
//if hit type isn't evade or miss
|
||||
if (action.hitType > HitType.Evade)
|
||||
hitTarget = true;
|
||||
|
||||
actions.AddRange(action.GetAllActions());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//No targets hit, cast failed
|
||||
actions.Add(new BattleAction(target.actorId, 30202, (uint) (0)));
|
||||
}
|
||||
|
||||
|
||||
// todo: this is fuckin stupid, probably only need *one* error packet, not an error for each action
|
||||
BattleAction[] errors = (BattleAction[])actions.ToArray().Clone();
|
||||
owner.OnCast(this, actions.ToArray(), spell, ref errors);
|
||||
owner.DoBattleAction(spell.id, spell.battleAnimation, actions);
|
||||
owner.statusEffects.RemoveStatusEffectsByFlags((uint)StatusEffectFlags.LoseOnCasting);
|
||||
//Now that we know if we hit the target we can check if the combo continues
|
||||
if (owner is Player player)
|
||||
if (spell.isCombo && hitTarget)
|
||||
player.SetCombos(spell.comboNextCommandId);
|
||||
else
|
||||
player.SetCombos();
|
||||
owner.DoBattleCommand(spell, "magic");
|
||||
}
|
||||
|
||||
public override void TryInterrupt()
|
||||
|
@@ -77,7 +77,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,55 +117,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||
|
||||
public override void OnComplete()
|
||||
{
|
||||
bool hitTarget = false;
|
||||
|
||||
skill.targetFind.FindWithinArea(target, skill.validTarget, skill.aoeTarget);
|
||||
isCompleted = true;
|
||||
var targets = skill.targetFind.GetTargets();
|
||||
|
||||
//Need a variable size list of actions because status effects may add extra actions
|
||||
//BattleAction[] actions = new BattleAction[targets.Count * skill.numHits];
|
||||
List<BattleAction> actions = new List<BattleAction>();
|
||||
List<StatusEffect> effects = owner.statusEffects.GetStatusEffectsByFlag((uint)StatusEffectFlags.ActivateOnAttack);
|
||||
|
||||
//modify skill based on status effects
|
||||
foreach (var effect in effects)
|
||||
effect.CallLuaFunction(owner, "onWeaponSkill", skill);
|
||||
|
||||
//Now that combos and positionals bonuses are done, we can calculate hits/crits/etc and damage for each action
|
||||
foreach (var chara in targets)
|
||||
{
|
||||
for (int hitNum = 0; hitNum < skill.numHits; hitNum++)
|
||||
{
|
||||
var action = new BattleAction(chara.actorId, skill.worldMasterTextId, 0, 0, (byte) hitDirection, 1);
|
||||
//For older versions this will need to be in the database for magic weaponskills
|
||||
action.battleActionType = BattleActionType.AttackPhysical;
|
||||
//uncached script
|
||||
lua.LuaEngine.CallLuaBattleCommandFunction(owner, skill, "weaponskill", "onSkillFinish", owner, target, skill, action);
|
||||
|
||||
//cached script
|
||||
//skill.CallLuaFunction(owner, "onSkillFinish", owner, target, skill, action);
|
||||
action.hitNum = (byte)hitNum;
|
||||
|
||||
if (action.hitType > HitType.Evade)
|
||||
hitTarget = true;
|
||||
|
||||
actions.AddRange(action.GetAllActions());
|
||||
}
|
||||
}
|
||||
|
||||
// todo: this is fuckin stupid, probably only need *one* error packet, not an error for each action
|
||||
BattleAction[] errors = (BattleAction[]) actions.ToArray().Clone();
|
||||
owner.OnWeaponSkill(this, actions.ToArray(), skill, ref errors);
|
||||
owner.DoBattleAction(skill.id, skill.battleAnimation, actions);
|
||||
owner.DoBattleCommand(skill, "weaponskill");
|
||||
owner.statusEffects.RemoveStatusEffectsByFlags((uint) StatusEffectFlags.LoseOnAttacking);
|
||||
|
||||
//Now that we know if we hit the target we can check if the combo continues
|
||||
if (owner is Player player)
|
||||
if (skill.isCombo && hitTarget)
|
||||
player.SetCombos(skill.comboNextCommandId);
|
||||
else
|
||||
player.SetCombos();
|
||||
lua.LuaEngine.GetInstance().OnSignal("weaponskillUsed");
|
||||
}
|
||||
|
||||
public override void TryInterrupt()
|
||||
|
Reference in New Issue
Block a user