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:
parent
c24f0c89fc
commit
3162106580
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,53 +2600,58 @@ 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->HasTarget() && luaspell->caster->GetTarget() != luaspell->caster){
|
if(luaspell->caster->IsPlayer() && luaspell->spell->GetSpellData()->affect_only_group_members) {
|
||||||
//Check if the caster has an implied target
|
GetPlayerGroupTargets((Player*)luaspell->caster, luaspell->caster, luaspell);
|
||||||
if (luaspell->caster->GetDistance(luaspell->caster->GetTarget()) <= luaspell->spell->GetSpellData()->radius)
|
|
||||||
{
|
|
||||||
luaspell->initial_target = luaspell->caster->GetTarget()->GetID();
|
|
||||||
luaspell->initial_target_char_id = (luaspell->caster->GetTarget() && luaspell->caster->GetTarget()->IsPlayer()) ? ((Player*)luaspell->caster->GetTarget())->GetCharacterID() : 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
int32 ignore_target = 0;
|
else {
|
||||||
std::vector<std::pair<int32, float>> spawns = luaspell->caster->GetZone()->GetAttackableSpawnsByDistance(luaspell->caster, luaspell->spell->GetSpellData()->radius);
|
if (luaspell->caster->HasTarget() && luaspell->caster->GetTarget() != luaspell->caster){
|
||||||
luaspell->MSpellTargets.writelock(__FUNCTION__, __LINE__);
|
//Check if the caster has an implied target
|
||||||
int32 i = 0;
|
if (luaspell->caster->GetDistance(luaspell->caster->GetTarget()) <= luaspell->spell->GetSpellData()->radius)
|
||||||
for (const auto& pair : spawns) {
|
{
|
||||||
if (i == 0){
|
luaspell->initial_target = luaspell->caster->GetTarget()->GetID();
|
||||||
Spawn* spawn = luaspell->caster->GetZone()->GetSpawnByID(luaspell->initial_target);
|
luaspell->initial_target_char_id = (luaspell->caster->GetTarget() && luaspell->caster->GetTarget()->IsPlayer()) ? ((Player*)luaspell->caster->GetTarget())->GetCharacterID() : 0;
|
||||||
if (spawn && luaspell->initial_target && luaspell->caster->GetID() != luaspell->initial_target && luaspell->caster->AttackAllowed((Entity*)spawn)){
|
|
||||||
//this is the "Direct" target and aoe can't be avoided
|
|
||||||
AddLuaSpellTarget(luaspell, luaspell->initial_target, false);
|
|
||||||
ignore_target = luaspell->initial_target;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int32 ignore_target = 0;
|
||||||
i++;
|
std::vector<std::pair<int32, float>> spawns = luaspell->caster->GetZone()->GetAttackableSpawnsByDistance(luaspell->caster, luaspell->spell->GetSpellData()->radius);
|
||||||
|
luaspell->MSpellTargets.writelock(__FUNCTION__, __LINE__);
|
||||||
if (luaspell->targets.size() >= luaspell->spell->GetSpellData()->max_aoe_targets)
|
int32 i = 0;
|
||||||
break;
|
for (const auto& pair : spawns) {
|
||||||
|
if (i == 0){
|
||||||
int32 target_id = pair.first;
|
Spawn* spawn = luaspell->caster->GetZone()->GetSpawnByID(luaspell->initial_target);
|
||||||
Spawn* spawn = luaspell->caster->GetZone()->GetSpawnByID(target_id);
|
if (spawn && luaspell->initial_target && luaspell->caster->GetID() != luaspell->initial_target && luaspell->caster->AttackAllowed((Entity*)spawn)){
|
||||||
if(!spawn) {
|
//this is the "Direct" target and aoe can't be avoided
|
||||||
LogWrite(SPELL__ERROR, 0, "Spell", "Error: Spell target is NULL! SpellProcess::ProcessSpell for Spell '%s' target id %u", (luaspell->spell != nullptr) ? luaspell->spell->GetName() : "Unknown", target_id);
|
AddLuaSpellTarget(luaspell, luaspell->initial_target, false);
|
||||||
}
|
ignore_target = luaspell->initial_target;
|
||||||
//If we have already added this spawn, check the next spawn in the list
|
}
|
||||||
if (spawn && spawn->GetID() == ignore_target || (spawn->IsEntity() && !luaspell->caster->AttackAllowed((Entity*)spawn))){
|
}
|
||||||
continue;
|
|
||||||
}
|
i++;
|
||||||
if (spawn){
|
|
||||||
//If this spawn is immune to aoe, continue
|
if (luaspell->targets.size() >= luaspell->spell->GetSpellData()->max_aoe_targets)
|
||||||
if (((Entity*)spawn)->IsAOEImmune() || ((Entity*)spawn)->IsMezzed())
|
break;
|
||||||
|
|
||||||
|
int32 target_id = pair.first;
|
||||||
|
Spawn* spawn = luaspell->caster->GetZone()->GetSpawnByID(target_id);
|
||||||
|
if(!spawn) {
|
||||||
|
LogWrite(SPELL__ERROR, 0, "Spell", "Error: Spell target is NULL! SpellProcess::ProcessSpell for Spell '%s' target id %u", (luaspell->spell != nullptr) ? luaspell->spell->GetName() : "Unknown", target_id);
|
||||||
|
}
|
||||||
|
//If we have already added this spawn, check the next spawn in the list
|
||||||
|
if (spawn && spawn->GetID() == ignore_target || (spawn->IsEntity() && !luaspell->caster->AttackAllowed((Entity*)spawn))){
|
||||||
continue;
|
continue;
|
||||||
AddLuaSpellTarget(luaspell, spawn->GetID(), false);
|
}
|
||||||
}
|
if (spawn){
|
||||||
|
//If this spawn is immune to aoe, continue
|
||||||
|
if (((Entity*)spawn)->IsAOEImmune() || ((Entity*)spawn)->IsMezzed())
|
||||||
|
continue;
|
||||||
|
AddLuaSpellTarget(luaspell, spawn->GetID(), false);
|
||||||
|
}
|
||||||
|
|
||||||
if (luaspell->targets.size() >= luaspell->spell->GetSpellData()->max_aoe_targets)
|
if (luaspell->targets.size() >= luaspell->spell->GetSpellData()->max_aoe_targets)
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
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());
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user