diff --git a/data/sql/updates/pending_db_world/rev_1637890270049187700.sql b/data/sql/updates/pending_db_world/rev_1637890270049187700.sql new file mode 100644 index 000000000..0addcd958 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1637890270049187700.sql @@ -0,0 +1,21 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1637890270049187700'); + +-- Adding Boss to Game event 13: Elemental Invasions +DELETE FROM `game_event_creature` WHERE `eventEntry` = 13 AND `guid` = 14461; +INSERT INTO `game_event_creature` (`eventEntry`, `guid`) VALUES (13, 14461); + +UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE `entry` = 179666; +DELETE FROM `smart_scripts` WHERE (`source_type` = 1 AND `entryorguid` = 179666); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(179666, 1, 0, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fire Elemental Rift - On Respawn - Set Event Phase 1'), +(179666, 1, 1, 2, 60, 1, 100, 0, 0, 1000, 30000, 30000, 0, 12, 14460, 6, 120000, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fire Elemental Rift - On Update - Summon Creature \'Blazing Invader\' (Phase 1)'), +(179666, 1, 2, 0, 61, 0, 100, 0, 14460, 0, 0, 0, 0, 63, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fire Elemental Rift - On Summoned Unit - Increase counter by 1'), +(179666, 1, 3, 0, 77, 0, 100, 0, 1, 3, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'When 3 Invaders have been summoned - Set Event Phase 2'), +(179666, 1, 4, 0, 77, 0, 100, 0, 1, 2, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'When there\'s 2 Invaders left - Set Event Phase 1'); + +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 14460; +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 14460); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(14460, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 89, 30, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blazing Invader - On Just Summoned - Start Random Movement'), +(14460, 0, 1, 0, 0, 0, 100, 0, 0, 11000, 10000, 16000, 0, 11, 23113, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blazing Invader - In Combat - Cast \'Blast Wave\''), +(14460, 0, 2, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 63, 1, 1, 0, 1, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Blazing Invader - On Just Died - Missing comment for action_type 63'); diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 05f27db79..f9df34f18 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1705,24 +1705,24 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (IsCreature(*itr)) { if (SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI())) - ai->GetScript()->StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset); + ai->GetScript()->StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset, e.action.setCounter.subtract); else LOG_ERROR("scripts.ai.sai", "SmartScript: Action target for SMART_ACTION_SET_COUNTER is not using SmartAI, skipping"); } else if (IsGameObject(*itr)) { if (SmartGameObjectAI* ai = CAST_AI(SmartGameObjectAI, (*itr)->ToGameObject()->AI())) - ai->GetScript()->StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset); + ai->GetScript()->StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset, e.action.setCounter.subtract); else LOG_ERROR("scripts.ai.sai", "SmartScript: Action target for SMART_ACTION_SET_COUNTER is not using SmartGameObjectAI, skipping"); } } - delete targets; } else - StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset); - + { + StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset, e.action.setCounter.subtract); + } break; } case SMART_ACTION_WP_START: @@ -3792,29 +3792,39 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* break; } case SMART_TARGET_OWNER_OR_SUMMONER: + /* + * Owners/Summoners should be WorldObjects. This allows to have other objects + * such as gameobjects to execute SmartScripts using this type of target. + * Otherwise, only Units like creatures can summon other creatures. + */ { if (me) { - if (Unit* owner = ObjectAccessor::GetUnit(*me, me->GetCharmerOrOwnerGUID())) + if (WorldObject* owner = ObjectAccessor::GetWorldObject(*me, me->GetCharmerOrOwnerGUID())) + { l->push_back(owner); - // Xinef: dont add same unit twice - else if (me->IsSummon() && me->ToTempSummon()->GetSummonerUnit()) - l->push_back(me->ToTempSummon()->GetSummonerUnit()); + } } else if (go) { - if (Unit* owner = ObjectAccessor::GetUnit(*go, go->GetOwnerGUID())) + if (WorldObject* owner = ObjectAccessor::GetWorldObject(*go, go->GetOwnerGUID())) + { l->push_back(owner); + } } // xinef: Get owner of owner if (e.target.owner.useCharmerOrOwner && !l->empty()) { - Unit* owner = l->front()->ToUnit(); - l->clear(); + if (Unit* owner = l->front()->ToUnit()) + { + l->clear(); - if (Unit* base = ObjectAccessor::GetUnit(*owner, owner->GetCharmerOrOwnerGUID())) - l->push_back(base); + if (Unit* base = ObjectAccessor::GetUnit(*owner, owner->GetCharmerOrOwnerGUID())) + { + l->push_back(base); + } + } } break; } diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 0967b0320..2b67bf41c 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -143,18 +143,28 @@ public: return nullptr; } - void StoreCounter(uint32 id, uint32 value, uint32 reset) + void StoreCounter(uint32 id, uint32 value, uint32 reset, uint32 subtract) { CounterMap::iterator itr = mCounterList.find(id); if (itr != mCounterList.end()) { - if (reset == 0) + if (!reset && !subtract) + { itr->second += value; + } + else if (subtract) + { + itr->second -= value; + } else + { itr->second = value; + } } else + { mCounterList.insert(std::make_pair(id, value)); + } ProcessEventsFor(SMART_EVENT_COUNTER_SET, nullptr, id); } diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index d24de7dd6..acbb7fcfc 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1005,6 +1005,7 @@ struct SmartAction uint32 counterId; uint32 value; uint32 reset; + uint32 subtract; } setCounter; struct diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 19751f3b2..1c1dadef6 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2271,7 +2271,7 @@ void WorldObject::AddObjectToRemoveList() map->AddObjectToRemoveList(this); } -TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties /*= nullptr*/, uint32 duration /*= 0*/, Unit* summoner /*= nullptr*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/) +TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties /*= nullptr*/, uint32 duration /*= 0*/, WorldObject* summoner /*= nullptr*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/) { uint32 mask = UNIT_MASK_SUMMON; if (properties) @@ -2451,7 +2451,7 @@ TempSummon* WorldObject::SummonCreature(uint32 entry, const Position& pos, TempS { if (Map* map = FindMap()) { - if (TempSummon* summon = map->SummonCreature(entry, pos, properties, duration, isType(TYPEMASK_UNIT) ? (Unit*)this : nullptr)) + if (TempSummon* summon = map->SummonCreature(entry, pos, properties, duration, (WorldObject*) this)) { summon->SetTempSummonType(spwtype); return summon; diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index c30492bdb..1746ea2d3 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -490,7 +490,7 @@ public: void UpdateIteratorBack(Player* player); - TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = nullptr, uint32 duration = 0, Unit* summoner = nullptr, uint32 spellId = 0, uint32 vehId = 0); + TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = nullptr, uint32 duration = 0, WorldObject* summoner = nullptr, uint32 spellId = 0, uint32 vehId = 0); GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime, bool checkTransport = true); void SummonCreatureGroup(uint8 group, std::list* list = nullptr);