mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-25 06:07:46 +00:00
Added party to Gridania opening, fixed BattleActionx18 and made it so x18 is used for packets with more than 10 targets. Changed how death works. Added respawn time and roam modifiers. Added TryAggro functions and moved aggroing out of roaming and helpplayers. Fixed high cpu usage in zone's OnUpdate function. Fixed work value in player update
This commit is contained in:
parent
520ae7a119
commit
1275c8b5da
61 changed files with 1226 additions and 223 deletions
|
@ -511,7 +511,6 @@ namespace FFXIVClassic_Map_Server
|
||||||
battleNpc.SetMod((uint)Modifier.Defense, reader.GetUInt32("def"));
|
battleNpc.SetMod((uint)Modifier.Defense, reader.GetUInt32("def"));
|
||||||
battleNpc.SetMod((uint)Modifier.Evasion, reader.GetUInt32("eva"));
|
battleNpc.SetMod((uint)Modifier.Evasion, reader.GetUInt32("eva"));
|
||||||
|
|
||||||
|
|
||||||
battleNpc.dropListId = reader.GetUInt32("dropListId");
|
battleNpc.dropListId = reader.GetUInt32("dropListId");
|
||||||
battleNpc.spellListId = reader.GetUInt32("spellListId");
|
battleNpc.spellListId = reader.GetUInt32("spellListId");
|
||||||
battleNpc.skillListId = reader.GetUInt32("skillListId");
|
battleNpc.skillListId = reader.GetUInt32("skillListId");
|
||||||
|
@ -644,12 +643,48 @@ namespace FFXIVClassic_Map_Server
|
||||||
battleNpc.SetMod((uint)Modifier.Defense, reader.GetUInt32("def"));
|
battleNpc.SetMod((uint)Modifier.Defense, reader.GetUInt32("def"));
|
||||||
battleNpc.SetMod((uint)Modifier.Evasion, reader.GetUInt32("eva"));
|
battleNpc.SetMod((uint)Modifier.Evasion, reader.GetUInt32("eva"));
|
||||||
|
|
||||||
|
if (battleNpc.poolMods != null)
|
||||||
|
{
|
||||||
|
foreach (var a in battleNpc.poolMods.mobModList)
|
||||||
|
{
|
||||||
|
battleNpc.SetMobMod(a.Value.id, (long)(a.Value.value));
|
||||||
|
}
|
||||||
|
foreach (var a in battleNpc.poolMods.modList)
|
||||||
|
{
|
||||||
|
battleNpc.SetMod(a.Key, (long)(a.Value.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (battleNpc.genusMods != null)
|
||||||
|
{
|
||||||
|
foreach (var a in battleNpc.genusMods.mobModList)
|
||||||
|
{
|
||||||
|
battleNpc.SetMobMod(a.Key, (long)(a.Value.value));
|
||||||
|
}
|
||||||
|
foreach (var a in battleNpc.genusMods.modList)
|
||||||
|
{
|
||||||
|
battleNpc.SetMod(a.Key, (long)(a.Value.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(battleNpc.spawnMods != null)
|
||||||
|
{
|
||||||
|
foreach (var a in battleNpc.spawnMods.mobModList)
|
||||||
|
{
|
||||||
|
battleNpc.SetMobMod(a.Key, (long)(a.Value.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var a in battleNpc.spawnMods.modList)
|
||||||
|
{
|
||||||
|
battleNpc.SetMod(a.Key, (long)(a.Value.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
battleNpc.dropListId = reader.GetUInt32("dropListId");
|
battleNpc.dropListId = reader.GetUInt32("dropListId");
|
||||||
battleNpc.spellListId = reader.GetUInt32("spellListId");
|
battleNpc.spellListId = reader.GetUInt32("spellListId");
|
||||||
battleNpc.skillListId = reader.GetUInt32("skillListId");
|
battleNpc.skillListId = reader.GetUInt32("skillListId");
|
||||||
battleNpc.SetMaxHP(1000);
|
|
||||||
battleNpc.SetHP(1000);
|
|
||||||
battleNpc.SetBattleNpcId(reader.GetUInt32("bnpcId"));
|
battleNpc.SetBattleNpcId(reader.GetUInt32("bnpcId"));
|
||||||
|
battleNpc.SetRespawnTime(reader.GetUInt32("respawnTime"));
|
||||||
battleNpc.CalculateBaseStats();
|
battleNpc.CalculateBaseStats();
|
||||||
battleNpc.RecalculateStats();
|
battleNpc.RecalculateStats();
|
||||||
//battleNpc.SetMod((uint)Modifier.ResistFire, )
|
//battleNpc.SetMod((uint)Modifier.ResistFire, )
|
||||||
|
@ -679,7 +714,7 @@ namespace FFXIVClassic_Map_Server
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
var query = $"SELECT {primaryKey}, modId, modVal, isMobMod FROM {tableName} GROUP BY {primaryKey};";
|
var query = $"SELECT {primaryKey}, modId, modVal, isMobMod FROM {tableName}";
|
||||||
|
|
||||||
MySqlCommand cmd = new MySqlCommand(query, conn);
|
MySqlCommand cmd = new MySqlCommand(query, conn);
|
||||||
|
|
||||||
|
@ -688,9 +723,9 @@ namespace FFXIVClassic_Map_Server
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
var id = reader.GetUInt32(primaryKey);
|
var id = reader.GetUInt32(primaryKey);
|
||||||
ModifierList modList = new ModifierList(id);
|
ModifierList modList = list.TryGetValue(id, out modList) ? modList : new ModifierList(id);
|
||||||
modList.SetModifier(reader.GetUInt16("modId"), reader.GetInt64("modVal"), reader.GetBoolean("isMobMod"));
|
modList.SetModifier(reader.GetUInt16("modId"), reader.GetInt64("modVal"), reader.GetBoolean("isMobMod"));
|
||||||
list.Add(id, modList);
|
list[id] = modList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -438,9 +438,6 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
|
|
||||||
updateFlags = ActorUpdateFlags.None;
|
updateFlags = ActorUpdateFlags.None;
|
||||||
zone.BroadcastPacketsAroundActor(this, packets);
|
zone.BroadcastPacketsAroundActor(this, packets);
|
||||||
|
|
||||||
SetActorPropetyPacket hpInfo = new SetActorPropetyPacket("charaWork/exp");
|
|
||||||
hpInfo.AddTarget();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -421,6 +421,11 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
return GetAllActors<BattleNpc>();
|
return GetAllActors<BattleNpc>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual List<Ally> GetAllies()
|
||||||
|
{
|
||||||
|
return GetAllActors<Ally>();
|
||||||
|
}
|
||||||
|
|
||||||
public void BroadcastPacketsAroundActor(Actor actor, List<SubPacket> packets)
|
public void BroadcastPacketsAroundActor(Actor actor, List<SubPacket> packets)
|
||||||
{
|
{
|
||||||
foreach (SubPacket packet in packets)
|
foreach (SubPacket packet in packets)
|
||||||
|
@ -495,8 +500,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
npc = new Npc(mActorList.Count + 1, actorClass, uniqueId, this, x, y, z, rot, state, animId, null);
|
npc = new Npc(mActorList.Count + 1, actorClass, uniqueId, this, x, y, z, rot, state, animId, null);
|
||||||
|
|
||||||
npc.LoadEventConditions(actorClass.eventConditions);
|
npc.LoadEventConditions(actorClass.eventConditions);
|
||||||
npc.SetMaxHP(300);
|
//npc.SetMaxHP(30000);
|
||||||
npc.SetHP(300);
|
//npc.SetHP(30000);
|
||||||
|
|
||||||
AddActorToZone(npc);
|
AddActorToZone(npc);
|
||||||
|
|
||||||
|
@ -666,7 +671,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
a.Update(tick);
|
a.Update(tick);
|
||||||
|
|
||||||
var deltaTime = (tick - Program.LastTick).TotalMilliseconds;
|
var deltaTime = (tick - Program.LastTick).TotalMilliseconds;
|
||||||
LuaEngine.GetInstance().CallLuaFunction(null, this, "onUpdate", true, deltaTime, this);
|
//LuaEngine.GetInstance().CallLuaFunction(null, this, "onUpdate", true, this, deltaTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,18 @@ namespace FFXIVClassic_Map_Server.actors.area
|
||||||
return actor;
|
return actor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (List<PrivateAreaContent> paList in contentAreas.Values)
|
||||||
|
{
|
||||||
|
foreach (PrivateArea pa in paList)
|
||||||
|
{
|
||||||
|
Actor actor = pa.FindActorInArea(id);
|
||||||
|
if (actor != null)
|
||||||
|
return actor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -230,10 +230,10 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
public void DoBattleAction(ushort commandId, uint animationId, BattleAction[] actions)
|
public void DoBattleAction(ushort commandId, uint animationId, BattleAction[] actions)
|
||||||
{
|
{
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
|
//AoE abilities only ever hit 16 people, so we probably won't need this loop anymore
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (actions.Length - currentIndex >= 18)
|
if (actions.Length - currentIndex >= 10)
|
||||||
zone.BroadcastPacketAroundActor(this, BattleActionX18Packet.BuildPacket(actorId, animationId, commandId, actions, ref currentIndex));
|
zone.BroadcastPacketAroundActor(this, BattleActionX18Packet.BuildPacket(actorId, animationId, commandId, actions, ref currentIndex));
|
||||||
else if (actions.Length - currentIndex > 1)
|
else if (actions.Length - currentIndex > 1)
|
||||||
zone.BroadcastPacketAroundActor(this, BattleActionX10Packet.BuildPacket(actorId, animationId, commandId, actions, ref currentIndex));
|
zone.BroadcastPacketAroundActor(this, BattleActionX10Packet.BuildPacket(actorId, animationId, commandId, actions, ref currentIndex));
|
||||||
|
@ -244,7 +244,9 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
animationId = 0; //If more than one packet is sent out, only send the animation once to avoid double playing.
|
|
||||||
|
//I think aoe effects play on all hit enemies. Firaga does at least
|
||||||
|
//animationId = 0; //If more than one packet is sent out, only send the animation once to avoid double playing.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +315,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
|
|
||||||
public virtual void OnPath(Vector3 point)
|
public virtual void OnPath(Vector3 point)
|
||||||
{
|
{
|
||||||
lua.LuaEngine.CallLuaBattleFunction(this, "onPath", this, point);
|
//lua.LuaEngine.CallLuaBattleFunction(this, "onPath", this, point);
|
||||||
|
|
||||||
updateFlags |= ActorUpdateFlags.Position;
|
updateFlags |= ActorUpdateFlags.Position;
|
||||||
this.isAtSpawn = false;
|
this.isAtSpawn = false;
|
||||||
|
@ -347,7 +349,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
|
|
||||||
if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0)
|
if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0)
|
||||||
{
|
{
|
||||||
var propPacketUtil = new ActorPropertyPacketUtil("charaWork.parameterSave", this);
|
var propPacketUtil = new ActorPropertyPacketUtil("charaWork/stateAtQuicklyForAll", this);
|
||||||
|
|
||||||
propPacketUtil.AddProperty("charaWork.parameterSave.mp");
|
propPacketUtil.AddProperty("charaWork.parameterSave.mp");
|
||||||
propPacketUtil.AddProperty("charaWork.parameterSave.mpMax");
|
propPacketUtil.AddProperty("charaWork.parameterSave.mpMax");
|
||||||
|
@ -470,6 +472,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
{
|
{
|
||||||
// todo: actual despawn timer
|
// todo: actual despawn timer
|
||||||
aiContainer.InternalDie(tick, 10);
|
aiContainer.InternalDie(tick, 10);
|
||||||
|
ChangeSpeed(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Despawn(DateTime tick)
|
public virtual void Despawn(DateTime tick)
|
||||||
|
@ -543,6 +546,20 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
updateFlags |= ActorUpdateFlags.HpTpMp;
|
updateFlags |= ActorUpdateFlags.HpTpMp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetMP(uint mp)
|
||||||
|
{
|
||||||
|
charaWork.parameterSave.mpMax = (short)mp;
|
||||||
|
if (mp > charaWork.parameterSave.hpMax[0])
|
||||||
|
SetMaxMP(mp);
|
||||||
|
|
||||||
|
updateFlags |= ActorUpdateFlags.HpTpMp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMaxMP(uint mp)
|
||||||
|
{
|
||||||
|
charaWork.parameterSave.mp = (short)mp;
|
||||||
|
updateFlags |= ActorUpdateFlags.HpTpMp;
|
||||||
|
}
|
||||||
// todo: the following functions are virtuals since we want to check hidden item bonuses etc on player for certain conditions
|
// 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)
|
public virtual void AddHP(int hp)
|
||||||
{
|
{
|
||||||
|
@ -562,7 +579,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public short GetJob()
|
public short GetClass()
|
||||||
{
|
{
|
||||||
return charaWork.parameterSave.state_mainSkill[0];
|
return charaWork.parameterSave.state_mainSkill[0];
|
||||||
}
|
}
|
||||||
|
@ -614,8 +631,30 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
|
|
||||||
public void RecalculateStats()
|
public void RecalculateStats()
|
||||||
{
|
{
|
||||||
if (GetMod((uint)Modifier.Hp) != 0)
|
uint hpMod = (uint) GetMod((uint)Modifier.Hp);
|
||||||
|
if (hpMod != 0)
|
||||||
{
|
{
|
||||||
|
SetMaxHP(hpMod);
|
||||||
|
uint hpp = (uint) GetMod((uint) Modifier.HpPercent);
|
||||||
|
uint hp = hpMod;
|
||||||
|
if(hpp != 0)
|
||||||
|
{
|
||||||
|
hp = (uint) Math.Ceiling(((float)hpp / 100.0f) * hpMod);
|
||||||
|
}
|
||||||
|
SetHP(hp);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint mpMod = (uint)GetMod((uint)Modifier.Mp);
|
||||||
|
if (mpMod != 0)
|
||||||
|
{
|
||||||
|
SetMaxMP(mpMod);
|
||||||
|
uint mpp = (uint)GetMod((uint)Modifier.MpPercent);
|
||||||
|
uint mp = mpMod;
|
||||||
|
if (mpp != 0)
|
||||||
|
{
|
||||||
|
mp = (uint)Math.Ceiling(((float)mpp / 100.0f) * mpMod);
|
||||||
|
}
|
||||||
|
SetMP(mp);
|
||||||
}
|
}
|
||||||
// todo: recalculate stats and crap
|
// todo: recalculate stats and crap
|
||||||
updateFlags |= ActorUpdateFlags.HpTpMp;
|
updateFlags |= ActorUpdateFlags.HpTpMp;
|
||||||
|
@ -650,9 +689,10 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
//var packet = BattleActionX01Packet.BuildPacket(owner.actorId, owner.actorId, target.actorId, (uint)0x19001000, (uint)0x8000604, (ushort)0x765D, (ushort)BattleActionX01PacketCommand.Attack, (ushort)damage, (byte)0x1);
|
//var packet = BattleActionX01Packet.BuildPacket(owner.actorId, owner.actorId, target.actorId, (uint)0x19001000, (uint)0x8000604, (ushort)0x765D, (ushort)BattleActionX01PacketCommand.Attack, (ushort)damage, (byte)0x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
target.OnDamageTaken(this, action, DamageTakenType.Ability);
|
|
||||||
// todo: call onAttack/onDamageTaken
|
// todo: call onAttack/onDamageTaken
|
||||||
target.DelHP(action.amount);
|
BattleUtils.DamageTarget(this, target, action);
|
||||||
|
target.OnDamageTaken(this, action, DamageTakenType.Ability);
|
||||||
|
|
||||||
if (target is BattleNpc)
|
if (target is BattleNpc)
|
||||||
((BattleNpc)target).lastAttacker = this;
|
((BattleNpc)target).lastAttacker = this;
|
||||||
|
|
||||||
|
@ -664,13 +704,26 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
{
|
{
|
||||||
var spell = ((MagicState)state).GetSpell();
|
var spell = ((MagicState)state).GetSpell();
|
||||||
// damage is handled in script
|
// damage is handled in script
|
||||||
this.DelMP(spell.mpCost); // mpCost can be set in script e.g. if caster has something for free spells
|
var spellCost = spell.CalculateCost((uint)this.GetLevel());
|
||||||
|
this.DelMP(spellCost); // mpCost can be set in script e.g. if caster has something for free spells
|
||||||
|
|
||||||
foreach (var action in actions)
|
foreach (BattleAction action in actions)
|
||||||
zone.FindActorInArea<Character>(action.targetId).OnDamageTaken(this, action, DamageTakenType.Magic);
|
{
|
||||||
|
if (zone.FindActorInArea<Character>(action.targetId) is Character chara)
|
||||||
|
{
|
||||||
|
if (chara != null && chara is BattleNpc)
|
||||||
|
{
|
||||||
|
((BattleNpc)chara).hateContainer.UpdateHate(this, action.amount);
|
||||||
|
((BattleNpc)chara).lastAttacker = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BattleUtils.DamageTarget(this, chara, action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (target is BattleNpc)
|
if (target is BattleNpc)
|
||||||
((BattleNpc)target).lastAttacker = this;
|
|
||||||
|
lua.LuaEngine.GetInstance().OnSignal("spellUsed");
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnWeaponSkill(State state, BattleAction[] actions, ref BattleAction[] errors)
|
public virtual void OnWeaponSkill(State state, BattleAction[] actions, ref BattleAction[] errors)
|
||||||
|
@ -679,11 +732,25 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
// damage is handled in script
|
// damage is handled in script
|
||||||
this.DelTP(skill.tpCost);
|
this.DelTP(skill.tpCost);
|
||||||
|
|
||||||
foreach (var action in actions)
|
foreach (BattleAction action in actions)
|
||||||
zone.FindActorInArea<BattleNpc>(action.targetId)?.OnDamageTaken(this, action, DamageTakenType.Weaponskill);
|
{
|
||||||
|
if (zone.FindActorInArea<Character>(action.targetId) is Character chara)
|
||||||
|
{
|
||||||
|
if (chara != null && chara is BattleNpc)
|
||||||
|
{
|
||||||
|
((BattleNpc)chara).hateContainer.UpdateHate(this, action.amount);
|
||||||
|
((BattleNpc)chara).lastAttacker = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BattleUtils.DamageTarget(this, chara, action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (target is BattleNpc)
|
if (target is BattleNpc)
|
||||||
((BattleNpc)target).lastAttacker = this;
|
((BattleNpc)target).lastAttacker = this;
|
||||||
|
|
||||||
|
|
||||||
|
lua.LuaEngine.GetInstance().OnSignal("weaponskillUsed");
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnAbility(State state, BattleAction[] actions, ref BattleAction[] errors)
|
public virtual void OnAbility(State state, BattleAction[] actions, ref BattleAction[] errors)
|
||||||
|
@ -769,22 +836,22 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
|
|
||||||
public bool IsDiscipleOfWar()
|
public bool IsDiscipleOfWar()
|
||||||
{
|
{
|
||||||
return currentJob < CLASSID_THM;
|
return GetClass() < CLASSID_THM;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDiscipleOfMagic()
|
public bool IsDiscipleOfMagic()
|
||||||
{
|
{
|
||||||
return currentJob >= CLASSID_THM && currentJob < CLASSID_CRP;
|
return GetClass() >= CLASSID_THM && currentJob < CLASSID_CRP;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDiscipleOfHand()
|
public bool IsDiscipleOfHand()
|
||||||
{
|
{
|
||||||
return currentJob >= CLASSID_CRP && currentJob < CLASSID_MIN;
|
return GetClass() >= CLASSID_CRP && currentJob < CLASSID_MIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDiscipleOfLand()
|
public bool IsDiscipleOfLand()
|
||||||
{
|
{
|
||||||
return currentJob >= CLASSID_MIN;
|
return GetClass() >= CLASSID_MIN;
|
||||||
}
|
}
|
||||||
#endregion lua helpers
|
#endregion lua helpers
|
||||||
#endregion ai stuff
|
#endregion ai stuff
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.actors.chara.npc;
|
using FFXIVClassic_Map_Server.actors.chara.npc;
|
||||||
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
||||||
{
|
{
|
||||||
|
@ -18,34 +19,61 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected List<Character> GetContentGroupCharas()
|
||||||
|
{
|
||||||
|
List<Character> contentGroupCharas = null;
|
||||||
|
|
||||||
|
if (owner.currentContentGroup != null)
|
||||||
|
{
|
||||||
|
contentGroupCharas = new List<Character>(owner.currentContentGroup.GetMemberCount());
|
||||||
|
foreach (var charaId in owner.currentContentGroup.GetMembers())
|
||||||
|
{
|
||||||
|
var chara = owner.zone.FindActorInArea<Character>(charaId);
|
||||||
|
|
||||||
|
if (chara != null)
|
||||||
|
contentGroupCharas.Add(chara);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return contentGroupCharas;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Iterate over players in the group and if they are fighting, assist them
|
||||||
|
protected override void TryAggro(DateTime tick)
|
||||||
|
{
|
||||||
|
//lua.LuaEngine.CallLuaBattleFunction(owner, "tryAggro", owner, GetContentGroupCharas());
|
||||||
|
|
||||||
|
foreach(Character chara in GetContentGroupCharas())
|
||||||
|
{
|
||||||
|
if(chara.IsPlayer())
|
||||||
|
{
|
||||||
|
if(owner.aiContainer.GetTargetFind().CanTarget((Character) chara.target) && chara.target is BattleNpc && ((BattleNpc)chara.target).hateContainer.HasHateForTarget(chara))
|
||||||
|
{
|
||||||
|
owner.Engage(chara.target.actorId);
|
||||||
|
owner.hateContainer.AddBaseHate((Character) chara.target);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//base.TryAggro(tick);
|
||||||
|
}
|
||||||
|
|
||||||
// server really likes to hang whenever scripts iterate area's actorlist
|
// server really likes to hang whenever scripts iterate area's actorlist
|
||||||
protected override void DoCombatTick(DateTime tick, List<Character> contentGroupCharas = null)
|
protected override void DoCombatTick(DateTime tick, List<Character> contentGroupCharas = null)
|
||||||
{
|
{
|
||||||
if (owner.currentContentGroup != null)
|
if (contentGroupCharas == null)
|
||||||
{
|
{
|
||||||
contentGroupCharas = new List<Character>(owner.currentContentGroup.GetMemberCount());
|
contentGroupCharas = GetContentGroupCharas();
|
||||||
foreach (var charaId in owner.currentContentGroup.GetMembers())
|
}
|
||||||
{
|
|
||||||
var chara = owner.zone.FindActorInArea<Character>(charaId);
|
|
||||||
|
|
||||||
if (chara != null)
|
|
||||||
contentGroupCharas.Add(chara);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
base.DoCombatTick(tick, contentGroupCharas);
|
base.DoCombatTick(tick, contentGroupCharas);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void DoRoamTick(DateTime tick, List<Character> contentGroupCharas = null)
|
protected override void DoRoamTick(DateTime tick, List<Character> contentGroupCharas = null)
|
||||||
{
|
{
|
||||||
if (owner.currentContentGroup != null)
|
if (contentGroupCharas == null)
|
||||||
{
|
{
|
||||||
contentGroupCharas = new List<Character>(owner.currentContentGroup.GetMemberCount());
|
contentGroupCharas = GetContentGroupCharas();
|
||||||
foreach (var charaId in owner.currentContentGroup.GetMembers())
|
|
||||||
{
|
|
||||||
var chara = owner.zone.FindActorInArea<Character>(charaId);
|
|
||||||
|
|
||||||
if (chara != null)
|
|
||||||
contentGroupCharas.Add(chara);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
base.DoRoamTick(tick, contentGroupCharas);
|
base.DoRoamTick(tick, contentGroupCharas);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,12 +39,20 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
||||||
public override void Update(DateTime tick)
|
public override void Update(DateTime tick)
|
||||||
{
|
{
|
||||||
lastUpdate = tick;
|
lastUpdate = tick;
|
||||||
|
|
||||||
// todo: handle aggro/deaggro and other shit here
|
// todo: handle aggro/deaggro and other shit here
|
||||||
if (owner.aiContainer.IsEngaged())
|
if (!owner.aiContainer.IsEngaged())
|
||||||
|
{
|
||||||
|
TryAggro(tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(owner.aiContainer.IsEngaged())
|
||||||
{
|
{
|
||||||
DoCombatTick(tick);
|
DoCombatTick(tick);
|
||||||
}
|
}
|
||||||
else if (!owner.IsDead())
|
|
||||||
|
//Only move if owner isn't dead and is either too far away from their spawn point or is meant to roam
|
||||||
|
if (!owner.IsDead() && (owner.isMovingToSpawn || owner.GetMobMod((uint) MobModifier.Roams) > 0))
|
||||||
{
|
{
|
||||||
DoRoamTick(tick);
|
DoRoamTick(tick);
|
||||||
}
|
}
|
||||||
|
@ -63,6 +71,38 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//If the owner isn't moving to spawn, iterate over nearby enemies and
|
||||||
|
//aggro the first one that is within 10 levels and can be detected, then engage
|
||||||
|
protected virtual void TryAggro(DateTime tick)
|
||||||
|
{
|
||||||
|
if (tick >= neutralTime && !owner.isMovingToSpawn)
|
||||||
|
{
|
||||||
|
if (!owner.neutral && owner.IsAlive())
|
||||||
|
{
|
||||||
|
foreach (var chara in owner.zone.GetActorsAroundActor<Character>(owner, 50))
|
||||||
|
{
|
||||||
|
if (owner.allegiance == chara.allegiance)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (owner.aiContainer.pathFind.AtPoint() && owner.detectionType != DetectionType.None)
|
||||||
|
{
|
||||||
|
uint levelDifference = (uint)Math.Abs(owner.GetLevel() - chara.GetLevel());
|
||||||
|
|
||||||
|
if (levelDifference <= 10 || (owner.detectionType & DetectionType.IgnoreLevelDifference) != 0 && CanAggroTarget(chara))
|
||||||
|
{
|
||||||
|
owner.hateContainer.AddBaseHate(chara);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (owner.hateContainer.GetHateList().Count > 0)
|
||||||
|
{
|
||||||
|
Engage(owner.hateContainer.GetMostHatedTarget());
|
||||||
|
}
|
||||||
|
}
|
||||||
public override bool Engage(Character target)
|
public override bool Engage(Character target)
|
||||||
{
|
{
|
||||||
var canEngage = this.owner.aiContainer.InternalEngage(target);
|
var canEngage = this.owner.aiContainer.InternalEngage(target);
|
||||||
|
@ -77,6 +117,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
||||||
owner.ChangeState(SetActorStatePacket.MAIN_STATE_ACTIVE);
|
owner.ChangeState(SetActorStatePacket.MAIN_STATE_ACTIVE);
|
||||||
|
|
||||||
owner.moveState = 2;
|
owner.moveState = 2;
|
||||||
|
//owner.SetMod((uint)Modifier.Speed, 5);
|
||||||
lastActionTime = DateTime.Now;
|
lastActionTime = DateTime.Now;
|
||||||
battleStartTime = lastActionTime;
|
battleStartTime = lastActionTime;
|
||||||
// todo: adjust cooldowns with modifiers
|
// todo: adjust cooldowns with modifiers
|
||||||
|
@ -129,12 +170,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
||||||
|
|
||||||
protected virtual void DoRoamTick(DateTime tick, List<Character> contentGroupCharas = null)
|
protected virtual void DoRoamTick(DateTime tick, List<Character> contentGroupCharas = null)
|
||||||
{
|
{
|
||||||
if (owner.hateContainer.GetHateList().Count > 0)
|
|
||||||
{
|
|
||||||
Engage(owner.hateContainer.GetMostHatedTarget());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tick >= waitTime)
|
if (tick >= waitTime)
|
||||||
{
|
{
|
||||||
neutralTime = tick.AddSeconds(5);
|
neutralTime = tick.AddSeconds(5);
|
||||||
|
@ -150,7 +185,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
waitTime = tick.AddSeconds(10);
|
waitTime = tick.AddSeconds(owner.GetMobMod((uint) MobModifier.RoamDelay));
|
||||||
owner.OnRoam(tick);
|
owner.OnRoam(tick);
|
||||||
|
|
||||||
if (CanMoveForward(0.0f) && !owner.aiContainer.pathFind.IsFollowingPath())
|
if (CanMoveForward(0.0f) && !owner.aiContainer.pathFind.IsFollowingPath())
|
||||||
|
@ -159,31 +194,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
||||||
owner.aiContainer.pathFind.SetPathFlags(PathFindFlags.None);
|
owner.aiContainer.pathFind.SetPathFlags(PathFindFlags.None);
|
||||||
owner.aiContainer.pathFind.PathInRange(owner.spawnX, owner.spawnY, owner.spawnZ, 1.5f, 50.0f);
|
owner.aiContainer.pathFind.PathInRange(owner.spawnX, owner.spawnY, owner.spawnZ, 1.5f, 50.0f);
|
||||||
}
|
}
|
||||||
lua.LuaEngine.CallLuaBattleFunction(owner, "onRoam", owner, contentGroupCharas);
|
//lua.LuaEngine.CallLuaBattleFunction(owner, "onRoam", owner, contentGroupCharas);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (tick >= neutralTime)
|
|
||||||
{
|
|
||||||
if (!owner.neutral && owner.IsAlive())
|
|
||||||
{
|
|
||||||
foreach (var chara in owner.zone.GetActorsAroundActor<Character>(owner, 50))
|
|
||||||
{
|
|
||||||
if (owner.allegiance == chara.allegiance)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!owner.isMovingToSpawn && owner.aiContainer.pathFind.AtPoint() && owner.detectionType != DetectionType.None)
|
|
||||||
{
|
|
||||||
uint levelDifference = (uint)Math.Abs(owner.GetLevel() - chara.GetLevel());
|
|
||||||
|
|
||||||
if (levelDifference <= 10 || (owner.detectionType & DetectionType.IgnoreLevelDifference) != 0 && CanAggroTarget(chara))
|
|
||||||
{
|
|
||||||
owner.hateContainer.AddBaseHate(chara);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (owner.aiContainer.pathFind.IsFollowingPath() && owner.aiContainer.CanFollowPath())
|
if (owner.aiContainer.pathFind.IsFollowingPath() && owner.aiContainer.CanFollowPath())
|
||||||
|
@ -202,8 +213,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.controllers
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Move();
|
Move();
|
||||||
lua.LuaEngine.CallLuaBattleFunction(owner, "onCombatTick", owner, owner.target, Utils.UnixTimeStampUTC(tick), contentGroupCharas);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Move()
|
protected virtual void Move()
|
||||||
|
|
|
@ -159,6 +159,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void FindWithinArea(Character target, ValidTarget flags, TargetFindAOETarget aoeTarget)
|
public void FindWithinArea(Character target, ValidTarget flags, TargetFindAOETarget aoeTarget)
|
||||||
{
|
{
|
||||||
|
targets.Clear();
|
||||||
validTarget = flags;
|
validTarget = flags;
|
||||||
// are we creating aoe circles around target or self
|
// are we creating aoe circles around target or self
|
||||||
if (aoeTarget == TargetFindAOETarget.Self)
|
if (aoeTarget == TargetFindAOETarget.Self)
|
||||||
|
@ -174,6 +175,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
||||||
if (masterTarget != null)
|
if (masterTarget != null)
|
||||||
targets.Add(masterTarget);
|
targets.Add(masterTarget);
|
||||||
|
|
||||||
|
if (aoeType != TargetFindAOEType.None)
|
||||||
|
{
|
||||||
if (IsPlayer(owner))
|
if (IsPlayer(owner))
|
||||||
{
|
{
|
||||||
if (masterTarget is Player)
|
if (masterTarget is Player)
|
||||||
|
@ -226,7 +229,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
||||||
AddAllInHateList();
|
AddAllInHateList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if(targets.Count > 16)
|
||||||
|
targets.RemoveRange(16, targets.Count - 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -288,7 +293,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
||||||
|
|
||||||
private void AddAllBattleNpcs(Character target, bool withPet)
|
private void AddAllBattleNpcs(Character target, bool withPet)
|
||||||
{
|
{
|
||||||
var actors = owner.zone.GetActorsAroundActor<BattleNpc>(owner, 50);
|
int dist = (int)maxDistance;
|
||||||
|
var actors = owner.zone.GetActorsAroundActor<BattleNpc>(target, dist);
|
||||||
|
|
||||||
foreach (BattleNpc actor in actors)
|
foreach (BattleNpc actor in actors)
|
||||||
{
|
{
|
||||||
|
@ -375,12 +381,13 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai
|
||||||
private bool IsWithinCircle(Character target, float maxDistance)
|
private bool IsWithinCircle(Character target, float maxDistance)
|
||||||
{
|
{
|
||||||
// todo: make y diff modifiable?
|
// todo: make y diff modifiable?
|
||||||
if (Math.Abs(owner.positionX - target.positionY) > 6.0f)
|
|
||||||
return false;
|
//if (Math.Abs(owner.positionX - target.positionY) > 6.0f)
|
||||||
|
// return false;
|
||||||
|
|
||||||
if (this.targetPosition == null)
|
if (this.targetPosition == null)
|
||||||
this.targetPosition = aoeTarget == TargetFindAOETarget.Self ? owner.GetPosAsVector3() : masterTarget.GetPosAsVector3();
|
this.targetPosition = aoeTarget == TargetFindAOETarget.Self ? owner.GetPosAsVector3() : masterTarget.GetPosAsVector3();
|
||||||
return target.GetPosAsVector3().IsWithinCircle(targetPosition, param);
|
return target.GetPosAsVector3().IsWithinCircle(targetPosition, maxDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsPlayer(Character target)
|
private bool IsPlayer(Character target)
|
||||||
|
|
|
@ -15,7 +15,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||||
: base(owner, null)
|
: base(owner, null)
|
||||||
{
|
{
|
||||||
owner.Disengage();
|
owner.Disengage();
|
||||||
owner.ChangeState(SetActorStatePacket.MAIN_STATE_DEAD2);
|
//owner.ChangeState(SetActorStatePacket.MAIN_STATE_DEAD2);
|
||||||
|
var deathStatePacket = SetActorStatePacket.BuildPacket(owner.actorId, SetActorStatePacket.MAIN_STATE_DEAD, owner.currentSubState);
|
||||||
|
owner.zone.BroadcastPacketAroundActor(owner, deathStatePacket);
|
||||||
canInterrupt = false;
|
canInterrupt = false;
|
||||||
startTime = tick;
|
startTime = tick;
|
||||||
despawnTime = startTime.AddSeconds(timeToFadeOut);
|
despawnTime = startTime.AddSeconds(timeToFadeOut);
|
||||||
|
|
|
@ -110,16 +110,16 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||||
var i = 0;
|
var i = 0;
|
||||||
foreach (var chara in targets)
|
foreach (var chara in targets)
|
||||||
{
|
{
|
||||||
var action = new BattleAction(target.actorId, spell.worldMasterTextId, spell.battleAnimation, 0, (byte)HitDirection.None, 1);
|
var action = new BattleAction(chara.actorId, spell.worldMasterTextId, spell.battleAnimation, 0, (byte)HitDirection.None, 1);
|
||||||
action.amount = (ushort)lua.LuaEngine.CallLuaBattleCommandFunction(owner, spell, "magic", "onMagicFinish", owner, chara, spell, action);
|
action.amount = (ushort)lua.LuaEngine.CallLuaBattleCommandFunction(owner, spell, "magic", "onMagicFinish", owner, chara, spell, action);
|
||||||
actions[i++] = action;
|
actions[i++] = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: this is fuckin stupid, probably only need *one* error packet, not an error for each action
|
// todo: this is fuckin stupid, probably only need *one* error packet, not an error for each action
|
||||||
var errors = (BattleAction[])actions.Clone();
|
var errors = (BattleAction[])actions.Clone();
|
||||||
|
|
||||||
owner.OnCast(this, actions, ref errors);
|
owner.OnCast(this, actions, ref errors);
|
||||||
owner.DoBattleAction(spell.id, spell.battleAnimation, actions);
|
owner.DoBattleAction(spell.id, spell.battleAnimation, actions);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void TryInterrupt()
|
public override void TryInterrupt()
|
||||||
|
|
|
@ -88,7 +88,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||||
{
|
{
|
||||||
skill.targetFind.FindWithinArea(target, skill.validTarget, skill.aoeTarget);
|
skill.targetFind.FindWithinArea(target, skill.validTarget, skill.aoeTarget);
|
||||||
isCompleted = true;
|
isCompleted = true;
|
||||||
|
|
||||||
var targets = skill.targetFind.GetTargets();
|
var targets = skill.targetFind.GetTargets();
|
||||||
|
|
||||||
BattleAction[] actions = new BattleAction[targets.Count];
|
BattleAction[] actions = new BattleAction[targets.Count];
|
||||||
|
@ -100,11 +99,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.state
|
||||||
// evasion, miss, dodge, etc to be handled in script, calling helpers from scripts/weaponskills.lua
|
// evasion, miss, dodge, etc to be handled in script, calling helpers from scripts/weaponskills.lua
|
||||||
action.amount = (ushort)lua.LuaEngine.CallLuaBattleCommandFunction(owner, skill, "weaponskill", "onSkillFinish", owner, target, skill, action);
|
action.amount = (ushort)lua.LuaEngine.CallLuaBattleCommandFunction(owner, skill, "weaponskill", "onSkillFinish", owner, target, skill, action);
|
||||||
actions[i++] = action;
|
actions[i++] = action;
|
||||||
|
chara.Engage(chara.actorId, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: this is fuckin stupid, probably only need *one* error packet, not an error for each action
|
// todo: this is fuckin stupid, probably only need *one* error packet, not an error for each action
|
||||||
var errors = (BattleAction[])actions.Clone();
|
var errors = (BattleAction[])actions.Clone();
|
||||||
|
|
||||||
owner.OnWeaponSkill(this, actions, ref errors);
|
owner.OnWeaponSkill(this, actions, ref errors);
|
||||||
owner.DoBattleAction(skill.id, skill.battleAnimation, actions);
|
owner.DoBattleAction(skill.id, skill.battleAnimation, actions);
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,8 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.utils
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DamageTarget(Character attacker, Character defender, BattleAction action)
|
public static void DamageTarget(Character attacker, Character defender, BattleAction action)
|
||||||
|
{
|
||||||
|
if (defender != null)
|
||||||
{
|
{
|
||||||
// todo: other stuff too
|
// todo: other stuff too
|
||||||
if (defender is BattleNpc)
|
if (defender is BattleNpc)
|
||||||
|
@ -89,6 +91,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.ai.utils
|
||||||
}
|
}
|
||||||
defender.DelHP((short)action.amount);
|
defender.DelHP((short)action.amount);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static int CalculateSpellDamage(Character attacker, Character defender, BattleCommand spell)
|
public static int CalculateSpellDamage(Character attacker, Character defender, BattleCommand spell)
|
||||||
{
|
{
|
||||||
|
|
|
@ -177,7 +177,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
packets = new List<SubPacket>();
|
packets = new List<SubPacket>();
|
||||||
if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0)
|
if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0)
|
||||||
{
|
{
|
||||||
var propPacketUtil = new ActorPropertyPacketUtil("charaWork.parameterSave", this);
|
var propPacketUtil = new ActorPropertyPacketUtil("charaWork/stateAtQuicklyForAll", this);
|
||||||
|
|
||||||
propPacketUtil.AddProperty("charaWork.parameterSave.hp[0]");
|
propPacketUtil.AddProperty("charaWork.parameterSave.hp[0]");
|
||||||
propPacketUtil.AddProperty("charaWork.parameterSave.hpMax[0]");
|
propPacketUtil.AddProperty("charaWork.parameterSave.hpMax[0]");
|
||||||
|
@ -290,6 +290,10 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
|
|
||||||
if (lastAttacker is Player)
|
if (lastAttacker is Player)
|
||||||
{
|
{
|
||||||
|
//I think this is, or should be odne in DoBattleAction. Packet capture had the message in the same packet as an attack
|
||||||
|
// <actor> defeat/defeats <target>
|
||||||
|
//((Player)lastAttacker).QueuePacket(BattleActionX01Packet.BuildPacket(lastAttacker.actorId, 0, 0, new BattleAction(actorId, 30108, 0)));
|
||||||
|
|
||||||
if (lastAttacker.currentParty != null && lastAttacker.currentParty is Party)
|
if (lastAttacker.currentParty != null && lastAttacker.currentParty is Party)
|
||||||
{
|
{
|
||||||
foreach (var memberId in ((Party)lastAttacker.currentParty).members)
|
foreach (var memberId in ((Party)lastAttacker.currentParty).members)
|
||||||
|
@ -297,14 +301,9 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
var partyMember = zone.FindActorInArea<Player>(memberId);
|
var partyMember = zone.FindActorInArea<Player>(memberId);
|
||||||
// onDeath(monster, player, killer)
|
// onDeath(monster, player, killer)
|
||||||
lua.LuaEngine.CallLuaBattleFunction(this, "onDeath", this, partyMember, lastAttacker);
|
lua.LuaEngine.CallLuaBattleFunction(this, "onDeath", this, partyMember, lastAttacker);
|
||||||
// <actor> defeat/defeats <target>
|
|
||||||
|
|
||||||
if (lastAttacker is Player)
|
|
||||||
((Player)lastAttacker).QueuePacket(BattleActionX01Packet.BuildPacket(lastAttacker.actorId, 0, 0, new BattleAction(actorId, 30108, 0)));
|
|
||||||
|
|
||||||
if(partyMember is Player)
|
if(partyMember is Player)
|
||||||
((Player)partyMember).AddExp(1500, (byte)partyMember.GetJob(), 5);
|
((Player)partyMember).AddExp(1500, (byte)partyMember.GetClass(), 5);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -317,7 +316,6 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
positionUpdates?.Clear();
|
positionUpdates?.Clear();
|
||||||
aiContainer.InternalDie(tick, despawnTime);
|
aiContainer.InternalDie(tick, despawnTime);
|
||||||
this.ResetMoveSpeeds();
|
this.ResetMoveSpeeds();
|
||||||
|
|
||||||
// todo: reset cooldowns
|
// todo: reset cooldowns
|
||||||
|
|
||||||
lua.LuaEngine.GetInstance().OnSignal("mobkill");
|
lua.LuaEngine.GetInstance().OnSignal("mobkill");
|
||||||
|
@ -381,6 +379,9 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
|
|
||||||
if (GetMobMod((uint)MobModifier.AttackScript) != 0)
|
if (GetMobMod((uint)MobModifier.AttackScript) != 0)
|
||||||
lua.LuaEngine.CallLuaBattleFunction(this, "onAttack", this, state.GetTarget(), action.amount);
|
lua.LuaEngine.CallLuaBattleFunction(this, "onAttack", this, state.GetTarget(), action.amount);
|
||||||
|
|
||||||
|
if (target is BattleNpc)
|
||||||
|
((BattleNpc)target).hateContainer.UpdateHate(this, action.amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnCast(State state, BattleAction[] actions, ref BattleAction[] errors)
|
public override void OnCast(State state, BattleAction[] actions, ref BattleAction[] errors)
|
||||||
|
@ -390,6 +391,19 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
if (GetMobMod((uint)MobModifier.SpellScript) != 0)
|
if (GetMobMod((uint)MobModifier.SpellScript) != 0)
|
||||||
foreach (var action in actions)
|
foreach (var action in actions)
|
||||||
lua.LuaEngine.CallLuaBattleFunction(this, "onCast", this, zone.FindActorInArea<Character>(action.targetId), ((MagicState)state).GetSpell(), action);
|
lua.LuaEngine.CallLuaBattleFunction(this, "onCast", this, zone.FindActorInArea<Character>(action.targetId), ((MagicState)state).GetSpell(), action);
|
||||||
|
|
||||||
|
foreach (BattleAction action in actions)
|
||||||
|
{
|
||||||
|
if (zone.FindActorInArea<Character>(action.targetId) is Character chara)
|
||||||
|
{
|
||||||
|
if (chara is BattleNpc)
|
||||||
|
{
|
||||||
|
((BattleNpc)chara).hateContainer.UpdateHate(this, action.amount);
|
||||||
|
((BattleNpc)chara).lastAttacker = this;
|
||||||
|
}
|
||||||
|
BattleUtils.DamageTarget(this, chara, action);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnAbility(State state, BattleAction[] actions, ref BattleAction[] errors)
|
public override void OnAbility(State state, BattleAction[] actions, ref BattleAction[] errors)
|
||||||
|
|
|
@ -32,5 +32,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.npc
|
||||||
AbilityScript = 21, // call my script's onAbility whenever i finish using an ability
|
AbilityScript = 21, // call my script's onAbility whenever i finish using an ability
|
||||||
CallForHelp = 22, // actor with this id outside of target's party with this can attack me
|
CallForHelp = 22, // actor with this id outside of target's party with this can attack me
|
||||||
FreeForAll = 23, // any actor can attack me
|
FreeForAll = 23, // any actor can attack me
|
||||||
|
Roams = 24, // Do I walk around?
|
||||||
|
RoamDelay = 25 // What is the delay between roam ticks
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -557,6 +557,9 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
|
|
||||||
if (currentContentGroup != null)
|
if (currentContentGroup != null)
|
||||||
currentContentGroup.SendGroupPackets(playerSession);
|
currentContentGroup.SendGroupPackets(playerSession);
|
||||||
|
|
||||||
|
if (currentParty != null)
|
||||||
|
currentParty.SendGroupPackets(playerSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendRemoveInventoryPackets(List<ushort> slots)
|
private void SendRemoveInventoryPackets(List<ushort> slots)
|
||||||
|
@ -1714,6 +1717,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
//currentParty.members.Remove(this);
|
//currentParty.members.Remove(this);
|
||||||
if (partyGroup.members.Count == 0)
|
if (partyGroup.members.Count == 0)
|
||||||
Server.GetWorldManager().NoMembersInParty((Party)currentParty);
|
Server.GetWorldManager().NoMembersInParty((Party)currentParty);
|
||||||
|
|
||||||
currentParty = null;
|
currentParty = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1755,7 +1759,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
|
|
||||||
if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0)
|
if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0)
|
||||||
{
|
{
|
||||||
var propPacketUtil = new ActorPropertyPacketUtil("charaWork.parameterSave", this);
|
var propPacketUtil = new ActorPropertyPacketUtil("charaWork/stateAtQuicklyForAll", this);
|
||||||
|
|
||||||
// todo: should this be using job as index?
|
// todo: should this be using job as index?
|
||||||
propPacketUtil.AddProperty($"charaWork.parameterSave.hp[{0}]");
|
propPacketUtil.AddProperty($"charaWork.parameterSave.hp[{0}]");
|
||||||
|
@ -1768,9 +1772,6 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
}
|
}
|
||||||
|
|
||||||
base.PostUpdate(tick, packets);
|
base.PostUpdate(tick, packets);
|
||||||
SetActorPropetyPacket hpInfo = new SetActorPropetyPacket("charaWork/exp");
|
|
||||||
hpInfo.AddTarget();
|
|
||||||
QueuePacket(hpInfo.BuildPacket(actorId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Die(DateTime tick)
|
public override void Die(DateTime tick)
|
||||||
|
@ -1801,7 +1802,6 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
public void UpdateHotbarCommands(List<ushort> slotsToUpdate)
|
public void UpdateHotbarCommands(List<ushort> slotsToUpdate)
|
||||||
{
|
{
|
||||||
ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/command", this);
|
ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/command", this);
|
||||||
ActorPropertyPacketUtil compatibiltyUtil = new ActorPropertyPacketUtil("charaWork/commandDetailForSelf", this);
|
|
||||||
foreach (ushort slot in slotsToUpdate)
|
foreach (ushort slot in slotsToUpdate)
|
||||||
{
|
{
|
||||||
propPacketUtil.AddProperty($"charaWork.command[{slot}]");
|
propPacketUtil.AddProperty($"charaWork.command[{slot}]");
|
||||||
|
@ -2184,9 +2184,9 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
{
|
{
|
||||||
// todo: update hotbar timers to skill's recast time (also needs to be done on class change or equip crap)
|
// todo: update hotbar timers to skill's recast time (also needs to be done on class change or equip crap)
|
||||||
base.OnCast(state, actions, ref errors);
|
base.OnCast(state, actions, ref errors);
|
||||||
|
|
||||||
var spell = ((MagicState)state).GetSpell();
|
var spell = ((MagicState)state).GetSpell();
|
||||||
// todo: should just make a thing that updates the one slot cause this is dumb as hell
|
// todo: should just make a thing that updates the one slot cause this is dumb as hell
|
||||||
|
|
||||||
UpdateHotbarTimer(spell.id, spell.recastTimeSeconds);
|
UpdateHotbarTimer(spell.id, spell.recastTimeSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2300,11 +2300,11 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
Database.LoadHotbar(this);
|
Database.LoadHotbar(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Gets the id of the player's current job. If they aren't a job, gets the id of their class
|
||||||
public byte GetCurrentClassOrJob()
|
public byte GetCurrentClassOrJob()
|
||||||
{
|
{
|
||||||
if (currentJob != 0)
|
if (currentJob != 0)
|
||||||
return (byte) currentJob;
|
return (byte) currentJob;
|
||||||
|
|
||||||
return charaWork.parameterSave.state_mainSkill[0];
|
return charaWork.parameterSave.state_mainSkill[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2315,12 +2315,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
mpMaxBase = (ushort)hp;
|
mpMaxBase = (ushort)hp;
|
||||||
charaWork.parameterSave.mpMax = (short)hp;
|
charaWork.parameterSave.mpMax = (short)hp;
|
||||||
charaWork.parameterSave.mp = (short)hp;
|
charaWork.parameterSave.mp = (short)hp;
|
||||||
AddTP(0);
|
AddTP(3000);
|
||||||
//SendCharaExpInfo();
|
updateFlags |= ActorUpdateFlags.HpTpMp;
|
||||||
//ActorPropertyPacketUtil exp = new ActorPropertyPacketUtil("charaWork/exp", this);
|
|
||||||
SetActorPropetyPacket hpInfo = new SetActorPropetyPacket("charaWork/exp");
|
|
||||||
hpInfo.AddTarget();
|
|
||||||
QueuePacket(hpInfo.BuildPacket(actorId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,6 +161,9 @@ namespace FFXIVClassic_Map_Server.actors.director
|
||||||
{
|
{
|
||||||
members.Add(actor);
|
members.Add(actor);
|
||||||
|
|
||||||
|
if (actor is Player)
|
||||||
|
((Player)actor).AddDirector(this);
|
||||||
|
|
||||||
if (contentGroup != null)
|
if (contentGroup != null)
|
||||||
contentGroup.AddMember(actor);
|
contentGroup.AddMember(actor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ namespace FFXIVClassic_Map_Server.actors.group
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
isStarted = true;
|
isStarted = true;
|
||||||
|
|
||||||
SendGroupPacketsAll(members);
|
SendGroupPacketsAll(members);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +51,7 @@ namespace FFXIVClassic_Map_Server.actors.group
|
||||||
if (actor == null)
|
if (actor == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if(!members.Contains(actor.actorId))
|
||||||
members.Add(actor.actorId);
|
members.Add(actor.actorId);
|
||||||
|
|
||||||
if (actor is Character)
|
if (actor is Character)
|
||||||
|
@ -121,7 +123,6 @@ namespace FFXIVClassic_Map_Server.actors.group
|
||||||
}
|
}
|
||||||
|
|
||||||
session.QueuePacket(GroupMembersEndPacket.buildPacket(session.id, session.GetActor().zoneId, time, this));
|
session.QueuePacket(GroupMembersEndPacket.buildPacket(session.id, session.GetActor().zoneId, time, this));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override uint GetTypeId()
|
public override uint GetTypeId()
|
||||||
|
|
|
@ -64,11 +64,23 @@ namespace FFXIVClassic_Map_Server.actors.group
|
||||||
groupMembers.Add(new GroupMember(id, -1, 0, false, true, Server.GetWorldManager().GetActorInWorld(id).customDisplayName));
|
groupMembers.Add(new GroupMember(id, -1, 0, false, true, Server.GetWorldManager().GetActorInWorld(id).customDisplayName));
|
||||||
foreach (uint charaId in members)
|
foreach (uint charaId in members)
|
||||||
{
|
{
|
||||||
if (charaId != id)
|
var chara = Server.GetWorldManager().GetActorInWorld(charaId);
|
||||||
groupMembers.Add(new GroupMember(charaId, -1, 0, false, true, Server.GetWorldManager().GetActorInWorld(charaId).customDisplayName));
|
if (charaId != id && chara != null)
|
||||||
|
groupMembers.Add(new GroupMember(charaId, -1, 0, false, true, chara.customDisplayName));
|
||||||
}
|
}
|
||||||
return groupMembers;
|
return groupMembers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddMember(uint memberId)
|
||||||
|
{
|
||||||
|
members.Add(memberId);
|
||||||
|
SendGroupPacketsAll(members);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveMember(uint memberId)
|
||||||
|
{
|
||||||
|
members.Remove(memberId);
|
||||||
|
SendGroupPacketsAll(members);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
|
|
||||||
public void FlushQueuedSendPackets()
|
public void FlushQueuedSendPackets()
|
||||||
{
|
{
|
||||||
if (!socket.Connected)
|
if (socket == null || !socket.Connected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (SendPacketQueue.Count > 0)
|
while (SendPacketQueue.Count > 0)
|
||||||
|
|
|
@ -477,12 +477,20 @@ namespace FFXIVClassic_Map_Server.lua
|
||||||
if (script != null)
|
if (script != null)
|
||||||
{
|
{
|
||||||
if (!script.Globals.Get(funcName).IsNil())
|
if (!script.Globals.Get(funcName).IsNil())
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
Coroutine coroutine = script.CreateCoroutine(script.Globals[funcName]).Coroutine;
|
Coroutine coroutine = script.CreateCoroutine(script.Globals[funcName]).Coroutine;
|
||||||
DynValue value = coroutine.Resume(args2);
|
DynValue value = coroutine.Resume(args2);
|
||||||
ResolveResume(player, coroutine, value);
|
ResolveResume(player, coroutine, value);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
player.SendMessage(0x20, "", e.Message);
|
||||||
|
player.EndEvent();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!optional)
|
if (!optional)
|
||||||
|
|
|
@ -112,7 +112,6 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
string[] split = name.Split('.');
|
string[] split = name.Split('.');
|
||||||
int arrayIndex = 0;
|
int arrayIndex = 0;
|
||||||
|
|
||||||
if (!(split[0].Equals("work") || split[0].Equals("charaWork") || split[0].Equals("playerWork") || split[0].Equals("npcWork") || split[0].Equals("guildleveWork")))
|
if (!(split[0].Equals("work") || split[0].Equals("charaWork") || split[0].Equals("playerWork") || split[0].Equals("npcWork") || split[0].Equals("guildleveWork")))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -35,27 +35,27 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||||
binWriter.Write((UInt16)commandId);
|
binWriter.Write((UInt16)commandId);
|
||||||
binWriter.Write((UInt16)0x810); //?
|
binWriter.Write((UInt16)0x810); //?
|
||||||
|
|
||||||
binWriter.Seek(0x58, SeekOrigin.Begin);
|
binWriter.Seek(0x28, SeekOrigin.Begin);
|
||||||
for (int i = 0; i < max; i++)
|
for (int i = 0; i < max; i++)
|
||||||
binWriter.Write((UInt32)actionList[listOffset + i].targetId);
|
binWriter.Write((UInt32)actionList[listOffset + i].targetId);
|
||||||
|
|
||||||
binWriter.Seek(0xA0, SeekOrigin.Begin);
|
binWriter.Seek(0x70, SeekOrigin.Begin);
|
||||||
for (int i = 0; i < max; i++)
|
for (int i = 0; i < max; i++)
|
||||||
binWriter.Write((UInt16)actionList[listOffset + i].amount);
|
binWriter.Write((UInt16)actionList[listOffset + i].amount);
|
||||||
|
|
||||||
binWriter.Seek(0xC4, SeekOrigin.Begin);
|
binWriter.Seek(0x94, SeekOrigin.Begin);
|
||||||
for (int i = 0; i < max; i++)
|
for (int i = 0; i < max; i++)
|
||||||
binWriter.Write((UInt16)actionList[listOffset + i].worldMasterTextId);
|
binWriter.Write((UInt16)actionList[listOffset + i].worldMasterTextId);
|
||||||
|
|
||||||
binWriter.Seek(0xE8, SeekOrigin.Begin);
|
binWriter.Seek(0xB8, SeekOrigin.Begin);
|
||||||
for (int i = 0; i < max; i++)
|
for (int i = 0; i < max; i++)
|
||||||
binWriter.Write((UInt32)actionList[listOffset + i].effectId);
|
binWriter.Write((UInt32)actionList[listOffset + i].effectId);
|
||||||
|
|
||||||
binWriter.Seek(0x130, SeekOrigin.Begin);
|
binWriter.Seek(0x100, SeekOrigin.Begin);
|
||||||
for (int i = 0; i < max; i++)
|
for (int i = 0; i < max; i++)
|
||||||
binWriter.Write((Byte)actionList[listOffset + i].param);
|
binWriter.Write((Byte)actionList[listOffset + i].param);
|
||||||
|
|
||||||
binWriter.Seek(0x142, SeekOrigin.Begin);
|
binWriter.Seek(0x112, SeekOrigin.Begin);
|
||||||
for (int i = 0; i < max; i++)
|
for (int i = 0; i < max; i++)
|
||||||
binWriter.Write((Byte)actionList[listOffset + i].unknown);
|
binWriter.Write((Byte)actionList[listOffset + i].unknown);
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,10 @@ function allyGlobal.onDespawn(ally)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--tryAggro serves the same purpose for now, keeping this around just in case
|
||||||
function allyGlobal.HelpPlayers(ally, contentGroupCharas, pickRandomTarget)
|
function allyGlobal.HelpPlayers(ally, contentGroupCharas, pickRandomTarget)
|
||||||
if contentGroupCharas then
|
if contentGroupCharas and not ally.IsEngaged() then
|
||||||
for _, chara in pairs(contentGroupCharas) do
|
for chara in contentGroupCharas do
|
||||||
if chara then
|
if chara then
|
||||||
-- probably a player, or another ally
|
-- probably a player, or another ally
|
||||||
-- todo: queue support actions, heal, try pull hate off player etc
|
-- todo: queue support actions, heal, try pull hate off player etc
|
||||||
|
@ -44,12 +45,14 @@ function allyGlobal.HelpPlayers(ally, contentGroupCharas, pickRandomTarget)
|
||||||
-- do stuff
|
-- do stuff
|
||||||
if not ally.IsEngaged() then
|
if not ally.IsEngaged() then
|
||||||
if chara.IsEngaged() then
|
if chara.IsEngaged() then
|
||||||
allyGlobal.EngageTarget(ally, chara.target, nil)
|
allyGlobal.EngageTarget(ally, chara.target, nil);
|
||||||
|
break;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif chara.IsMonster() and chara.IsEngaged() then
|
elseif chara.IsMonster() and chara.IsEngaged() then
|
||||||
if not ally.IsEngaged() then
|
if not ally.IsEngaged() then
|
||||||
allyGlobal.EngageTarget(ally, chara.target, nil)
|
allyGlobal.EngageTarget(ally, chara, nil);
|
||||||
|
break;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -57,6 +60,36 @@ function allyGlobal.HelpPlayers(ally, contentGroupCharas, pickRandomTarget)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--Iterate over characters in contentGroup, if a player is in combat, assist them.
|
||||||
|
function allyGlobal.tryAggro(ally, contentGroupCharas)
|
||||||
|
local count = 0;
|
||||||
|
if contentGroupCharas and not ally.IsEngaged() then
|
||||||
|
for i = 0, #contentGroupCharas - 1 do
|
||||||
|
if contentGroupCharas[i] and ally then
|
||||||
|
if contentGroupCharas[i].IsPlayer() then
|
||||||
|
-- probably a player, or another ally
|
||||||
|
-- todo: queue support actions, heal, try pull hate off player etc
|
||||||
|
if contentGroupCharas[i].target then
|
||||||
|
if ally.aiContainer:GetTargetFind():CanTarget(contentGroupCharas[i].target) and contentGroupCharas[i].target.IsMonster() and contentGroupCharas[i].target.hateContainer:HasHateForTarget(contentGroupCharas[i]) then
|
||||||
|
-- do stuff
|
||||||
|
allyGlobal.EngageTarget(ally, contentGroupCharas[i].target, nil);
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
elseif contentGroupCharas[i].IsMonster() and contentGroupCharas[i].IsEngaged() then
|
||||||
|
if not ally.IsEngaged() then
|
||||||
|
print("Engaging monster that is engaged");
|
||||||
|
allyGlobal.EngageTarget(ally, contentGroupCharas[i], nil);
|
||||||
|
break;
|
||||||
|
end]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function allyGlobal.HealPlayer(ally, player)
|
function allyGlobal.HealPlayer(ally, player)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -67,14 +100,16 @@ end
|
||||||
|
|
||||||
function allyGlobal.EngageTarget(ally, target, contentGroupCharas)
|
function allyGlobal.EngageTarget(ally, target, contentGroupCharas)
|
||||||
if contentGroupCharas then
|
if contentGroupCharas then
|
||||||
for _, chara in pairs(contentGroupCharas) do
|
for chara in contentGroupCharas do
|
||||||
if chara.IsMonster() then
|
if chara.IsMonster() then
|
||||||
if chara.allegiance ~= ally.allegiance then
|
if chara.allegiance ~= ally.allegiance then
|
||||||
ally.Engage(chara)
|
ally.Engage(chara)
|
||||||
|
break;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif target then
|
elseif target then
|
||||||
ally.Engage(target)
|
ally.Engage(target)
|
||||||
|
ally.hateContainer.AddBaseHate(target);
|
||||||
end
|
end
|
||||||
end
|
end
|
13
data/scripts/commands/AbilityCure.lua
Normal file
13
data/scripts/commands/AbilityCure.lua
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
require("global")
|
||||||
|
|
||||||
|
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
local worldManager = GetWorldManager();
|
||||||
|
local shortCommandId = bit32.bxor(command, 2700083200);
|
||||||
|
local ability = worldManager:GetAbility(shortCommandId);
|
||||||
|
|
||||||
|
--player:PlayAnimation(ability.modelAnimation);
|
||||||
|
|
||||||
|
|
||||||
|
player:endEvent();
|
||||||
|
end
|
14
data/scripts/commands/ArrowReloadCommand.lua
Normal file
14
data/scripts/commands/ArrowReloadCommand.lua
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
require("global")
|
||||||
|
|
||||||
|
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
local worldManager = GetWorldManager();
|
||||||
|
--local shortCommandId = command.actorId;--bit32:bxor(command.actorId, 2700083200);
|
||||||
|
local ability = worldManager:GetAbility(command.actorId);
|
||||||
|
|
||||||
|
if ability then
|
||||||
|
player.SendBattleActionX01Packet(ability.modelAnimation, ability.effectAnimation, 0x756D, command.actorId, ability.animationType);
|
||||||
|
end
|
||||||
|
|
||||||
|
player:endEvent();
|
||||||
|
end
|
14
data/scripts/commands/AttackAbility.lua
Normal file
14
data/scripts/commands/AttackAbility.lua
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
require("global")
|
||||||
|
|
||||||
|
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
local worldManager = GetWorldManager();
|
||||||
|
--local shortCommandId = command.actorId;--bit32:bxor(command.actorId, 2700083200);
|
||||||
|
local ability = worldManager:GetAbility(command.actorId);
|
||||||
|
|
||||||
|
if ability then
|
||||||
|
player.SendBattleActionX01Packet(ability.modelAnimation, ability.effectAnimation, 0x756D, command.actorId, ability.animationType);
|
||||||
|
end
|
||||||
|
|
||||||
|
player:endEvent();
|
||||||
|
end
|
6
data/scripts/commands/ChangeJobCommand.lua
Normal file
6
data/scripts/commands/ChangeJobCommand.lua
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
function onEventStarted(player, caller, commandRequest, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
player:SetCurrentJob(17);
|
||||||
|
|
||||||
|
player:EndEvent();
|
||||||
|
end
|
3
data/scripts/commands/CureMagic.lua
Normal file
3
data/scripts/commands/CureMagic.lua
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
end
|
14
data/scripts/commands/CuregaMagic.lua
Normal file
14
data/scripts/commands/CuregaMagic.lua
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
require("global")
|
||||||
|
|
||||||
|
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
local worldManager = GetWorldManager();
|
||||||
|
--local shortCommandId = command.actorId;--bit32:bxor(command.actorId, 2700083200);
|
||||||
|
local ability = worldManager:GetAbility(command.actorId);
|
||||||
|
|
||||||
|
if ability then
|
||||||
|
player.SendBattleActionX01Packet(ability.modelAnimation, ability.effectAnimation, 0x756D, command.actorId, ability.animationType);
|
||||||
|
end
|
||||||
|
|
||||||
|
player:endEvent();
|
||||||
|
end
|
14
data/scripts/commands/EffectMagic.lua
Normal file
14
data/scripts/commands/EffectMagic.lua
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
require("global")
|
||||||
|
|
||||||
|
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
local worldManager = GetWorldManager();
|
||||||
|
--local shortCommandId = command.actorId;--bit32:bxor(command.actorId, 2700083200);
|
||||||
|
local ability = worldManager:GetBattleCommand(command.actorId);
|
||||||
|
|
||||||
|
if ability then
|
||||||
|
player.SendBattleActionX01Packet(ability.modelAnimation, ability.effectAnimation);
|
||||||
|
end
|
||||||
|
|
||||||
|
player:endEvent();
|
||||||
|
end
|
14
data/scripts/commands/EsunaMagic.lua
Normal file
14
data/scripts/commands/EsunaMagic.lua
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
require("global")
|
||||||
|
|
||||||
|
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
local worldManager = GetWorldManager();
|
||||||
|
--local shortCommandId = command.actorId;--bit32:bxor(command.actorId, 2700083200);
|
||||||
|
local ability = worldManager:GetAbility(command.actorId);
|
||||||
|
|
||||||
|
if ability then
|
||||||
|
player.SendBattleActionX01Packet(ability.modelAnimation, ability.effectAnimation, 0x756D, command.actorId, ability.animationType);
|
||||||
|
end
|
||||||
|
|
||||||
|
player:endEvent();
|
||||||
|
end
|
7
data/scripts/commands/PointSearchAbility.lua
Normal file
7
data/scripts/commands/PointSearchAbility.lua
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
|
||||||
|
player.Cast(command.actorId, targetActor);
|
||||||
|
player:endEvent();
|
||||||
|
end
|
14
data/scripts/commands/RaiseMagic.lua
Normal file
14
data/scripts/commands/RaiseMagic.lua
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
require("global")
|
||||||
|
|
||||||
|
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
local worldManager = GetWorldManager();
|
||||||
|
--local shortCommandId = command.actorId;--bit32:bxor(command.actorId, 2700083200);
|
||||||
|
local ability = worldManager:GetAbility(command.actorId);
|
||||||
|
|
||||||
|
if ability then
|
||||||
|
player.SendBattleActionX01Packet(ability.modelAnimation, ability.effectAnimation);
|
||||||
|
end
|
||||||
|
|
||||||
|
player:endEvent();
|
||||||
|
end
|
14
data/scripts/commands/ShotCommand.lua
Normal file
14
data/scripts/commands/ShotCommand.lua
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
require("global")
|
||||||
|
|
||||||
|
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
local worldManager = GetWorldManager();
|
||||||
|
--local shortCommandId = command.actorId;--bit32:bxor(command.actorId, 2700083200);
|
||||||
|
local ability = worldManager:GetAbility(command.actorId);
|
||||||
|
|
||||||
|
if ability then
|
||||||
|
player.SendBattleActionX01Packet(ability.modelAnimation, ability.effectAnimation);
|
||||||
|
end
|
||||||
|
|
||||||
|
player:endEvent();
|
||||||
|
end
|
14
data/scripts/commands/SongMagic.lua
Normal file
14
data/scripts/commands/SongMagic.lua
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
require("global")
|
||||||
|
|
||||||
|
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
|
||||||
|
|
||||||
|
local worldManager = GetWorldManager();
|
||||||
|
--local shortCommandId = command.actorId;--bit32:bxor(command.actorId, 2700083200);
|
||||||
|
local ability = worldManager:GetAbility(command.actorId);
|
||||||
|
|
||||||
|
if ability then
|
||||||
|
player.SendBattleActionX01Packet(ability.modelAnimation, ability.effectAnimation, 0x756D, command.actorId, ability.animationType);
|
||||||
|
end
|
||||||
|
|
||||||
|
player:endEvent();
|
||||||
|
end
|
|
@ -152,8 +152,11 @@ function onTrigger(player, argc, skillName, level)
|
||||||
--local x, y, z = player.GetPos();
|
--local x, y, z = player.GetPos();
|
||||||
for i = 1, 1 do
|
for i = 1, 1 do
|
||||||
|
|
||||||
local actor = player.GetZone().SpawnActor(2207303, 'ass', x, y, z, rot, 0, 0, true );
|
local actor = player.GetZone().SpawnActor(2104001, 'ass', x, y, z, rot, 0, 0, true );
|
||||||
|
|
||||||
|
if player.currentContentGroup then
|
||||||
|
player.currentContentGroup:AddMember(actor.actorId)
|
||||||
|
end
|
||||||
--actor.FollowTarget(player, 3.2);
|
--actor.FollowTarget(player, 3.2);
|
||||||
end;
|
end;
|
||||||
return;
|
return;
|
||||||
|
|
24
data/scripts/commands/magic/Distortion.lua
Normal file
24
data/scripts/commands/magic/Distortion.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
24
data/scripts/commands/magic/Healing Trap.lua
Normal file
24
data/scripts/commands/magic/Healing Trap.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
24
data/scripts/commands/magic/Homing Missle.lua
Normal file
24
data/scripts/commands/magic/Homing Missle.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
24
data/scripts/commands/magic/Return Trap.lua
Normal file
24
data/scripts/commands/magic/Return Trap.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
24
data/scripts/commands/magic/Stun II.lua
Normal file
24
data/scripts/commands/magic/Stun II.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
24
data/scripts/commands/magic/Stun.lua
Normal file
24
data/scripts/commands/magic/Stun.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
24
data/scripts/commands/magic/Transfer Trap.lua
Normal file
24
data/scripts/commands/magic/Transfer Trap.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
24
data/scripts/commands/magic/blizzard.lua
Normal file
24
data/scripts/commands/magic/blizzard.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
24
data/scripts/commands/magic/buff trap.lua
Normal file
24
data/scripts/commands/magic/buff trap.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
27
data/scripts/commands/magic/burst.lua
Normal file
27
data/scripts/commands/magic/burst.lua
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
require("global");
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(1000, 2500);
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
-- action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
27
data/scripts/commands/magic/fira.lua
Normal file
27
data/scripts/commands/magic/fira.lua
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
require("global");
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
-- action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
27
data/scripts/commands/magic/firaga.lua
Normal file
27
data/scripts/commands/magic/firaga.lua
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
require("global");
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(1000, 2500);
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
-- action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
27
data/scripts/commands/magic/fire.lua
Normal file
27
data/scripts/commands/magic/fire.lua
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
require("global");
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
-- action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
27
data/scripts/commands/magic/flare.lua
Normal file
27
data/scripts/commands/magic/flare.lua
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
require("global");
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(1000, 2500);
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
-- action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
27
data/scripts/commands/magic/freeze.lua
Normal file
27
data/scripts/commands/magic/freeze.lua
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
require("global");
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
-- action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
27
data/scripts/commands/magic/holy.lua
Normal file
27
data/scripts/commands/magic/holy.lua
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
require("global");
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(1000, 2500);
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
-- action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
24
data/scripts/commands/magic/thundaga.lua
Normal file
24
data/scripts/commands/magic/thundaga.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
24
data/scripts/commands/magic/thundara.lua
Normal file
24
data/scripts/commands/magic/thundara.lua
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
require("magic");
|
||||||
|
|
||||||
|
function onMagicPrepare(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicStart(caster, target, spell)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onMagicFinish(caster, target, spell, action)
|
||||||
|
local damage = math.random(10, 100);
|
||||||
|
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
26
data/scripts/commands/weaponskill/simian_thrash.lua
Normal file
26
data/scripts/commands/weaponskill/simian_thrash.lua
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
require("global");
|
||||||
|
|
||||||
|
function onSkillPrepare(caster, target, skill)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onSkillStart(caster, target, skill)
|
||||||
|
return 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function onSkillFinish(caster, target, skill, action)
|
||||||
|
local damage = math.random(0, 0);
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
action.worldMasterTextId = 0x765D;
|
||||||
|
|
||||||
|
-- todo: populate a global script with statuses and modifiers
|
||||||
|
-- magic.HandleAttackMagic(caster, target, spell, action)
|
||||||
|
-- action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
--action.effectId = bit32.bxor(0x8000000, spell.effectAnimation, 15636);
|
||||||
|
|
||||||
|
if target.hateContainer then
|
||||||
|
target.hateContainer.UpdateHate(caster, damage);
|
||||||
|
end;
|
||||||
|
return damage;
|
||||||
|
end;
|
|
@ -10,12 +10,12 @@ function onCreate(starterPlayer, contentArea, director)
|
||||||
--mob3 = contentArea:SpawnActor(2201407, "mob3", 375.125, 4.4, -703.591, -1.54);
|
--mob3 = contentArea:SpawnActor(2201407, "mob3", 375.125, 4.4, -703.591, -1.54);
|
||||||
yda = GetWorldManager().SpawnBattleNpcById(6, contentArea);
|
yda = GetWorldManager().SpawnBattleNpcById(6, contentArea);
|
||||||
papalymo = GetWorldManager().SpawnBattleNpcById(7, contentArea);
|
papalymo = GetWorldManager().SpawnBattleNpcById(7, contentArea);
|
||||||
yda:ChangeState(2);
|
--yda:ChangeState(2);
|
||||||
mob1 = GetWorldManager().SpawnBattleNpcById(3, contentArea);
|
mob1 = GetWorldManager().SpawnBattleNpcById(3, contentArea);
|
||||||
mob2 = GetWorldManager().SpawnBattleNpcById(4, contentArea);
|
mob2 = GetWorldManager().SpawnBattleNpcById(4, contentArea);
|
||||||
mob3 = GetWorldManager().SpawnBattleNpcById(5, contentArea);
|
mob3 = GetWorldManager().SpawnBattleNpcById(5, contentArea);
|
||||||
starterPlayer.currentParty.members:Add(yda.actorId);
|
starterPlayer.currentParty:AddMember(papalymo.actorId);
|
||||||
starterPlayer.currentParty.members:Add(papalymo.actorId);
|
starterPlayer.currentParty:AddMember(yda.actorId);
|
||||||
starterPlayer:SetMod(modifiersGlobal.MinimumHpLock, 1);
|
starterPlayer:SetMod(modifiersGlobal.MinimumHpLock, 1);
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,6 +35,47 @@ end
|
||||||
|
|
||||||
function onDestroy()
|
function onDestroy()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--Iterating over allies using the for...in syntax throws an except and lags the server.
|
||||||
|
--This function probably isn't needed either way, it does the smae thing as TryAggro in ally
|
||||||
|
function onUpdate(tick, area)
|
||||||
|
if area then
|
||||||
|
local players = area:GetPlayers()
|
||||||
|
local mobs = area:GetMonsters()
|
||||||
|
local allies = area:GetAllies()
|
||||||
|
local resumeChecks = true
|
||||||
|
for player in players do
|
||||||
|
if player then
|
||||||
|
local exitLoop = false
|
||||||
|
|
||||||
|
if allies then
|
||||||
|
for i = 0, #allies - 1 do
|
||||||
|
if allies[i] then
|
||||||
|
if not allies[i]:IsEngaged() then
|
||||||
|
if player:IsEngaged() and player.target then
|
||||||
|
|
||||||
|
allies[i].neutral = false
|
||||||
|
allies[i].isAutoAttackEnabled = true
|
||||||
|
allies[i]:SetMod(modifiersGlobal.Speed, 8)
|
||||||
|
allyGlobal.EngageTarget(allies[i], player.target)
|
||||||
|
exitLoop = true
|
||||||
|
break
|
||||||
|
-- todo: support scripted paths
|
||||||
|
elseif allies[i]:GetSpeed() > 0 then
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if exitLoop then
|
||||||
|
resumeChecks = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not resumeChecks then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -10,55 +10,71 @@ function init()
|
||||||
return "/Director/Quest/QuestDirectorMan0g001";
|
return "/Director/Quest/QuestDirectorMan0g001";
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--Should we be using this to spawn mobs and drop Simplecontent?
|
||||||
function onCreateContentArea(players, director, contentArea, contentGroup)
|
function onCreateContentArea(players, director, contentArea, contentGroup)
|
||||||
director:StartContentGroup();
|
director:StartContentGroup();
|
||||||
end
|
end
|
||||||
|
|
||||||
function onEventStarted(player, actor, triggerName)
|
function onEventStarted(player, actor, triggerName)
|
||||||
man0g0Quest = player:GetQuest("Man0g0");
|
man0g0Quest = player:GetQuest("Man0g0");
|
||||||
|
player:SendMessage(0x20, "", "Starting");
|
||||||
startTutorialMode(player);
|
startTutorialMode(player);
|
||||||
callClientFunction(player, "delegateEvent", player, man0g0Quest, "processTtrBtl001", nil, nil, nil);
|
callClientFunction(player, "delegateEvent", player, man0g0Quest, "processTtrBtl001", nil, nil, nil);
|
||||||
player:EndEvent();
|
player:EndEvent();
|
||||||
|
player:SendMessage(0x20, "", "Waiting for player active");
|
||||||
waitForSignal("playerActive");
|
waitForSignal("playerActive");
|
||||||
|
player:SendMessage(0x20, "", "player active");
|
||||||
wait(1); --If this isn't here, the scripts bugs out. TODO: Find a better alternative.
|
wait(1); --If this isn't here, the scripts bugs out. TODO: Find a better alternative.
|
||||||
kickEventContinue(player, actor, "noticeEvent", "noticeEvent");
|
kickEventContinue(player, actor, "noticeEvent", "noticeEvent");
|
||||||
callClientFunction(player, "delegateEvent", player, man0g0Quest, "processTtrBtl002", nil, nil, nil);
|
callClientFunction(player, "delegateEvent", player, man0g0Quest, "processTtrBtl002", nil, nil, nil);
|
||||||
|
player:SendMessage(0x20, "", "processTtrBtl002 called");
|
||||||
player:EndEvent();
|
player:EndEvent();
|
||||||
|
|
||||||
|
--Combat portion of tutorial
|
||||||
|
if player:IsDiscipleOfWar() then
|
||||||
waitForSignal("playerAttack");
|
waitForSignal("playerAttack");
|
||||||
closeTutorialWidget(player);
|
closeTutorialWidget(player);
|
||||||
showTutorialSuccessWidget(player, 9055); --Open TutorialSuccessWidget for attacking enemy
|
showTutorialSuccessWidget(player, 9055); --Open TutorialSuccessWidget for attacking enemy
|
||||||
wait(3);
|
|
||||||
openTutorialWidget(player, CONTROLLER_KEYBOARD, TUTORIAL_TP);
|
openTutorialWidget(player, CONTROLLER_KEYBOARD, TUTORIAL_TP);
|
||||||
waitForSignal("tpOver1000");
|
waitForSignal("tpOver1000");
|
||||||
closeTutorialWidget(player);
|
closeTutorialWidget(player);
|
||||||
openTutorialWidget(player, CONTROLLER_KEYBOARD, TUTORIAL_WEAPONSKILLS);
|
openTutorialWidget(player, CONTROLLER_KEYBOARD, TUTORIAL_WEAPONSKILLS);
|
||||||
|
waitForSignal("weaponskillUsed");
|
||||||
if player:IsDiscipleOfWar() then
|
|
||||||
waitForSignal("weaponskillUsed"); --Should be wait for weaponskillUsed signal
|
|
||||||
elseif player:IsDiscipleOfMagic() then
|
|
||||||
waitForSignal("spellUsed")
|
|
||||||
elseif player:IsDiscipleOfHand() then
|
|
||||||
waitForSignal("abilityUsed")
|
|
||||||
elseif player:IsDiscipleOfLand() then
|
|
||||||
waitForSignal("abilityUsed")
|
|
||||||
end
|
|
||||||
closeTutorialWidget(player);
|
closeTutorialWidget(player);
|
||||||
showTutorialSuccessWidget(player, 9065); --Open TutorialSuccessWidget for weapon skill
|
showTutorialSuccessWidget(player, 9065); --Open TutorialSuccessWidget for weapon skill
|
||||||
|
elseif player:IsDiscipleOfMagic() then
|
||||||
|
openTutorialWidget(player, CONTROLLER_KEYBOARD, TUTORIAL_CASTING);
|
||||||
|
waitForSignal("spellUsed");
|
||||||
|
closeTutorialWidget(player);
|
||||||
|
elseif player:IsDiscipleOfHand() then
|
||||||
|
waitForSignal("abilityUsed");
|
||||||
|
elseif player:IsDiscipleOfLand() then
|
||||||
|
waitForSignal("abilityUsed");
|
||||||
|
end
|
||||||
|
|
||||||
waitForSignal("mobkill"); --Should be wait for mobkill
|
--Currently this requires the player to pass all the other signals first, need a way for signals to work out of order
|
||||||
|
waitForSignal("mobkill");
|
||||||
waitForSignal("mobkill");
|
waitForSignal("mobkill");
|
||||||
waitForSignal("mobkill");
|
waitForSignal("mobkill");
|
||||||
worldMaster = GetWorldMaster();
|
worldMaster = GetWorldMaster();
|
||||||
|
wait(5);--Debug waits, get rid of these later
|
||||||
|
player:Disengage(0x0000);
|
||||||
|
wait(5);
|
||||||
|
man0g0Quest:NextPhase(10);
|
||||||
|
wait(5);
|
||||||
|
--This doesn't work
|
||||||
|
player:RemoveFromCurrentPartyAndCleanup();
|
||||||
player:SendDataPacket("attention", worldMaster, "", 51073, 2);
|
player:SendDataPacket("attention", worldMaster, "", 51073, 2);
|
||||||
wait(7);
|
wait(5);
|
||||||
player:ChangeMusic(7);
|
player:ChangeMusic(7);
|
||||||
player:ChangeState(0);
|
wait(5);
|
||||||
kickEventContinue(player, actor, "noticeEvent", "noticeEvent");
|
kickEventContinue(player, actor, "noticeEvent", "noticeEvent");
|
||||||
|
wait(5);
|
||||||
callClientFunction(player, "delegateEvent", player, man0g0Quest, "processEvent020_1", nil, nil, nil);
|
callClientFunction(player, "delegateEvent", player, man0g0Quest, "processEvent020_1", nil, nil, nil);
|
||||||
|
wait(5);
|
||||||
player:GetZone():ContentFinished();
|
player:GetZone():ContentFinished();
|
||||||
player:EndEvent();
|
--player:EndEvent();
|
||||||
GetWorldManager():DoZoneChange(player, 155, "PrivateAreaMasterPast", 1, 15, 175.38, -1.21, -1156.51, -2.1);
|
--GetWorldManager():DoZoneChange(player, 155, "PrivateAreaMasterPast", 1, 15, 175.38, -1.21, -1156.51, -2.1);
|
||||||
--[[
|
--[[
|
||||||
IF DoW:
|
IF DoW:
|
||||||
OpenWidget (TP)
|
OpenWidget (TP)
|
||||||
|
@ -72,10 +88,9 @@ function onEventStarted(player, actor, triggerName)
|
||||||
OpenWidget (DEFEAT ENEMY)
|
OpenWidget (DEFEAT ENEMY)
|
||||||
]]
|
]]
|
||||||
|
|
||||||
--man0g0Quest:NextPhase(10);
|
player:EndEvent();
|
||||||
--player:EndEvent();
|
wait(5);
|
||||||
|
GetWorldManager():DoZoneChange(player, 155, "PrivateAreaMasterPast", 1, 15, 175.38, -1.21, -1156.51, -2.1);
|
||||||
--GetWorldManager():DoZoneChange(player, 155, "PrivateAreaMasterPast", 1, 15, 175.38, -1.21, -1156.51, -2.1);
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
79
data/scripts/modifiers.lua
Normal file
79
data/scripts/modifiers.lua
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
modifiersGlobal =
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Hp = 1,
|
||||||
|
HpPercent = 2,
|
||||||
|
Mp = 3,
|
||||||
|
MpPercent = 4,
|
||||||
|
Tp = 5,
|
||||||
|
TpPercent = 6,
|
||||||
|
Regen = 7,
|
||||||
|
Refresh = 8,
|
||||||
|
Strength = 9,
|
||||||
|
Vitality = 10,
|
||||||
|
Dexterity = 11,
|
||||||
|
Intelligence = 12,
|
||||||
|
Mind = 13,
|
||||||
|
Piety = 14,
|
||||||
|
Attack = 15,
|
||||||
|
Accuracy = 16,
|
||||||
|
Defense = 17,
|
||||||
|
Evasion = 18,
|
||||||
|
MagicAttack = 19,
|
||||||
|
MagicHeal = 20, -- is this needed? shouldnt it just be calc'd from mind
|
||||||
|
MagicAccuracy = 21,
|
||||||
|
MagicEvasion = 22,
|
||||||
|
MagicDefense = 23,
|
||||||
|
MagicEnhancePotency = 24,
|
||||||
|
MagicEnfeeblingPotency = 25,
|
||||||
|
ResistFire = 26,
|
||||||
|
ResistIce = 27,
|
||||||
|
ResistWind = 28,
|
||||||
|
ResistLightning = 29,
|
||||||
|
ResistEarth = 30,
|
||||||
|
ResistWater = 31, -- <3 u jorge
|
||||||
|
AttackRange = 32,
|
||||||
|
Speed = 33,
|
||||||
|
AttackDelay = 34,
|
||||||
|
|
||||||
|
CraftProcessing = 35,
|
||||||
|
CraftMagicProcessing = 36,
|
||||||
|
CraftProcessControl = 37,
|
||||||
|
|
||||||
|
HarvestPotency = 38,
|
||||||
|
HarvestLimit = 39,
|
||||||
|
HarvestRate = 40,
|
||||||
|
|
||||||
|
Raise = 41,
|
||||||
|
MinimumHpLock = 42, -- hp cannot fall below this value
|
||||||
|
}
|
||||||
|
|
||||||
|
mobModifiersGlobal =
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
SpawnLeash = 1, -- how far can i move before i deaggro target
|
||||||
|
SightRange = 2, -- how close does target need to be for me to detect by sight
|
||||||
|
SoundRange = 3, -- how close does target need to be for me to detect by sound
|
||||||
|
BuffChance = 4,
|
||||||
|
HealChance = 5,
|
||||||
|
SkillUseChance = 6,
|
||||||
|
LinkRadius = 7,
|
||||||
|
MagicDelay = 8,
|
||||||
|
SpecialDelay = 9,
|
||||||
|
ExpBonus = 10, --
|
||||||
|
IgnoreSpawnLeash = 11, -- pursue target forever
|
||||||
|
DrawIn = 12, -- do i suck people in around me
|
||||||
|
HpScale = 13, --
|
||||||
|
Assist = 14, -- gotta call the bois
|
||||||
|
NoMove = 15, -- cant move
|
||||||
|
ShareTarget = 16, -- use this actor's id as target id
|
||||||
|
AttackScript = 17, -- call my script's onAttack whenever i attack
|
||||||
|
DefendScript = 18, -- call my script's onDamageTaken whenever i take damage
|
||||||
|
SpellScript = 19, -- call my script's onSpellCast whenever i finish casting
|
||||||
|
WeaponskillScript = 20, -- call my script's onWeaponSkill whenever i finish using a weaponskill
|
||||||
|
AbilityScript = 21, -- call my script's onAbility whenever i finish using an ability
|
||||||
|
CallForHelp = 22, -- actor with this id outside of target's party with this can attack me
|
||||||
|
FreeForAll = 23, -- any actor can attack me
|
||||||
|
Roams = 24, -- Do I walk around?
|
||||||
|
RoamDelay = 25 -- What is the delay between roam ticks
|
||||||
|
}
|
|
@ -20,3 +20,8 @@ function onRoam(ally, contentGroupCharas)
|
||||||
ally.animationId = 0
|
ally.animationId = 0
|
||||||
allyGlobal.onCombatTick(ally, nil, nil, contentGroupCharas)
|
allyGlobal.onCombatTick(ally, nil, nil, contentGroupCharas)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function tryAggro(ally, contentGroupCharas)
|
||||||
|
allyGlobal.tryAggro(ally, contentGroupCharas)
|
||||||
|
end
|
|
@ -13,10 +13,14 @@ function onCombatTick(ally, target, tick, contentGroupCharas)
|
||||||
allyGlobal.onCombatTick(ally, target, tick, contentGroupCharas)
|
allyGlobal.onCombatTick(ally, target, tick, contentGroupCharas)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function tryAggro(ally, contentGroupCharas)
|
||||||
|
allyGlobal.tryAggro(ally, contentGroupCharas)
|
||||||
|
end
|
||||||
|
|
||||||
function onRoam(ally, contentGroupCharas)
|
function onRoam(ally, contentGroupCharas)
|
||||||
ally.detectionType = 0xFF
|
ally.detectionType = 0xFF
|
||||||
ally.isMovingToSpawn = false
|
ally.isMovingToSpawn = false
|
||||||
ally.neutral = false
|
ally.neutral = false
|
||||||
ally.animationId = 0
|
ally.animationId = 0
|
||||||
allyGlobal.onCombatTick(ally, contentGroupCharas)
|
--allyGlobal.onCombatTick(ally, contentGroupCharas)
|
||||||
end
|
end
|
|
@ -7,10 +7,9 @@ end
|
||||||
|
|
||||||
function onEventStarted(player, npc, triggerName)
|
function onEventStarted(player, npc, triggerName)
|
||||||
man0g0Quest = player:GetQuest("Man0g0");
|
man0g0Quest = player:GetQuest("Man0g0");
|
||||||
print("hi");
|
print("Got Quest Man0g0");
|
||||||
if (man0g0Quest ~= nil) then
|
if (man0g0Quest ~= nil) then
|
||||||
|
print("Man0g0Quest is not nil");
|
||||||
print("hi2");
|
|
||||||
if (triggerName == "pushDefault") then
|
if (triggerName == "pushDefault") then
|
||||||
callClientFunction(player, "delegateEvent", player, man0g0Quest, "processTtrNomal002", nil, nil, nil);
|
callClientFunction(player, "delegateEvent", player, man0g0Quest, "processTtrNomal002", nil, nil, nil);
|
||||||
elseif (triggerName == "talkDefault") then
|
elseif (triggerName == "talkDefault") then
|
||||||
|
@ -23,8 +22,8 @@ function onEventStarted(player, npc, triggerName)
|
||||||
man0g0Quest:SaveData();
|
man0g0Quest:SaveData();
|
||||||
player:GetDirector("OpeningDirector"):onTalkEvent(player, npc);
|
player:GetDirector("OpeningDirector"):onTalkEvent(player, npc);
|
||||||
--Was she talked to after papalymo?
|
--Was she talked to after papalymo?
|
||||||
print("hi3");
|
|
||||||
else
|
else
|
||||||
|
print("Making content area");
|
||||||
if (man0g0Quest:GetQuestFlag(MAN0G0_FLAG_MINITUT_DONE1) == true) then
|
if (man0g0Quest:GetQuestFlag(MAN0G0_FLAG_MINITUT_DONE1) == true) then
|
||||||
|
|
||||||
player:EndEvent();
|
player:EndEvent();
|
||||||
|
@ -43,8 +42,9 @@ function onEventStarted(player, npc, triggerName)
|
||||||
player:KickEvent(director, "noticeEvent", true);
|
player:KickEvent(director, "noticeEvent", true);
|
||||||
player:SetLoginDirector(director);
|
player:SetLoginDirector(director);
|
||||||
|
|
||||||
print("hi5");
|
print("Content area and director made");
|
||||||
GetWorldManager():DoZoneChangeContent(player, contentArea, 362.4087, 4, -703.8168, 1.5419, 16);
|
GetWorldManager():DoZoneChangeContent(player, contentArea, 362.4087, 4, -703.8168, 1.5419, 16);
|
||||||
|
print("Zone Change");
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
callClientFunction(player, "delegateEvent", player, man0g0Quest, "processEvent000_1", nil, nil, nil);
|
callClientFunction(player, "delegateEvent", player, man0g0Quest, "processEvent000_1", nil, nil, nil);
|
||||||
|
|
Loading…
Add table
Reference in a new issue