call spell remove function for reason "target_dead" and "target_removed" also address the long delay between calling the remove function and the death of a spawn. Lastly made it so we can reference the spawn group id after death for a spawn since we remove it from a spawn group.
This commit is contained in:
parent
e20b45eedd
commit
3efce0abd6
@ -822,7 +822,7 @@ lua_State* LuaInterface::LoadLuaFile(const char* name) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaInterface::RemoveSpell(LuaSpell* spell, bool call_remove_function, bool can_delete, string reason, bool removing_all_spells) {
|
void LuaInterface::RemoveSpell(LuaSpell* spell, bool call_remove_function, bool can_delete, string reason, bool removing_all_spells, bool return_after_call_remove, Spawn* overrideTarget) {
|
||||||
if(call_remove_function){
|
if(call_remove_function){
|
||||||
lua_getglobal(spell->state, "remove");
|
lua_getglobal(spell->state, "remove");
|
||||||
if (!lua_isfunction(spell->state, lua_gettop(spell->state))){
|
if (!lua_isfunction(spell->state, lua_gettop(spell->state))){
|
||||||
@ -835,7 +835,9 @@ void LuaInterface::RemoveSpell(LuaSpell* spell, bool call_remove_function, bool
|
|||||||
lua_pushlightuserdata(spell->state, spawn_wrapper);
|
lua_pushlightuserdata(spell->state, spawn_wrapper);
|
||||||
if(spell->caster && (spell->initial_target || spell->caster->GetTarget())){
|
if(spell->caster && (spell->initial_target || spell->caster->GetTarget())){
|
||||||
spawn_wrapper = new LUASpawnWrapper();
|
spawn_wrapper = new LUASpawnWrapper();
|
||||||
if(!spell->initial_target)
|
if(overrideTarget)
|
||||||
|
spawn_wrapper->spawn = overrideTarget;
|
||||||
|
else if(!spell->initial_target)
|
||||||
spawn_wrapper->spawn = spell->caster->GetTarget();
|
spawn_wrapper->spawn = spell->caster->GetTarget();
|
||||||
else if(spell->caster->GetZone()) {
|
else if(spell->caster->GetZone()) {
|
||||||
spawn_wrapper->spawn = spell->caster->GetZone()->GetSpawnByID(spell->initial_target);
|
spawn_wrapper->spawn = spell->caster->GetZone()->GetSpawnByID(spell->initial_target);
|
||||||
@ -890,6 +892,9 @@ void LuaInterface::RemoveSpell(LuaSpell* spell, bool call_remove_function, bool
|
|||||||
ResetFunctionStack(spell->state);
|
ResetFunctionStack(spell->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(return_after_call_remove)
|
||||||
|
return;
|
||||||
|
|
||||||
spell->MSpellTargets.readlock(__FUNCTION__, __LINE__);
|
spell->MSpellTargets.readlock(__FUNCTION__, __LINE__);
|
||||||
if(spell->caster) {
|
if(spell->caster) {
|
||||||
for (int8 i = 0; i < spell->targets.size(); i++) {
|
for (int8 i = 0; i < spell->targets.size(); i++) {
|
||||||
|
@ -194,7 +194,7 @@ public:
|
|||||||
bool LoadRegionScript(const char* name);
|
bool LoadRegionScript(const char* name);
|
||||||
LuaSpell* LoadSpellScript(string name);
|
LuaSpell* LoadSpellScript(string name);
|
||||||
LuaSpell* LoadSpellScript(const char* name);
|
LuaSpell* LoadSpellScript(const char* name);
|
||||||
void RemoveSpell(LuaSpell* spell, bool call_remove_function = true, bool can_delete = true, string reason = "", bool removing_all_spells = false);
|
void RemoveSpell(LuaSpell* spell, bool call_remove_function = true, bool can_delete = true, string reason = "", bool removing_all_spells = false, bool return_after_call_remove = false, Spawn* overrideTarget = nullptr);
|
||||||
Spawn* GetSpawn(lua_State* state, int8 arg_num = 1);
|
Spawn* GetSpawn(lua_State* state, int8 arg_num = 1);
|
||||||
Item* GetItem(lua_State* state, int8 arg_num = 1);
|
Item* GetItem(lua_State* state, int8 arg_num = 1);
|
||||||
Quest* GetQuest(lua_State* state, int8 arg_num = 1);
|
Quest* GetQuest(lua_State* state, int8 arg_num = 1);
|
||||||
|
@ -4082,15 +4082,16 @@ void Spawn::SetSpawnGroupList(vector<Spawn*>* list, Mutex* mutex){
|
|||||||
MSpawnGroup = mutex;
|
MSpawnGroup = mutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spawn::RemoveSpawnFromGroup(bool erase_all){
|
void Spawn::RemoveSpawnFromGroup(bool erase_all, bool ignore_death){
|
||||||
SetSpawnGroupID(0);
|
if(!ignore_death)
|
||||||
|
SetSpawnGroupID(0);
|
||||||
bool del = false;
|
bool del = false;
|
||||||
if(MSpawnGroup){
|
if(MSpawnGroup){
|
||||||
MSpawnGroup->writelock(__FUNCTION__, __LINE__);
|
MSpawnGroup->writelock(__FUNCTION__, __LINE__);
|
||||||
if(spawn_group_list){
|
if(spawn_group_list){
|
||||||
vector<Spawn*>::iterator itr;
|
vector<Spawn*>::iterator itr;
|
||||||
Spawn* spawn = 0;
|
Spawn* spawn = 0;
|
||||||
if(spawn_group_list->size() == 1)
|
if(spawn_group_list->size() == 1 && !ignore_death)
|
||||||
erase_all = true;
|
erase_all = true;
|
||||||
for(itr = spawn_group_list->begin(); itr != spawn_group_list->end(); itr++){
|
for(itr = spawn_group_list->begin(); itr != spawn_group_list->end(); itr++){
|
||||||
spawn = *itr;
|
spawn = *itr;
|
||||||
|
@ -1099,7 +1099,7 @@ public:
|
|||||||
int32 GetSpawnGroupID();
|
int32 GetSpawnGroupID();
|
||||||
void AddSpawnToGroup(Spawn* spawn);
|
void AddSpawnToGroup(Spawn* spawn);
|
||||||
void SetSpawnGroupList(vector<Spawn*>* list, Mutex* mutex);
|
void SetSpawnGroupList(vector<Spawn*>* list, Mutex* mutex);
|
||||||
void RemoveSpawnFromGroup(bool erase_all = false);
|
void RemoveSpawnFromGroup(bool erase_all = false, bool ignore_death = false);
|
||||||
|
|
||||||
void SetRunningTo(Spawn* spawn){ running_to = spawn->GetID(); }
|
void SetRunningTo(Spawn* spawn){ running_to = spawn->GetID(); }
|
||||||
Spawn* GetRunningTo();
|
Spawn* GetRunningTo();
|
||||||
|
@ -1704,6 +1704,11 @@ void SpellProcess::ProcessEntityCommand(ZoneServer* zone, EntityCommand* entity_
|
|||||||
bool SpellProcess::CastProcessedSpell(LuaSpell* spell, bool passive, bool in_heroic_opp){
|
bool SpellProcess::CastProcessedSpell(LuaSpell* spell, bool passive, bool in_heroic_opp){
|
||||||
if(!spell || !spell->caster || !spell->spell || spell->interrupted)
|
if(!spell || !spell->caster || !spell->spell || spell->interrupted)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if(spell->spell->GetSpellData()->duration1 > 0){
|
||||||
|
AddActiveSpell(spell);
|
||||||
|
}
|
||||||
|
|
||||||
Client* client = 0;
|
Client* client = 0;
|
||||||
if(spell->caster && spell->caster->IsPlayer())
|
if(spell->caster && spell->caster->IsPlayer())
|
||||||
client = ((Player*)spell->caster)->GetClient();
|
client = ((Player*)spell->caster)->GetClient();
|
||||||
@ -1716,6 +1721,7 @@ bool SpellProcess::CastProcessedSpell(LuaSpell* spell, bool passive, bool in_her
|
|||||||
SendSpellBookUpdate(client);
|
SendSpellBookUpdate(client);
|
||||||
}
|
}
|
||||||
spell->caster->GetZone()->SendSpellFailedPacket(client, SPELL_ERROR_NO_TARGETS_IN_RANGE);
|
spell->caster->GetZone()->SendSpellFailedPacket(client, SPELL_ERROR_NO_TARGETS_IN_RANGE);
|
||||||
|
DeleteActiveSpell(spell, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1734,16 +1740,22 @@ bool SpellProcess::CastProcessedSpell(LuaSpell* spell, bool passive, bool in_her
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MutexList<LuaSpell*>::iterator itr = active_spells.begin();
|
|
||||||
bool processedSpell = false;
|
bool processedSpell = false;
|
||||||
|
|
||||||
bool allTargets = (spell->spell->GetSpellData()->spell_type == SPELL_TYPE_ALLGROUPTARGETS);
|
bool allTargets = (spell->spell->GetSpellData()->spell_type == SPELL_TYPE_ALLGROUPTARGETS);
|
||||||
|
|
||||||
if (!processedSpell)
|
if (!processedSpell)
|
||||||
processedSpell = ProcessSpell(spell, true, 0, 0, allTargets);
|
processedSpell = ProcessSpell(spell, true, 0, 0, allTargets);
|
||||||
|
|
||||||
|
if(spell->resisted && spell->spell->GetSpellData()->duration1) {
|
||||||
|
DeleteActiveSpell(spell, true);
|
||||||
|
}
|
||||||
// Quick hack to prevent a crash on spells that zones the caster (Gate)
|
// Quick hack to prevent a crash on spells that zones the caster (Gate)
|
||||||
if (!spell->caster)
|
if (!spell->caster) {
|
||||||
|
if(spell->spell->GetSpellData()->duration1)
|
||||||
|
DeleteActiveSpell(spell, true);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Skill* skill = spell->caster->GetSkillByID(spell->spell->GetSpellData()->mastery_skill, false);
|
Skill* skill = spell->caster->GetSkillByID(spell->spell->GetSpellData()->mastery_skill, false);
|
||||||
// trigger potential skill increase if we succeed in casting a mastery skill and it still has room to grow (against this spell)
|
// trigger potential skill increase if we succeed in casting a mastery skill and it still has room to grow (against this spell)
|
||||||
@ -1805,6 +1817,7 @@ bool SpellProcess::CastProcessedSpell(LuaSpell* spell, bool passive, bool in_her
|
|||||||
else{
|
else{
|
||||||
if (!passive)
|
if (!passive)
|
||||||
SendFinishedCast(spell, client);
|
SendFinishedCast(spell, client);
|
||||||
|
DeleteActiveSpell(spell, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(!spell->resisted && (spell->spell->GetSpellDuration() > 0 || spell->spell->GetSpellData()->duration_until_cancel || spell->spell->GetSpellData()->spell_book_type == SPELL_BOOK_TYPE_NOT_SHOWN)) {
|
if(!spell->resisted && (spell->spell->GetSpellDuration() > 0 || spell->spell->GetSpellData()->duration_until_cancel || spell->spell->GetSpellData()->spell_book_type == SPELL_BOOK_TYPE_NOT_SHOWN)) {
|
||||||
@ -1839,8 +1852,6 @@ bool SpellProcess::CastProcessedSpell(LuaSpell* spell, bool passive, bool in_her
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
active_spells.Add(spell);
|
|
||||||
|
|
||||||
if (spell->num_triggers > 0)
|
if (spell->num_triggers > 0)
|
||||||
ClientPacketFunctions::SendMaintainedExamineUpdate(client, spell->slot_pos, spell->num_triggers, 0);
|
ClientPacketFunctions::SendMaintainedExamineUpdate(client, spell->slot_pos, spell->num_triggers, 0);
|
||||||
if (spell->damage_remaining > 0)
|
if (spell->damage_remaining > 0)
|
||||||
@ -1855,9 +1866,7 @@ bool SpellProcess::CastProcessedSpell(LuaSpell* spell, bool passive, bool in_her
|
|||||||
spell->timer.SetTimer(spell->spell->GetSpellData()->call_frequency*100);
|
spell->timer.SetTimer(spell->spell->GetSpellData()->call_frequency*100);
|
||||||
else
|
else
|
||||||
spell->timer.SetTimer(spell->spell->GetSpellData()->duration1*100);
|
spell->timer.SetTimer(spell->spell->GetSpellData()->duration1*100);
|
||||||
if (active_spells.count(spell) < 1) {
|
AddActiveSpell(spell);
|
||||||
active_spells.Add(spell);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the caster is a player and the spell is a tradeskill spell check for a tradeskill event
|
// if the caster is a player and the spell is a tradeskill spell check for a tradeskill event
|
||||||
@ -2824,7 +2833,8 @@ void SpellProcess::CheckRemoveTargetFromSpell(LuaSpell* spell, bool allow_delete
|
|||||||
|
|
||||||
remove_spawn = spell->caster->GetZone()->GetSpawnByID((*remove_target_itr));
|
remove_spawn = spell->caster->GetZone()->GetSpawnByID((*remove_target_itr));
|
||||||
if (remove_spawn) {
|
if (remove_spawn) {
|
||||||
if(remove_spawn && remove_spawn->IsPlayer())
|
bool found_target = false;
|
||||||
|
if(remove_spawn->IsPlayer())
|
||||||
{
|
{
|
||||||
multimap<int32,int8>::iterator entries;
|
multimap<int32,int8>::iterator entries;
|
||||||
while((entries = spell->char_id_targets.find(((Player*)remove_spawn)->GetCharacterID())) != spell->char_id_targets.end())
|
while((entries = spell->char_id_targets.find(((Player*)remove_spawn)->GetCharacterID())) != spell->char_id_targets.end())
|
||||||
@ -2834,6 +2844,7 @@ void SpellProcess::CheckRemoveTargetFromSpell(LuaSpell* spell, bool allow_delete
|
|||||||
}
|
}
|
||||||
for (target_itr = targets->begin(); target_itr != targets->end(); target_itr++) {
|
for (target_itr = targets->begin(); target_itr != targets->end(); target_itr++) {
|
||||||
if (remove_spawn->GetID() == (*target_itr)) {
|
if (remove_spawn->GetID() == (*target_itr)) {
|
||||||
|
found_target = true;
|
||||||
((Entity*)remove_spawn)->RemoveProc(0, spell);
|
((Entity*)remove_spawn)->RemoveProc(0, spell);
|
||||||
((Entity*)remove_spawn)->RemoveMaintainedSpell(spell);
|
((Entity*)remove_spawn)->RemoveMaintainedSpell(spell);
|
||||||
LogWrite(SPELL__DEBUG, 0, "Spell", "%s CheckRemoveTargetFromSpell %s (%u).", spell->spell->GetName(), remove_spawn->GetName(), remove_spawn->GetID());
|
LogWrite(SPELL__DEBUG, 0, "Spell", "%s CheckRemoveTargetFromSpell %s (%u).", spell->spell->GetName(), remove_spawn->GetName(), remove_spawn->GetID());
|
||||||
@ -2845,9 +2856,18 @@ void SpellProcess::CheckRemoveTargetFromSpell(LuaSpell* spell, bool allow_delete
|
|||||||
}
|
}
|
||||||
if (targets->size() == 0 && spell->char_id_targets.size() == 0 && allow_delete) {
|
if (targets->size() == 0 && spell->char_id_targets.size() == 0 && allow_delete) {
|
||||||
spell->MSpellTargets.releasewritelock(__FUNCTION__, __LINE__);
|
spell->MSpellTargets.releasewritelock(__FUNCTION__, __LINE__);
|
||||||
|
if(found_target)
|
||||||
|
lua_interface->RemoveSpell(spell, true, false, !remove_spawn->Alive() ? "target_dead" : "target_removed", false, true, remove_spawn);
|
||||||
should_delete = true;
|
should_delete = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
spell->MSpellTargets.releasewritelock(__FUNCTION__, __LINE__);
|
||||||
|
// call remove function "on death"
|
||||||
|
if(found_target)
|
||||||
|
lua_interface->RemoveSpell(spell, true, false, !remove_spawn->Alive() ? "target_dead" : "target_removed", false, true, remove_spawn);
|
||||||
|
spell->MSpellTargets.writelock(__FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spell->MSpellTargets.releasewritelock(__FUNCTION__, __LINE__);
|
spell->MSpellTargets.releasewritelock(__FUNCTION__, __LINE__);
|
||||||
|
@ -4331,7 +4331,7 @@ Spawn* ZoneServer::GetSpawnGroup(int32 id){
|
|||||||
for (itr = spawn_list.begin(); itr != spawn_list.end(); itr++) {
|
for (itr = spawn_list.begin(); itr != spawn_list.end(); itr++) {
|
||||||
spawn = itr->second;
|
spawn = itr->second;
|
||||||
if(spawn){
|
if(spawn){
|
||||||
if(spawn->GetSpawnGroupID() == id){
|
if(spawn->Alive() && spawn->GetSpawnGroupID() == id){
|
||||||
ret = spawn;
|
ret = spawn;
|
||||||
quick_group_id_lookup.Put(id, spawn->GetID());
|
quick_group_id_lookup.Put(id, spawn->GetID());
|
||||||
break;
|
break;
|
||||||
@ -6798,7 +6798,7 @@ void ZoneServer::RemoveSpawnSupportFunctions(Spawn* spawn, bool lock_spell_proce
|
|||||||
|
|
||||||
if (spawn->GetSpawnGroupID() > 0) {
|
if (spawn->GetSpawnGroupID() > 0) {
|
||||||
int32 group_id = spawn->GetSpawnGroupID();
|
int32 group_id = spawn->GetSpawnGroupID();
|
||||||
spawn->RemoveSpawnFromGroup();
|
spawn->RemoveSpawnFromGroup(false, (spawn->IsEntity() && !spawn->Alive()) ? true : false);
|
||||||
if (spawn_group_map.count(group_id) > 0)
|
if (spawn_group_map.count(group_id) > 0)
|
||||||
spawn_group_map.Get(group_id).Remove(spawn->GetID());
|
spawn_group_map.Get(group_id).Remove(spawn->GetID());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user