diff options
Diffstat (limited to 'src')
11 files changed, 338 insertions, 108 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 866437d828c..afa4b62d8b0 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -380,6 +380,7 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData* data) SetAttackTime(RANGED_ATTACK, cInfo->rangeattacktime); SetUInt32Value(UNIT_FIELD_FLAGS, unit_flags); + SetUInt32Value(UNIT_FIELD_FLAGS_2, cInfo->unit_flags2); SetUInt32Value(UNIT_DYNAMIC_FLAGS, dynamicflags); diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index c8ebf1aa13b..4dd080f8b15 100755 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -111,6 +111,7 @@ struct CreatureTemplate uint32 rangeattacktime; uint32 unit_class; // enum Classes. Note only 4 classes are known for creatures. uint32 unit_flags; // enum UnitFlags mask values + uint32 unit_flags2; // enum UnitFlags2 mask values uint32 dynamicflags; uint32 family; // enum CreatureFamily values (optional) uint32 trainer_type; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 8660b040037..fa82a8e5ffe 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -17119,7 +17119,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) SetUInt64Value(PLAYER_FARSIGHT, 0); SetCreatorGUID(0); - RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE); + RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVEMENT); // reset some aura modifiers before aura apply SetUInt32Value(PLAYER_TRACK_CREATURES, 0); @@ -17516,8 +17516,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) { uint32 zoneId = GetZoneId(); - std::map<uint64, Bag*> bagMap; // fast guid lookup for bags - std::map<uint64, Item*> invalidBagMap; // fast guid lookup for bags + std::map<uint32, Bag*> bagMap; // fast guid lookup for bags + std::map<uint32, Item*> invalidBagMap; // fast guid lookup for bags std::list<Item*> problematicItems; SQLTransaction trans = CharacterDatabase.BeginTransaction(); @@ -17576,7 +17576,7 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) { item->SetSlot(NULL_SLOT); // Item is in the bag, find the bag - std::map<uint64, Bag*>::iterator itr = bagMap.find(bagGuid); + std::map<uint32, Bag*>::iterator itr = bagMap.find(bagGuid); if (itr != bagMap.end()) { ItemPosCountVec dest; @@ -17586,8 +17586,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) } else if (invalidBagMap.find(bagGuid) != invalidBagMap.end()) { - std::map<uint64, Item*>::iterator itr = invalidBagMap.find(bagGuid); - if (std::find(problematicItems.begin(),problematicItems.end(),itr->second) != problematicItems.end()) + std::map<uint32, Item*>::iterator itr = invalidBagMap.find(bagGuid); + if (std::find(problematicItems.begin(), problematicItems.end(), itr->second) != problematicItems.end()) err = EQUIP_ERR_INT_BAG_ERROR; } else diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 46dbf4829a6..2ec3ffec8ef 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -618,17 +618,24 @@ enum UnitFlags // Value masks for UNIT_FIELD_FLAGS_2 enum UnitFlags2 { - UNIT_FLAG2_FEIGN_DEATH = 0x00000001, - UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip) - UNIT_FLAG2_IGNORE_REPUTATION = 0x00000004, - UNIT_FLAG2_COMPREHEND_LANG = 0x00000008, - UNIT_FLAG2_MIRROR_IMAGE = 0x00000010, - UNIT_FLAG2_FORCE_MOVE = 0x00000040, - UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, - UNIT_FLAG2_DISARM_RANGED = 0x00000400, // this does not disable ranged weapon display (maybe additional flag needed?) - UNIT_FLAG2_REGENERATE_POWER = 0x00000800, - UNIT_FLAG2_ALLOW_ENEMY_INTERACT = 0x00004000, - UNIT_FLAG2_ALLOW_CHEAT_SPELLS = 0x00040000, // allows casting spells with AttributesEx7 & SPELL_ATTR7_IS_CHEAT_SPELL + UNIT_FLAG2_FEIGN_DEATH = 0x00000001, + UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip) + UNIT_FLAG2_IGNORE_REPUTATION = 0x00000004, + UNIT_FLAG2_COMPREHEND_LANG = 0x00000008, + UNIT_FLAG2_MIRROR_IMAGE = 0x00000010, + UNIT_FLAG2_INSTANTLY_APPEAR_MODEL = 0x00000020, // Unit model instantly appears when summoned (does not fade in) + UNIT_FLAG2_FORCE_MOVEMENT = 0x00000040, + UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, + UNIT_FLAG2_DISABLE_PRED_STATS = 0x00000100, // Player has disabled predicted stats (Used by raid frames) + UNIT_FLAG2_DISARM_RANGED = 0x00000400, // this does not disable ranged weapon display (maybe additional flag needed?) + UNIT_FLAG2_REGENERATE_POWER = 0x00000800, + UNIT_FLAG2_RESTRICT_PARTY_INTERACTION = 0x00001000, // Restrict interaction to party or raid + UNIT_FLAG2_PREVENT_SPELL_CLICK = 0x00002000, // Prevent spellclick + UNIT_FLAG2_ALLOW_ENEMY_INTERACT = 0x00004000, + UNIT_FLAG2_DISABLE_TURN = 0x00008000, + UNIT_FLAG2_UNK2 = 0x00010000, + UNIT_FLAG2_PLAY_DEATH_ANIM = 0x00020000, // Plays special death animation upon death + UNIT_FLAG2_ALLOW_CHEAT_SPELLS = 0x00040000, // Allows casting spells with AttributesEx7 & SPELL_ATTR7_IS_CHEAT_SPELL }; /// Non Player Character flags diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 08a76008fde..b7c64a26ced 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -369,17 +369,17 @@ void ObjectMgr::LoadCreatureTemplates() QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, " // 9 10 11 12 13 14 15 16 17 18 19 20 21 "modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, " - // 22 23 24 25 26 27 28 29 30 31 32 - "scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, " - // 33 34 35 36 37 38 39 40 41 42 + // 22 23 24 25 26 27 28 29 30 31 32 33 + "scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, " + // 34 35 36 37 38 39 40 41 42 43 "dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, " - // 43 44 45 46 47 48 49 50 51 52 53 + // 44 45 46 47 48 49 50 51 52 53 54 "type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, " - // 54 55 56 57 58 59 60 61 62 63 64 65 66 + // 55 56 57 58 59 60 61 62 63 64 65 66 67 "spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, " - // 67 68 69 70 71 72 73 74 75 76 77 + // 68 69 70 71 72 73 74 75 76 77 78 "InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, " - // 78 79 80 81 82 83 + // 79 80 81 82 83 84 " questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName " "FROM creature_template;"); @@ -435,49 +435,50 @@ void ObjectMgr::LoadCreatureTemplates() creatureTemplate.rangeattacktime = fields[30].GetUInt32(); creatureTemplate.unit_class = uint32(fields[31].GetUInt8()); creatureTemplate.unit_flags = fields[32].GetUInt32(); - creatureTemplate.dynamicflags = fields[33].GetUInt32(); - creatureTemplate.family = uint32(fields[34].GetUInt8()); - creatureTemplate.trainer_type = uint32(fields[35].GetUInt8()); - creatureTemplate.trainer_spell = fields[36].GetUInt32(); - creatureTemplate.trainer_class = uint32(fields[37].GetUInt8()); - creatureTemplate.trainer_race = uint32(fields[38].GetUInt8()); - creatureTemplate.minrangedmg = fields[39].GetFloat(); - creatureTemplate.maxrangedmg = fields[40].GetFloat(); - creatureTemplate.rangedattackpower = uint32(fields[41].GetUInt16()); - creatureTemplate.type = uint32(fields[42].GetUInt8()); - creatureTemplate.type_flags = fields[43].GetUInt32(); - creatureTemplate.lootid = fields[44].GetUInt32(); - creatureTemplate.pickpocketLootId = fields[45].GetUInt32(); - creatureTemplate.SkinLootId = fields[46].GetUInt32(); + creatureTemplate.unit_flags2 = fields[33].GetUInt32(); + creatureTemplate.dynamicflags = fields[34].GetUInt32(); + creatureTemplate.family = uint32(fields[35].GetUInt8()); + creatureTemplate.trainer_type = uint32(fields[36].GetUInt8()); + creatureTemplate.trainer_spell = fields[37].GetUInt32(); + creatureTemplate.trainer_class = uint32(fields[38].GetUInt8()); + creatureTemplate.trainer_race = uint32(fields[39].GetUInt8()); + creatureTemplate.minrangedmg = fields[40].GetFloat(); + creatureTemplate.maxrangedmg = fields[41].GetFloat(); + creatureTemplate.rangedattackpower = uint32(fields[42].GetUInt16()); + creatureTemplate.type = uint32(fields[43].GetUInt8()); + creatureTemplate.type_flags = fields[44].GetUInt32(); + creatureTemplate.lootid = fields[45].GetUInt32(); + creatureTemplate.pickpocketLootId = fields[46].GetUInt32(); + creatureTemplate.SkinLootId = fields[47].GetUInt32(); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - creatureTemplate.resistance[i] = fields[47 + i -1].GetInt16(); + creatureTemplate.resistance[i] = fields[48 + i -1].GetInt16(); for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) - creatureTemplate.spells[i] = fields[53 + i].GetUInt32(); - - creatureTemplate.PetSpellDataId = fields[61].GetUInt32(); - creatureTemplate.VehicleId = fields[62].GetUInt32(); - creatureTemplate.mingold = fields[63].GetUInt32(); - creatureTemplate.maxgold = fields[64].GetUInt32(); - creatureTemplate.AIName = fields[65].GetString(); - creatureTemplate.MovementType = uint32(fields[66].GetUInt8()); - creatureTemplate.InhabitType = uint32(fields[67].GetUInt8()); - creatureTemplate.HoverHeight = fields[68].GetFloat(); - creatureTemplate.ModHealth = fields[69].GetFloat(); - creatureTemplate.ModMana = fields[70].GetFloat(); - creatureTemplate.ModArmor = fields[71].GetFloat(); - creatureTemplate.RacialLeader = fields[72].GetBool(); + creatureTemplate.spells[i] = fields[54 + i].GetUInt32(); + + creatureTemplate.PetSpellDataId = fields[62].GetUInt32(); + creatureTemplate.VehicleId = fields[63].GetUInt32(); + creatureTemplate.mingold = fields[64].GetUInt32(); + creatureTemplate.maxgold = fields[65].GetUInt32(); + creatureTemplate.AIName = fields[66].GetString(); + creatureTemplate.MovementType = uint32(fields[67].GetUInt8()); + creatureTemplate.InhabitType = uint32(fields[68].GetUInt8()); + creatureTemplate.HoverHeight = fields[69].GetFloat(); + creatureTemplate.ModHealth = fields[70].GetFloat(); + creatureTemplate.ModMana = fields[71].GetFloat(); + creatureTemplate.ModArmor = fields[72].GetFloat(); + creatureTemplate.RacialLeader = fields[73].GetBool(); for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) - creatureTemplate.questItems[i] = fields[73 + i].GetUInt32(); - - creatureTemplate.movementId = fields[79].GetUInt32(); - creatureTemplate.RegenHealth = fields[80].GetBool(); - creatureTemplate.equipmentId = fields[81].GetUInt32(); - creatureTemplate.MechanicImmuneMask = fields[82].GetUInt32(); - creatureTemplate.flags_extra = fields[83].GetUInt32(); - creatureTemplate.ScriptID = GetScriptId(fields[84].GetCString()); + creatureTemplate.questItems[i] = fields[74 + i].GetUInt32(); + + creatureTemplate.movementId = fields[80].GetUInt32(); + creatureTemplate.RegenHealth = fields[81].GetBool(); + creatureTemplate.equipmentId = fields[82].GetUInt32(); + creatureTemplate.MechanicImmuneMask = fields[83].GetUInt32(); + creatureTemplate.flags_extra = fields[84].GetUInt32(); + creatureTemplate.ScriptID = GetScriptId(fields[85].GetCString()); ++count; } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index b83e44d6a73..bca26bd7391 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2958,13 +2958,13 @@ void AuraEffect::HandleForceMoveForward(AuraApplication const* aurApp, uint8 mod Unit* target = aurApp->GetTarget(); if (apply) - target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE); + target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVEMENT); else { // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit if (target->HasAuraType(GetAuraType())) return; - target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE); + target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVEMENT); } } diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h index e34e86c16a7..ed8c5351493 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h @@ -39,5 +39,9 @@ #define DATA_PRISON_CELL6 18 #define DATA_PRISON_CELL7 19 #define DATA_PRISON_CELL8 20 +#define DATA_BROGGOK_LEVER 21 +#define ACTION_ACTIVATE_BROGGOK 22 +#define ACTION_RESET_BROGGOK 23 +#define ACTION_PREPARE_BROGGOK 24 #endif diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp index 3a2e0834fed..84d292e1fe4 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp @@ -47,9 +47,9 @@ class boss_broggok : public CreatureScript { } - struct boss_broggokAI : public ScriptedAI + struct boss_broggokAI : public BossAI { - boss_broggokAI(Creature* creature) : ScriptedAI(creature) + boss_broggokAI(Creature* creature) : BossAI(creature, DATA_BROGGOK) { instance = creature->GetInstanceScript(); } @@ -59,27 +59,21 @@ class boss_broggok : public CreatureScript uint32 AcidSpray_Timer; uint32 PoisonSpawn_Timer; uint32 PoisonBolt_Timer; + bool canAttack; void Reset() { + _Reset(); AcidSpray_Timer = 10000; PoisonSpawn_Timer = 5000; PoisonBolt_Timer = 7000; - if (instance) - { - instance->SetData(TYPE_BROGGOK_EVENT, NOT_STARTED); - instance->HandleGameObject(instance->GetData64(DATA_DOOR4), true); - } + DoAction(ACTION_RESET_BROGGOK); + instance->SetData(TYPE_BROGGOK_EVENT, NOT_STARTED); } void EnterCombat(Unit* /*who*/) { DoScriptText(SAY_AGGRO, me); - if (instance) - { - instance->SetData(TYPE_BROGGOK_EVENT, IN_PROGRESS); - instance->HandleGameObject(instance->GetData64(DATA_DOOR4), false); - } } void JustSummoned(Creature* summoned) @@ -94,7 +88,8 @@ class boss_broggok : public CreatureScript { if (!UpdateVictim()) return; - + if (!canAttack) + return; if (AcidSpray_Timer <= diff) { DoCast(me->getVictim(), SPELL_SLIME_SPRAY); @@ -132,6 +127,26 @@ class boss_broggok : public CreatureScript } } + void DoAction(int32 const action) + { + switch (action) + { + case ACTION_PREPARE_BROGGOK: + me->SetInCombatWithZone(); + break; + case ACTION_ACTIVATE_BROGGOK: + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); + canAttack = true; + break; + case ACTION_RESET_BROGGOK: + me->SetReactState(REACT_PASSIVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); + canAttack = false; + break; + } + } + }; CreatureAI* GetAI(Creature* creature) const @@ -140,7 +155,27 @@ class boss_broggok : public CreatureScript } }; +class go_broggok_lever : public GameObjectScript +{ + public: + go_broggok_lever() : GameObjectScript("go_broggok_lever") {} + + bool OnGossipHello(Player* player, GameObject* go) + { + if (InstanceScript* instance = go->GetInstanceScript()) + if (instance->GetData(TYPE_BROGGOK_EVENT) != DONE && instance->GetData(TYPE_BROGGOK_EVENT) != IN_PROGRESS) + { + instance->SetData(TYPE_BROGGOK_EVENT, IN_PROGRESS); + if (Creature* broggok = Creature::GetCreature(*go, instance->GetData64(DATA_BROGGOK))) + broggok->AI()->DoAction(ACTION_PREPARE_BROGGOK); + } + go->UseDoorOrButton(); + return false; + } +}; + void AddSC_boss_broggok() { new boss_broggok(); + new go_broggok_lever(); } diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp index a0bcc396fdb..3c07862e0f6 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp @@ -57,7 +57,9 @@ enum eKelidan SPELL_VORTEX = 37370, ENTRY_KELIDAN = 17377, - ENTRY_CHANNELER = 17653 + ENTRY_CHANNELER = 17653, + + ACTION_ACTIVATE_ADDS = 92 }; const float ShadowmoonChannelers[5][4]= @@ -107,6 +109,8 @@ class boss_kelidan_the_breaker : public CreatureScript Firenova = false; addYell = false; SummonChannelers(); + me->SetReactState(REACT_PASSIVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); if (instance) instance->SetData(TYPE_KELIDAN_THE_BREAKER_EVENT, NOT_STARTED); } @@ -152,7 +156,8 @@ class boss_kelidan_the_breaker : public CreatureScript if (channeler && channeler->isAlive()) return; } - + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); if (killer) me->AI()->AttackStart(killer); } @@ -269,7 +274,6 @@ class boss_kelidan_the_breaker : public CreatureScript DoMeleeAttackIfReady(); } - }; CreatureAI* GetAI(Creature* creature) const @@ -295,16 +299,11 @@ class mob_shadowmoon_channeler : public CreatureScript { public: - mob_shadowmoon_channeler() - : CreatureScript("mob_shadowmoon_channeler") - { - } + mob_shadowmoon_channeler() : CreatureScript("mob_shadowmoon_channeler") {} struct mob_shadowmoon_channelerAI : public ScriptedAI { - mob_shadowmoon_channelerAI(Creature* creature) : ScriptedAI(creature) - { - } + mob_shadowmoon_channelerAI(Creature* creature) : ScriptedAI(creature){} uint32 ShadowBolt_Timer; uint32 MarkOfShadow_Timer; diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp index 4c434feb4ec..893f97fe711 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp @@ -26,6 +26,7 @@ EndScriptData */ #include "ScriptMgr.h" #include "InstanceScript.h" #include "blood_furnace.h" +#include "CreatureAI.h" #define ENTRY_SEWER1 181823 #define ENTRY_SEWER2 181766 @@ -35,9 +36,7 @@ class instance_blood_furnace : public InstanceMapScript { public: instance_blood_furnace() - : InstanceMapScript("instance_blood_furnace", 542) - { - } + : InstanceMapScript("instance_blood_furnace", 542) {} struct instance_blood_furnace_InstanceMapScript : public InstanceScript { @@ -63,6 +62,18 @@ class instance_blood_furnace : public InstanceMapScript uint64 PrisonCell7GUID; uint64 PrisonCell8GUID; + std::set<uint64> PrisonersCell5; + std::set<uint64> PrisonersCell6; + std::set<uint64> PrisonersCell7; + std::set<uint64> PrisonersCell8; + + uint8 PrisonerCounter5; + uint8 PrisonerCounter6; + uint8 PrisonerCounter7; + uint8 PrisonerCounter8; + + uint64 BroggokLeverGUID; + uint32 m_auiEncounter[MAX_ENCOUNTER]; std::string str_data; @@ -89,24 +100,45 @@ class instance_blood_furnace : public InstanceMapScript PrisonCell6GUID = 0; PrisonCell7GUID = 0; PrisonCell8GUID = 0; + + PrisonersCell5.clear(); + PrisonersCell6.clear(); + PrisonersCell7.clear(); + PrisonersCell8.clear(); + + PrisonerCounter5 = 0; + PrisonerCounter6 = 0; + PrisonerCounter7 = 0; + PrisonerCounter8 = 0; + + BroggokLeverGUID = 0; } void OnCreatureCreate(Creature* creature) { switch (creature->GetEntry()) { - case 17381: - The_MakerGUID = creature->GetGUID(); - break; - case 17380: - BroggokGUID = creature->GetGUID(); - break; - case 17377: - Kelidan_The_BreakerGUID = creature->GetGUID(); - break; + case 17381: + The_MakerGUID = creature->GetGUID(); + break; + case 17380: + BroggokGUID = creature->GetGUID(); + break; + case 17377: + Kelidan_The_BreakerGUID = creature->GetGUID(); + break; + case 17398: + StorePrisoner(creature); + break; } } + void OnCreatureDeath(Creature* unit) + { + if (unit && unit->GetTypeId() == TYPEID_UNIT && unit->GetEntry() == 17398) + PrisonerDied(unit->GetGUID()); + } + void OnGameObjectCreate(GameObject* go) { if (go->GetEntry() == 181766) //Final exit door @@ -138,6 +170,9 @@ class instance_blood_furnace : public InstanceMapScript PrisonCell7GUID = go->GetGUID(); if (go->GetEntry() == 181817) //Broggok prison cell back left PrisonCell8GUID = go->GetGUID(); + + if (go->GetEntry() == 181982) + BroggokLeverGUID = go->GetGUID(); //Broggok lever } uint64 GetData64(uint32 data) @@ -161,18 +196,25 @@ class instance_blood_furnace : public InstanceMapScript case DATA_PRISON_CELL6: return PrisonCell6GUID; case DATA_PRISON_CELL7: return PrisonCell7GUID; case DATA_PRISON_CELL8: return PrisonCell8GUID; + case DATA_BROGGOK_LEVER: return BroggokLeverGUID; } - return 0; } - void SetData(uint32 /*type*/, uint32 data) + void SetData(uint32 type, uint32 data) { - switch (data) + switch (type) { - case TYPE_THE_MAKER_EVENT: m_auiEncounter[0] = data; break; - case TYPE_BROGGOK_EVENT: m_auiEncounter[1] = data; break; - case TYPE_KELIDAN_THE_BREAKER_EVENT: m_auiEncounter[2] = data; break; + case TYPE_THE_MAKER_EVENT: + m_auiEncounter[0] = data; + break; + case TYPE_BROGGOK_EVENT: + m_auiEncounter[1] = data; + UpdateBroggokEvent(data); + break; + case TYPE_KELIDAN_THE_BREAKER_EVENT: + m_auiEncounter[2] = data; + break; } if (data == DONE) @@ -189,15 +231,14 @@ class instance_blood_furnace : public InstanceMapScript } } - uint32 GetData(uint32 data) + uint32 GetData(uint32 type) { - switch (data) + switch (type) { case TYPE_THE_MAKER_EVENT: return m_auiEncounter[0]; case TYPE_BROGGOK_EVENT: return m_auiEncounter[1]; case TYPE_KELIDAN_THE_BREAKER_EVENT: return m_auiEncounter[2]; } - return 0; } @@ -225,6 +266,147 @@ class instance_blood_furnace : public InstanceMapScript OUT_LOAD_INST_DATA_COMPLETE; } + + void UpdateBroggokEvent(uint32 data) + { + switch (data) + { + case IN_PROGRESS: + ActivateCell(DATA_PRISON_CELL5); + HandleGameObject(Door4GUID, false); + break; + case NOT_STARTED: + ResetPrisons(); + HandleGameObject(Door5GUID, false); + HandleGameObject(Door4GUID, true); + if (GameObject* lever = instance->GetGameObject(BroggokLeverGUID)) + lever->Respawn(); + break; + } + } + + void ResetPrisons() + { + PrisonerCounter5 = PrisonersCell5.size(); + ResetPrisoners(PrisonersCell5); + HandleGameObject(PrisonCell5GUID, false); + + PrisonerCounter6 = PrisonersCell6.size(); + ResetPrisoners(PrisonersCell6); + HandleGameObject(PrisonCell6GUID, false); + + PrisonerCounter7 = PrisonersCell7.size(); + ResetPrisoners(PrisonersCell7); + HandleGameObject(PrisonCell7GUID, false); + + PrisonerCounter8 = PrisonersCell8.size(); + ResetPrisoners(PrisonersCell8); + HandleGameObject(PrisonCell8GUID, false); + } + + void ResetPrisoners(std::set<uint64> prisoners) + { + for (std::set<uint64>::iterator i = prisoners.begin(); i != prisoners.end(); ++i) + if (Creature* prisoner = instance->GetCreature(*i)) + ResetPrisoner(prisoner); + } + + void ResetPrisoner(Creature* prisoner) + { + if (!prisoner->isAlive()) + prisoner->Respawn(true); + prisoner->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); + } + + void StorePrisoner(Creature* creature) + { + float posX = creature->GetPositionX(); + float posY = creature->GetPositionY(); + + if (posX >= 405.0f && posX <= 423.0f) + { + if (posY >= 106.0f && posY <= 123.0f) + { + PrisonersCell5.insert(creature->GetGUID()); + ++PrisonerCounter5; + } + else if (posY >= 76.0f && posY <= 91.0f) + { + PrisonersCell6.insert(creature->GetGUID()); + ++PrisonerCounter6; + } + else return; + } + else if (posX >= 490.0f && posX <= 506.0f) + { + if (posY >= 106.0f && posY <= 123.0f) + { + PrisonersCell7.insert(creature->GetGUID()); + ++PrisonerCounter7; + } + else if (posY >= 76.0f && posY <= 91.0f) + { + PrisonersCell8.insert(creature->GetGUID()); + ++PrisonerCounter8; + } + else + return; + } + else + return; + + ResetPrisoner(creature); + } + + void PrisonerDied(uint64 guid) + { + if (PrisonersCell5.find(guid) != PrisonersCell5.end() && --PrisonerCounter5 <= 0) + ActivateCell(DATA_PRISON_CELL6); + else if (PrisonersCell6.find(guid) != PrisonersCell6.end() && --PrisonerCounter6 <= 0) + ActivateCell(DATA_PRISON_CELL7); + else if (PrisonersCell7.find(guid) != PrisonersCell7.end() && --PrisonerCounter7 <= 0) + ActivateCell(DATA_PRISON_CELL8); + else if (PrisonersCell8.find(guid) != PrisonersCell8.end() && --PrisonerCounter8 <= 0) + ActivateCell(DATA_DOOR5); + } + + void ActivateCell(uint8 id) + { + switch (id) + { + case DATA_PRISON_CELL5: + HandleGameObject(PrisonCell5GUID,true); + ActivatePrisoners(PrisonersCell5); + break; + case DATA_PRISON_CELL6: + HandleGameObject(PrisonCell6GUID,true); + ActivatePrisoners(PrisonersCell6); + break; + case DATA_PRISON_CELL7: + HandleGameObject(PrisonCell7GUID,true); + ActivatePrisoners(PrisonersCell7); + break; + case DATA_PRISON_CELL8: + HandleGameObject(PrisonCell8GUID,true); + ActivatePrisoners(PrisonersCell8); + break; + case DATA_DOOR5: + HandleGameObject(Door5GUID,true); + if (Creature* broggok = instance->GetCreature(BroggokGUID)) + broggok->AI()->DoAction(ACTION_ACTIVATE_BROGGOK); + break; + } + } + + void ActivatePrisoners(std::set<uint64> prisoners) + { + for (std::set<uint64>::iterator i = prisoners.begin(); i != prisoners.end(); ++i) + if (Creature* prisoner = instance->GetCreature(*i)) + { + prisoner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); + prisoner->SetInCombatWithZone(); + } + } }; InstanceScript* GetInstanceScript(InstanceMap* map) const diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp index 872d9ec415c..c491852b1bd 100755 --- a/src/server/shared/Database/Implementation/WorldDatabase.cpp +++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp @@ -78,7 +78,7 @@ void WorldDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(WORLD_INS_CREATURE_TRANSPORT, "INSERT INTO creature_transport (guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO) values (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_CREATURE_TRANSPORT_EMOTE, "UPDATE creature_transport SET emote = ? WHERE transport_entry = ? AND guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_SEL_COMMANDS, "SELECT name, security, help FROM command", CONNECTION_SYNCH); - PREPARE_STATEMENT(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_SEL_IP2NATION_COUNTRY, "SELECT c.country FROM ip2nationCountries c, ip2nation i WHERE i.ip < ? AND c.code = i.country ORDER BY i.ip DESC LIMIT 0,1", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH); |
