1
0

Added Lua Functions PlayAnimationString(Spawn: Spawn, String: EmoteStringCommand, Spawn: OptTarget, Boolean: SetNoTarget, Boolean: UseAllSpellTargets, Boolean: IgnoreSelf) and GetSpellTargets(Optional_Spell) if no argument must be in spell script. Fixed spells with no range that are group based to apply to all in group.

This commit is contained in:
Emagi 2025-01-10 19:08:47 -05:00
parent c24f0c89fc
commit 3162106580
6 changed files with 133 additions and 46 deletions

View File

@ -7134,6 +7134,39 @@ int EQ2Emu_lua_PlayAnimation(lua_State* state) {
return 0; return 0;
} }
int EQ2Emu_lua_PlayAnimationString(lua_State* state) {
if (!lua_interface)
return 0;
Spawn* spawn = lua_interface->GetSpawn(state);
std::string name = lua_interface->GetStringValue(state, 2);
Spawn* opt_target = lua_interface->GetSpawn(state, 3);
bool set_no_target = lua_interface->GetBooleanValue(state, 4);
bool use_all_spelltargets = lua_interface->GetBooleanValue(state, 5);
bool ignore_self = lua_interface->GetBooleanValue(state, 6);
LuaSpell* spell = lua_interface->GetCurrentSpell(state);
if (!spawn) {
lua_interface->LogError("%s: LUA PlayAnimationString command error: spawn is not valid", lua_interface->GetScriptName(state));
return 0;
}
if (spell && spell->caster && spell->caster->GetZone() && use_all_spelltargets) {
Spawn* target;
spell->MSpellTargets.readlock(__FUNCTION__, __LINE__);
for (int8 i = 0; i < spell->targets.size(); i++) {
target = spell->caster->GetZone()->GetSpawnByID(spell->targets.at(i));
if(target && (!ignore_self || spawn != target)) {
spell->caster->GetZone()->HandleEmote(target, name, opt_target, set_no_target);
}
}
spell->MSpellTargets.releasereadlock(__FUNCTION__, __LINE__);
}
else {
spawn->GetZone()->HandleEmote(spawn, name, opt_target, set_no_target);
}
return 0;
}
int EQ2Emu_lua_IsPet(lua_State* state) { int EQ2Emu_lua_IsPet(lua_State* state) {
if (!lua_interface) if (!lua_interface)
return 0; return 0;
@ -14254,6 +14287,44 @@ int EQ2Emu_lua_GetSpellInitialTarget(lua_State* state) {
return 0; return 0;
} }
int EQ2Emu_lua_GetSpellTargets(lua_State* state) {
if (!lua_interface)
return 0;
LuaSpell* spell = lua_interface->GetSpell(state);
if(!spell) {
spell = lua_interface->GetCurrentSpell(state);
}
lua_interface->ResetFunctionStack(state);
if (spell) {
if(!spell->caster) {
lua_interface->LogError("%s: LUA GetSpellTargets command error, caster does not exist.", lua_interface->GetScriptName(state));
return 0;
}
if(!spell->caster->GetZone()) {
lua_interface->LogError("%s: LUA GetSpellTargets command error, zone does not exist.", lua_interface->GetScriptName(state));
return 0;
}
if (spell && spell->caster) {
ZoneServer* zone = spell->caster->GetZone();
spell->MSpellTargets.readlock(__FUNCTION__, __LINE__);
lua_createtable(state, spell->targets.size(), 0);
int newTable = lua_gettop(state);
for (int32 i = 0; i < spell->targets.size(); i++) {
Spawn* spawn = zone->GetSpawnByID(spell->targets.at(i));
lua_interface->SetSpawnValue(state, spawn);
lua_rawseti(state, newTable, i + 1);
}
spell->MSpellTargets.releasereadlock(__FUNCTION__, __LINE__);
return 1;
}
}
return 0;
}
int EQ2Emu_lua_DespawnByLocationID(lua_State* state) { int EQ2Emu_lua_DespawnByLocationID(lua_State* state) {
ZoneServer* zone = lua_interface->GetZone(state); ZoneServer* zone = lua_interface->GetZone(state);
int32 location_id = lua_interface->GetInt32Value(state, 2); int32 location_id = lua_interface->GetInt32Value(state, 2);

View File

@ -202,6 +202,7 @@ int EQ2Emu_lua_PlayFlavorID(lua_State* state);
int EQ2Emu_lua_PlaySound(lua_State* state); int EQ2Emu_lua_PlaySound(lua_State* state);
int EQ2Emu_lua_PlayVoice(lua_State* state); int EQ2Emu_lua_PlayVoice(lua_State* state);
int EQ2Emu_lua_PlayAnimation(lua_State* state); int EQ2Emu_lua_PlayAnimation(lua_State* state);
int EQ2Emu_lua_PlayAnimationString(lua_State* state);
int EQ2Emu_lua_AddLootItem(lua_State* state); int EQ2Emu_lua_AddLootItem(lua_State* state);
int EQ2Emu_lua_HasLootItem(lua_State* state); int EQ2Emu_lua_HasLootItem(lua_State* state);
int EQ2Emu_lua_RemoveLootItem(lua_State* state); int EQ2Emu_lua_RemoveLootItem(lua_State* state);
@ -658,6 +659,7 @@ int EQ2Emu_lua_GetCharacterFlag(lua_State* state);
int EQ2Emu_lua_ToggleCharacterFlag(lua_State* state); int EQ2Emu_lua_ToggleCharacterFlag(lua_State* state);
int EQ2Emu_lua_GetSpellInitialTarget(lua_State* state); int EQ2Emu_lua_GetSpellInitialTarget(lua_State* state);
int EQ2Emu_lua_GetSpellTargets(lua_State* state);
int EQ2Emu_lua_DespawnByLocationID(lua_State* state); int EQ2Emu_lua_DespawnByLocationID(lua_State* state);

View File

@ -1114,6 +1114,7 @@ void LuaInterface::RegisterFunctions(lua_State* state) {
lua_register(state, "PlaySound", EQ2Emu_lua_PlaySound); lua_register(state, "PlaySound", EQ2Emu_lua_PlaySound);
lua_register(state, "PlayVoice", EQ2Emu_lua_PlayVoice); lua_register(state, "PlayVoice", EQ2Emu_lua_PlayVoice);
lua_register(state, "PlayAnimation", EQ2Emu_lua_PlayAnimation); lua_register(state, "PlayAnimation", EQ2Emu_lua_PlayAnimation);
lua_register(state, "PlayAnimationString", EQ2Emu_lua_PlayAnimationString);
lua_register(state, "AddLootItem", EQ2Emu_lua_AddLootItem); lua_register(state, "AddLootItem", EQ2Emu_lua_AddLootItem);
lua_register(state, "HasLootItem", EQ2Emu_lua_HasLootItem); lua_register(state, "HasLootItem", EQ2Emu_lua_HasLootItem);
lua_register(state, "RemoveLootItem", EQ2Emu_lua_RemoveLootItem); lua_register(state, "RemoveLootItem", EQ2Emu_lua_RemoveLootItem);
@ -1563,6 +1564,7 @@ void LuaInterface::RegisterFunctions(lua_State* state) {
lua_register(state, "ToggleCharacterFlag", EQ2Emu_lua_ToggleCharacterFlag); lua_register(state, "ToggleCharacterFlag", EQ2Emu_lua_ToggleCharacterFlag);
lua_register(state, "GetSpellInitialTarget", EQ2Emu_lua_GetSpellInitialTarget); lua_register(state, "GetSpellInitialTarget", EQ2Emu_lua_GetSpellInitialTarget);
lua_register(state, "GetSpellTargets", EQ2Emu_lua_GetSpellTargets);
lua_register(state,"DespawnByLocationID", EQ2Emu_lua_DespawnByLocationID); lua_register(state,"DespawnByLocationID", EQ2Emu_lua_DespawnByLocationID);

View File

@ -2583,7 +2583,7 @@ bool SpellProcess::GetPlayerGroupTargets(Player* target, Spawn* caster, LuaSpell
continue; continue;
else if (info && info->client && else if (info && info->client &&
info->client->GetPlayer()->GetZone() == ((Player*)target)->GetZone() && info->client->GetPlayer()->Alive() info->client->GetPlayer()->GetZone() == ((Player*)target)->GetZone() && info->client->GetPlayer()->Alive()
&& (bypassRangeChecks || caster->GetDistance((Entity*)info->client->GetPlayer()) <= luaspell->spell->GetSpellData()->range)) && (bypassRangeChecks || luaspell->spell->GetSpellData()->range == 0 || (luaspell->spell->GetSpellData()->range > 0 && caster->GetDistance((Entity*)info->client->GetPlayer()) <= luaspell->spell->GetSpellData()->range)))
{ {
AddSelfAndPet(luaspell, info->client->GetPlayer()); AddSelfAndPet(luaspell, info->client->GetPlayer());
} }
@ -2600,6 +2600,10 @@ bool SpellProcess::GetPlayerGroupTargets(Player* target, Spawn* caster, LuaSpell
void SpellProcess::GetSpellTargetsTrueAOE(LuaSpell* luaspell) { void SpellProcess::GetSpellTargetsTrueAOE(LuaSpell* luaspell) {
if (luaspell && luaspell->caster && luaspell->spell && luaspell->spell->GetSpellData()->max_aoe_targets > 0) { if (luaspell && luaspell->caster && luaspell->spell && luaspell->spell->GetSpellData()->max_aoe_targets > 0) {
if(luaspell->caster->IsPlayer() && luaspell->spell->GetSpellData()->affect_only_group_members) {
GetPlayerGroupTargets((Player*)luaspell->caster, luaspell->caster, luaspell);
}
else {
if (luaspell->caster->HasTarget() && luaspell->caster->GetTarget() != luaspell->caster){ if (luaspell->caster->HasTarget() && luaspell->caster->GetTarget() != luaspell->caster){
//Check if the caster has an implied target //Check if the caster has an implied target
if (luaspell->caster->GetDistance(luaspell->caster->GetTarget()) <= luaspell->spell->GetSpellData()->radius) if (luaspell->caster->GetDistance(luaspell->caster->GetTarget()) <= luaspell->spell->GetSpellData()->radius)
@ -2648,6 +2652,7 @@ void SpellProcess::GetSpellTargetsTrueAOE(LuaSpell* luaspell) {
} }
luaspell->MSpellTargets.releasewritelock(__FUNCTION__, __LINE__); luaspell->MSpellTargets.releasewritelock(__FUNCTION__, __LINE__);
} }
}
if (luaspell->targets.size() > 20) if (luaspell->targets.size() > 20)
LogWrite(SPELL__DEBUG, 0, "Spell", "Warning in SpellProcess::GetSpellTargetsTrueAOE Size of targets array is %u", luaspell->targets.size()); LogWrite(SPELL__DEBUG, 0, "Spell", "Warning in SpellProcess::GetSpellTargetsTrueAOE Size of targets array is %u", luaspell->targets.size());
} }

View File

@ -6822,12 +6822,19 @@ void ZoneServer::RemoveSpawnSupportFunctions(Spawn* spawn, bool lock_spell_proce
movement_spawns.erase(spawn->GetID()); movement_spawns.erase(spawn->GetID());
} }
void ZoneServer::HandleEmote(Spawn* originator, string name) { void ZoneServer::HandleEmote(Spawn* originator, string name, Spawn* opt_target, bool no_target) {
if (!originator) { if (!originator) {
LogWrite(ZONE__ERROR, 0, "Zone", "HandleEmote called with an invalid client"); LogWrite(ZONE__ERROR, 0, "Zone", "HandleEmote called with an invalid client");
return; return;
} }
Spawn* target = originator->GetTarget();
if(opt_target)
target = opt_target;
if(no_target) // override having a target
target = nullptr;
Client* orig_client = (originator->IsPlayer() && ((Player*)originator)->GetClient()) ? ((Player*)originator)->GetClient() : nullptr; Client* orig_client = (originator->IsPlayer() && ((Player*)originator)->GetClient()) ? ((Player*)originator)->GetClient() : nullptr;
Client* client = 0; Client* client = 0;
int32 cur_client_version = orig_client ? orig_client->GetVersion() : 546; int32 cur_client_version = orig_client ? orig_client->GetVersion() : 546;
@ -6875,10 +6882,10 @@ void ZoneServer::HandleEmote(Spawn* originator, string name) {
packet->setDataByName("spawn_id" , client->GetPlayer()->GetIDWithPlayerSpawn(originator)); packet->setDataByName("spawn_id" , client->GetPlayer()->GetIDWithPlayerSpawn(originator));
if(!emoteResponse){ if(!emoteResponse){
string message; string message;
if(originator->GetTarget() && originator->GetTarget()->GetID() != originator->GetID()){ if(target && target->GetID() != originator->GetID()){
message = emote->GetTargetedMessageString(); message = emote->GetTargetedMessageString();
if(message.find("%t") < 0xFFFFFFFF) if(message.find("%t") < 0xFFFFFFFF)
message.replace(message.find("%t"), 2, originator->GetTarget()->GetName()); message.replace(message.find("%t"), 2, target->GetName());
} }
if(message.length() == 0) if(message.length() == 0)
message = emote->GetMessageString(); message = emote->GetMessageString();

View File

@ -335,7 +335,7 @@ public:
void SendSpawnVisualState(Spawn* spawn, int16 type); void SendSpawnVisualState(Spawn* spawn, int16 type);
void SendSpellFailedPacket(Client* client, int16 error); void SendSpellFailedPacket(Client* client, int16 error);
void SendInterruptPacket(Spawn* interrupted, LuaSpell* spell, bool fizzle=false); void SendInterruptPacket(Spawn* interrupted, LuaSpell* spell, bool fizzle=false);
void HandleEmote(Spawn* originator, string name); void HandleEmote(Spawn* originator, string name, Spawn* opt_target = nullptr, bool no_target = false);
Spawn* GetSpawnByDatabaseID(int32 id); Spawn* GetSpawnByDatabaseID(int32 id);
Spawn* GetSpawnByID(int32 id, bool spawnListLocked=false); Spawn* GetSpawnByID(int32 id, bool spawnListLocked=false);