public override void OnComplete() { //BattleAction action = new BattleAction(target.actorId, 0x765D, (uint) HitEffect.Hit, 0, (byte) HitDirection.None); errorResult = null; // todo: implement auto attack damage bonus in Character.OnAttack /* * ≪Auto-attack Damage Bonus≫ * Class Bonus 1 Bonus 2 * Pugilist Intelligence Strength * Gladiator Mind Strength * Marauder Vitality Strength * Archer Dexterity Piety * Lancer Piety Strength * Conjurer Mind Piety * Thaumaturge Mind Piety * The above damage bonus also applies to “Shot” attacks by archers. */ // handle paralyze/intimidate/sleep/whatever in Character.OnAttack // todo: Change this to use a BattleCommand like the other states //List<BattleAction> actions = new List<BattleAction>(); CommandResultContainer actions = new CommandResultContainer(); var i = 0; for (int hitNum = 0; hitNum < 1 /* owner.GetMod((uint) Modifier.HitCount)*/; hitNum++) { CommandResult action = new CommandResult(target.actorId, 0x765D, (uint)HitEffect.Hit, 100, (byte)HitDirection.None, (byte)hitNum); 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 action.DoAction(owner, target, null, actions); } // todo: this is f****n stupid, probably only need *one* error packet, not an error for each action CommandResult[] errors = (CommandResult[])actions.GetList().ToArray().Clone(); CommandResult error = null;// new BattleAction(0, null, 0, 0); //owner.DoActions(null, actions.GetList(), ref error); //owner.OnAttack(this, actions[0], ref errorResult); var anim = (uint)(17 << 24 | 1 << 12); owner.DoBattleAction(22104, anim, actions.GetList()); }
//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>(); CommandResultContainer actions = new CommandResultContainer(); 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; ushort totalDamage = 0; for (int hitNum = 1; hitNum <= command.numHits; hitNum++) { var action = new CommandResult(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++; totalDamage += action.amount; } } if (command.numHits > 1) { //30442: [hitCount]fold Attack! [chara] takes a total of totalDamage points of damage. //30450: All attacks miss! ushort textId = (ushort)(hitTarget ? 30442 : 30450); actions.AddAction(new CommandResult(chara.actorId, textId, 0, totalDamage, (byte)hitCount)); } } statusEffects.CallLuaFunctionByFlag((uint)StatusEffectFlags.ActivateOnCommandFinish, "onCommandFinish", this, command, actions); } else { actions.AddAction(new CommandResult(actorId, 30202, 0)); } //Now that we know if we hit the target we can check if the combo continues if (this is Player) { if (command.isCombo && hitTarget) { ((Player)this).SetCombos(command.comboNextCommandId); } else { ((Player)this).SetCombos(); } } CommandResult error = new CommandResult(actorId, 0, 0); DelMP(command.CalculateMpCost(this)); DelTP(command.CalculateTpCost(this)); actions.CombineLists(); DoBattleAction(command.id, command.battleAnimation, actions.GetList()); }