void PointMovementGenerator<Creature>::MovementInform(Creature &unit) { if (unit.AI()) unit.AI()->MovementInform(POINT_MOTION_TYPE, id); if (unit.IsTemporarySummon()) { TemporarySummon* pSummon = (TemporarySummon*)(&unit); if (pSummon->GetSummonerGuid().IsCreature()) if(Creature* pSummoner = unit.GetMap()->GetCreature(pSummon->GetSummonerGuid())) if (pSummoner->AI()) pSummoner->AI()->SummonedMovementInform(&unit, POINT_MOTION_TYPE, id); } }
void SpawnFlameTriggers(uint8 point) { for(uint8 j = 0; j < 50; ++j) { if (point == 1) me->SummonCreature(NPC_BREATH_TRIGGER, 480.0f-(j*3), -518.0f+(j/16.0f), 105.0f, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); else me->SummonCreature(NPC_BREATH_TRIGGER, 480.0f-(j*3), -510.0f+(j/16.0f), 105.0f, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); } // and out of loop, cover the small room if (point == 0) { Creature *cr; if (cr = me->SummonCreature(NPC_BREATH_TRIGGER, 483, -484.9f, 105, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000)) cr->CastSpell(cr, cr->GetMap()->IsHeroic() ? SPELL_FLAME_BREATH_H : SPELL_FLAME_BREATH_N, true); if (cr = me->SummonCreature(NPC_BREATH_TRIGGER, 471.0f, -484.7f, 105, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000)) cr->CastSpell(cr, cr->GetMap()->IsHeroic() ? SPELL_FLAME_BREATH_H : SPELL_FLAME_BREATH_N, true); for (uint8 j = 0; j < 7; j++) if (cr = me->SummonCreature(NPC_BREATH_TRIGGER, 477.0f, -507.0f+(j*3), 105.0f, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000)) cr->CastSpell(cr, cr->GetMap()->IsHeroic() ? SPELL_FLAME_BREATH_H : SPELL_FLAME_BREATH_N, true); } }
void ObjectGridEvacuator::Visit(CreatureMapType &m) { // creature in unloading grid can have respawn point in another grid // if it will be unloaded then it will not respawn in original grid until unload/load original grid // move to respawn point to prevent this case. For player view in respawn grid this will be normal respawn. for (CreatureMapType::iterator iter = m.begin(); iter != m.end();) { Creature* c = iter->getSource(); ++iter; ASSERT(!c->isPet() && "ObjectGridRespawnMover must not be called for pets"); c->GetMap()->CreatureRespawnRelocation(c, true); } }
Transport::~Transport() { for(CreatureSet::iterator itr = m_NPCPassengerSet.begin(); itr != m_NPCPassengerSet.end(); ++itr) { Creature* passenger = *itr; Map* map = passenger->GetMap(); passenger->SetTransport(NULL); passenger->CleanupsBeforeDelete(); map->Remove(passenger, true); } m_NPCPassengerSet.clear(); m_WayPoints.clear(); m_passengers.clear(); }
void SpawnAdds() { for (uint8 i = 0; i < 4; ++i) { Creature *pCreature = (Unit::GetCreature((*me), AddGUID[i])); if (!pCreature || !pCreature->isAlive()) { if (pCreature) pCreature->setDeathState(DEAD); pCreature = me->SummonCreature(AddEntry[i], Pos_X[i], POS_Y, POS_Z, ORIENT, TEMPSUMMON_DEAD_DESPAWN, 0); if (pCreature) AddGUID[i] = pCreature->GetGUID(); } else { pCreature->AI()->EnterEvadeMode(); pCreature->GetMap()->CreatureRelocation(me, Pos_X[i], POS_Y, POS_Z, ORIENT); pCreature->StopMoving(); } } }
bool ChargeMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff) { i_nextMoveTime.Update(diff); if(i_nextMoveTime.Passed()) { i_nextMoveTime.Reset(m_pointTime); float angle = creature.GetAngle(m_path[curPoint].x,m_path[curPoint].y); creature.GetMap()->CreatureRelocation(&creature, m_path[curPoint].x, m_path[curPoint].y, m_path[curPoint].z, angle); if(curPoint >= m_end) { creature.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); return false; } ++curPoint; } return true; }
void WaypointMovementGenerator<Creature>::OnArrived(Creature& creature) { if (!i_path || i_path->empty()) return; if (m_isArrivalDone) return; creature.ClearUnitState(UNIT_STAT_ROAMING_MOVE); m_isArrivalDone = true; if (i_path->at(i_currentNode)->event_id && urand(0, 99) < i_path->at(i_currentNode)->event_chance) { sLog->outDebug(LOG_FILTER_MAPSCRIPTS, "Creature movement start script %u at point %u for %u.", i_path->at(i_currentNode)->event_id, i_currentNode, creature.GetGUID()); creature.GetMap()->ScriptsStart(sWaypointScripts, i_path->at(i_currentNode)->event_id, &creature, NULL/*, false*/); } // Inform script MovementInform(creature); Stop(i_path->at(i_currentNode)->delay); }
bool EffectAuraDummy_npc_scourged_flamespitter(const Aura* pAura, bool bApply) { if (pAura->GetId() == SPELL_REINFORCED_NET && pAura->GetEffIndex() == EFFECT_INDEX_0 && bApply) { Creature* pCreature = (Creature*)pAura->GetTarget(); Unit* pCaster = pAura->GetCaster(); if (!pCreature || !pCaster || pCaster->GetTypeId() != TYPEID_PLAYER || pCreature->GetEntry() != NPC_FLAMESPITTER) return false; // move the flamespitter to the ground level pCreature->GetMotionMaster()->Clear(); pCreature->SetWalk(false); float fGroundZ = pCreature->GetMap()->GetHeight(pCreature->GetPhaseMask(), pCreature->GetPositionX(), pCreature->GetPositionY(), pCreature->GetPositionZ()); pCreature->GetMotionMaster()->MovePoint(1, pCreature->GetPositionX(), pCreature->GetPositionY(), fGroundZ); return true; } return false; }
bool HomeMovementGenerator<Creature>::Update(Creature &owner, const uint32& time_diff) { CreatureTraveller traveller(owner); i_destinationHolder.UpdateTraveller(traveller, time_diff); if (time_diff > i_travel_timer) { float x, y, z; owner.GetRespawnCoord(x, y, z); float myx, myy, myz; owner.GetPosition(myx, myy, myz); if (x != myx || y != myy || z != myz) { Position travelto = owner.GetMap()->getNextPositionOnPathToLocation(myx,myy,myz,x,y,z); uint32 travel_time = i_destinationHolder.SetDestination(traveller, travelto.m_positionX, travelto.m_positionY, travelto.m_positionZ); modifyTravelTime(travel_time); return true; } owner.AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); // restore orientation of not moving creature at returning to home if (owner.GetDefaultMovementType() == IDLE_MOTION_TYPE) { //sLog.outDebug("Entering HomeMovement::GetDestination(z,y,z)"); owner.SetOrientation(ori); WorldPacket packet; owner.BuildHeartBeatMsg(&packet); owner.SendMessageToSet(&packet, false); } owner.clearUnitState(UNIT_STAT_EVADE); owner.AI()->JustReachedHome(); return false; } i_travel_timer -= time_diff; return true; }
void instance_uldaman::Update(uint32 uiDiff) { if (GetData(TYPE_ALTAR_EVENT) != IN_PROGRESS) return; if (!m_uiKeeperCooldown) return; if (m_uiKeeperCooldown <= uiDiff) { for (GuidList::const_iterator itr = m_lKeepers.begin(); itr != m_lKeepers.end(); ++itr) { // Get Keeper which is alive and out of combat Creature* pKeeper = instance->GetCreature(*itr); if (!pKeeper || !pKeeper->IsAlive() || pKeeper->getVictim()) continue; // Get starter player for attack Player* pPlayer = pKeeper->GetMap()->GetPlayer(m_playerGuid); if (!pPlayer || !pPlayer->IsAlive()) { // If he's not available, then get a random player, within a reasonamble distance in map pPlayer = GetPlayerInMap(true, false); if (!pPlayer || !pPlayer->IsWithinDistInMap(pKeeper, 50.0f)) { SetData(TYPE_ALTAR_EVENT, NOT_STARTED); return; } } // Attack the player pKeeper->RemoveAurasDueToSpell(SPELL_STONED); pKeeper->AI()->AttackStart(pPlayer); break; } m_uiKeeperCooldown = 0; } else m_uiKeeperCooldown -= uiDiff; }
void ObjectGridRespawnMover::Visit(CreatureMapType &m) { // creature in unloading grid can have respawn point in another grid // if it will be unloaded then it will not respawn in original grid until unload/load original grid // move to respawn point to prevent this case. For player view in respawn grid this will be normal respawn. for (CreatureMapType::iterator iter = m.begin(); iter != m.end();) { Creature * c = iter->getSource(); ++iter; ASSERT(!c->isPet() && "ObjectGridRespawnMover don't must be called for pets"); Cell const& cur_cell = c->GetCurrentCell(); float resp_x, resp_y, resp_z; c->GetRespawnCoord(resp_x, resp_y, resp_z); CellPair resp_val = Trinity::ComputeCellPair(resp_x, resp_y); Cell resp_cell(resp_val); if (cur_cell.DiffGrid(resp_cell)) { c->GetMap()->CreatureRespawnRelocation(c); // false result ignored: will be unload with other creatures at grid } } }
void Test() override { switch (GetTestStep()) { case 0: { Creature* c = SpawnCreature(1, 1); if (!c) Fail("Failed to summon a creature"); else if (c->GetMap() != GetMap()) Fail("Creature summoned on the wrong map"); else if (!c->FindNearestCreature(NPC_MAGMADAR, 50.0f)) Fail("Unit magmadar not found near creature"); SpawnPlayer(0, CLASS_WARLOCK, RACE_GNOME); Wait(500); NextStep(); break; } case 1: { Player* p = GetTestPlayer(0); if (!p) Fail("Unable to summon a player"); else if (p->getClass() != CLASS_WARLOCK && p->getRace() != RACE_GNOME) Fail("Bad player class or race"); else if (p->FindMap() != GetMap()) Fail("Bad player map"); else if (p->GetInstanceId() != GetMap()->GetInstanceId()) Fail("Diff instance id (player vs map)"); else if (!p->FindNearestCreature(NPC_MAGMADAR, 50.0f)) Fail("Unit magmadar not found near player"); else Finish(); return; } } }
bool EffectDummy(Unit* /*pCaster*/, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Object* pTarget, ObjectGuid /*originalCasterGuid*/) override { Creature* pCreatureTarget = pTarget->ToCreature(); if (uiEffIndex != EFFECT_INDEX_0 || pCreatureTarget->GetEntry() != NPC_SUB_BOSS_TRIGGER) return true; ScriptedInstance* pInstance = (ScriptedInstance*)pCreatureTarget->GetInstanceData(); if (!pInstance) return true; if (Creature* ptarget = pCreatureTarget->GetMap()->GetCreature(ObjectGuid(pInstance->GetData64(DATA64_GOTH_RANDOM_LEFT)))) { uint32 uiTriggered = SPELL_A_TO_SKULL; if (uiSpellId == SPELL_B_TO_ANCHOR_2) uiTriggered = SPELL_B_TO_SKULL; else if (uiSpellId == SPELL_C_TO_ANCHOR_2) uiTriggered = SPELL_C_TO_SKULL; pCreatureTarget->CastSpell(ptarget, uiTriggered, true); } return true; }
void RandomMovementGenerator<Creature>::_setRandomLocation(Creature& creature) { float destX = i_x; float destY = i_y; float destZ = i_z; creature.addUnitState(UNIT_STAT_ROAMING_MOVE); // check if new random position is assigned, GetReachableRandomPosition may fail if (creature.GetMap()->GetReachableRandomPosition(&creature, destX, destY, destZ, i_radius)) { Movement::MoveSplineInit init(creature); init.MoveTo(destX, destY, destZ, true); init.SetWalk(true); init.Launch(); if (roll_chance_i(MOVEMENT_RANDOM_MMGEN_CHANCE_NO_BREAK)) i_nextMoveTime.Reset(50); else i_nextMoveTime.Reset(urand(3000, 10000)); // Keep a short wait time } else i_nextMoveTime.Reset(50); // Retry later return; }
void FilterTargets(std::list<WorldObject*>& targets) { // Shards of torment seems to target tanks if no other targets are available as of Warlords of Draenor if (targets.size() <= 1) { _hasTarget = !targets.empty(); return; } Creature* caster = GetCaster()->ToCreature(); if (!caster || !caster->IsAIEnabled) return; if (WorldObject* tank = caster->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO)) targets.remove(tank); std::list<WorldObject*> melee, ranged; for (WorldObject* target : targets) { if (caster->IsWithinMeleeRange(target->ToUnit())) melee.push_back(target); else ranged.push_back(target); } targets.clear(); if (caster->GetMap()->Is25ManRaid()) if (WorldObject* target = GetRandomContainerElement(ranged, melee)) targets.push_back(target); if (WorldObject* target = GetRandomContainerElement(melee, ranged)) targets.push_back(target); _hasTarget = !targets.empty(); }
void WaypointMovementGenerator<Creature>::OnArrived(Creature& creature) { if (!i_path || i_path->empty()) { return; } m_lastReachedWaypoint = i_currentNode; if (m_isArrivalDone) { return; } creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); m_isArrivalDone = true; WaypointPath::const_iterator currPoint = i_path->find(i_currentNode); MANGOS_ASSERT(currPoint != i_path->end()); WaypointNode const& node = currPoint->second; if (node.script_id) { DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature movement start script %u at point %u for %s.", node.script_id, i_currentNode, creature.GetGuidStr().c_str()); creature.GetMap()->ScriptsStart(DBS_ON_CREATURE_MOVEMENT, node.script_id, &creature, &creature); } // We have reached the destination and can process behavior if (WaypointBehavior* behavior = node.behavior) { if (behavior->emote != 0) { creature.HandleEmote(behavior->emote); } if (behavior->spell != 0) { creature.CastSpell(&creature, behavior->spell, false); } if (behavior->model1 != 0) { creature.SetDisplayId(behavior->model1); } if (behavior->textid[0]) { int32 textId = behavior->textid[0]; // Not only one text is set if (behavior->textid[1]) { // Select one from max 5 texts (0 and 1 already checked) int i = 2; for (; i < MAX_WAYPOINT_TEXT; ++i) { if (!behavior->textid[i]) { break; } } textId = behavior->textid[urand(0, i - 1)]; } if (MangosStringLocale const* textData = sObjectMgr.GetMangosStringLocale(textId)) { creature.MonsterText(textData, NULL); } else { sLog.outErrorDb("%s reached waypoint %u, attempted to do text %i, but required text-data could not be found", creature.GetGuidStr().c_str(), i_currentNode, textId); } } } // Inform script if (creature.AI()) { uint32 type = WAYPOINT_MOTION_TYPE; if (m_PathOrigin == PATH_FROM_EXTERNAL && m_pathId > 0) type = EXTERNAL_WAYPOINT_MOVE + m_pathId; creature.AI()->MovementInform(type, i_currentNode); } // Wait delay ms Stop(node.delay); }
bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff) { if (!&creature) return true; // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff if (creature.hasUnitState(UNIT_STAT_NOT_MOVE)) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } // prevent a crash at empty waypoint path. if (!i_path || i_path->empty()) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } if (i_currentNode >= i_path->size()) { sLog.outError("WaypointMovement currentNode (%u) is equal or bigger than path size (creature entry %u)", i_currentNode, creature.GetEntry()); i_currentNode = 0; } CreatureTraveller traveller(creature); i_nextMoveTime.Update(diff); if (i_destinationHolder.UpdateTraveller(traveller, diff, false, true)) { if (!IsActive(creature)) // force stop processing (movement can move out active zone with cleanup movegens list) return true; // not expire now, but already lost } // creature has been stopped in middle of the waypoint segment if (!i_destinationHolder.HasArrived() && creature.IsStopped()) { // Timer has elapsed, meaning this part controlled it if (i_nextMoveTime.Passed()) { SetStoppedByPlayer(false); creature.addUnitState(UNIT_STAT_ROAMING_MOVE); if (creature.canFly()) creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); // Now we re-set destination to same node and start travel const WaypointNode &node = i_path->at(i_currentNode); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); } else // if( !i_nextMoveTime.Passed()) { // unexpected end of timer && creature stopped && not at end of segment if (!IsStoppedByPlayer()) { // Put 30 seconds delay i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER); i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER); SetStoppedByPlayer(true); // Mark we did it } } return true; // Abort here this update } if (creature.IsStopped()) { if (!m_isArrivalDone) { if (i_path->at(i_currentNode).orientation != 100) creature.SetOrientation(i_path->at(i_currentNode).orientation); if (i_path->at(i_currentNode).script_id) { DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature movement start script %u at point %u for creature %u (entry %u).", i_path->at(i_currentNode).script_id, i_currentNode, creature.GetDBTableGUIDLow(), creature.GetEntry()); creature.GetMap()->ScriptsStart(sCreatureMovementScripts, i_path->at(i_currentNode).script_id, &creature, &creature); } // We have reached the destination and can process behavior if (WaypointBehavior *behavior = i_path->at(i_currentNode).behavior) { if (behavior->emote != 0) creature.HandleEmote(behavior->emote); if (behavior->spell != 0) { creature.CastSpell(&creature, behavior->spell, false); if (!IsActive(creature)) // force stop processing (cast can change movegens list) return true; // not expire now, but already lost } if (behavior->model1 != 0) creature.SetDisplayId(behavior->model1); if (behavior->textid[0]) { // Not only one text is set if (behavior->textid[1]) { // Select one from max 5 texts (0 and 1 already checked) int i = 2; for(; i < MAX_WAYPOINT_TEXT; ++i) { if (!behavior->textid[i]) break; } creature.Say(behavior->textid[rand() % i], 0, 0); } else creature.Say(behavior->textid[0], 0, 0); } } // wpBehaviour found // Can only do this once for the node m_isArrivalDone = true; // Inform script MovementInform(creature); if (!IsActive(creature)) // force stop processing (movement can move out active zone with cleanup movegens list) return true; // not expire now, but already lost // prevent a crash at empty waypoint path. if (!i_path || i_path->empty() || i_currentNode >= i_path->size()) { creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } } } // i_creature.IsStopped() // This is at the end of waypoint segment (incl. was previously stopped by player, extending the time) if (i_nextMoveTime.Passed()) { // If stopped then begin a new move segment if (creature.IsStopped()) { creature.addUnitState(UNIT_STAT_ROAMING_MOVE); if (creature.canFly()) creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); if (WaypointBehavior *behavior = i_path->at(i_currentNode).behavior) { if (behavior->model2 != 0) creature.SetDisplayId(behavior->model2); creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); } // behavior for "departure" of the current node is done m_isArrivalDone = false; // Proceed with increment current node and then send to the next destination ++i_currentNode; // Oops, end of the line so need to start from the beginning if (i_currentNode >= i_path->size()) i_currentNode = 0; if (i_path->at(i_currentNode).orientation != 100) creature.SetOrientation(i_path->at(i_currentNode).orientation); const WaypointNode &node = i_path->at(i_currentNode); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); } else { // If not stopped then stop it creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); SetStoppedByPlayer(false); // Set TimeTracker to waittime for the current node i_nextMoveTime.Reset(i_path->at(i_currentNode).delay); } } return true; }
void HandleDummy(SpellEffIndex /*effIndex*/) { uint32 roll = urand(1, 100); uint8 ev; if (roll <= 50) ev = EVENT_MISS; else if (roll <= 83) ev = EVENT_HIT; else ev = EVENT_MISS_BIRD; Unit* shooter = GetCaster(); Creature* wilhelm = GetHitUnit()->ToCreature(); Creature* apple = shooter->FindNearestCreature(NPC_APPLE, 30); Creature* drostan = shooter->FindNearestCreature(NPC_DROSTAN, 30); if (!wilhelm || !apple || !drostan) return; switch (ev) { case EVENT_MISS_BIRD: { Creature* crunchy = shooter->FindNearestCreature(NPC_CRUNCHY, 30); Creature* bird = shooter->FindNearestCreature(NPC_THICKBIRD, 30); if (!bird || !crunchy) ; // fall to EVENT_MISS else { shooter->CastSpell(bird, SPELL_MISS_BIRD_APPLE); bird->CastSpell(bird, SPELL_BIRD_FALL); wilhelm->AI()->Talk(SAY_WILHELM_MISS); drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS); bird->KillSelf(); crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(), bird->GetMap()->GetWaterOrGroundLevel(bird->GetPhaseShift(), bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ())); /// @todo Make crunchy perform emote eat when he reaches the bird break; } } case EVENT_MISS: { shooter->CastSpell(wilhelm, SPELL_MISS_APPLE); wilhelm->AI()->Talk(SAY_WILHELM_MISS); drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS); break; } case EVENT_HIT: { shooter->CastSpell(apple, SPELL_HIT_APPLE); apple->CastSpell(apple, SPELL_APPLE_FALL); wilhelm->AI()->Talk(SAY_WILHELM_HIT); if (Player* player = shooter->ToPlayer()) player->KilledMonsterCredit(NPC_APPLE); break; } } }
//move selected creature static bool HandleNpcMoveCommand(ChatHandler* handler, const char* args) { uint32 lowguid = 0; Creature* pCreature = handler->getSelectedCreature(); if (!pCreature) { // number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r char* cId = handler->extractKeyFromLink((char*)args,"Hcreature"); if (!cId) return false; lowguid = atoi(cId); /* FIXME: impossible without entry if (lowguid) pCreature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(),MAKE_GUID(lowguid,HIGHGUID_UNIT)); */ // Attempting creature load from DB data if (!pCreature) { CreatureData const* data = sObjectMgr->GetCreatureData(lowguid); if (!data) { handler->PSendSysMessage(LANG_COMMAND_CREATGUIDNOTFOUND, lowguid); handler->SetSentErrorMessage(true); return false; } uint32 map_id = data->mapid; if (handler->GetSession()->GetPlayer()->GetMapId() != map_id) { handler->PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, lowguid); handler->SetSentErrorMessage(true); return false; } } else { lowguid = pCreature->GetDBTableGUIDLow(); } } else { lowguid = pCreature->GetDBTableGUIDLow(); } float x = handler->GetSession()->GetPlayer()->GetPositionX(); float y = handler->GetSession()->GetPlayer()->GetPositionY(); float z = handler->GetSession()->GetPlayer()->GetPositionZ(); float o = handler->GetSession()->GetPlayer()->GetOrientation(); if (pCreature) { if (CreatureData const* data = sObjectMgr->GetCreatureData(pCreature->GetDBTableGUIDLow())) { const_cast<CreatureData*>(data)->posX = x; const_cast<CreatureData*>(data)->posY = y; const_cast<CreatureData*>(data)->posZ = z; const_cast<CreatureData*>(data)->orientation = o; } pCreature->GetMap()->CreatureRelocation(pCreature,x, y, z,o); pCreature->GetMotionMaster()->Initialize(); if (pCreature->isAlive()) // dead creature will reset movement generator at respawn { pCreature->setDeathState(JUST_DIED); pCreature->Respawn(); } } WorldDatabase.PExecute("UPDATE creature SET position_x = '%f', position_y = '%f', position_z = '%f', orientation = '%f' WHERE guid = '%u'", x, y, z, o, lowguid); handler->PSendSysMessage(LANG_COMMAND_CREATUREMOVED); return true; }
void WorldSession::SendListInventory(ObjectGuid vendorguid) { DEBUG_LOG("WORLD: Sent SMSG_LIST_INVENTORY"); Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR); if (!pCreature) { DEBUG_LOG("WORLD: SendListInventory - %s not found or you can't interact with him.", vendorguid.GetString().c_str()); _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, ObjectGuid(), 0); return; } // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); // Stop the npc if moving if (!pCreature->IsStopped()) pCreature->StopMoving(); VendorItemData const* vItems = pCreature->GetVendorItems(); VendorItemData const* tItems = pCreature->GetVendorTemplateItems(); uint8 customitems = vItems ? vItems->GetItemCount() : 0; uint8 numitems = customitems + (tItems ? tItems->GetItemCount() : 0); std::vector<bool> bitFlags; float discountMod = _player->GetReputationPriceDiscount(pCreature); uint8 count = 0; ByteBuffer buffer; for (uint8 vendorslot = 0; vendorslot < numitems; ++vendorslot) { VendorItem const* crItem = vendorslot < customitems ? vItems->GetItem(vendorslot) : tItems->GetItem(vendorslot - customitems); if (crItem) { uint32 price, displayId, buyCount, maxDurability; int32 maxCount; if (crItem->type == VENDOR_ITEM_TYPE_ITEM) { ItemPrototype const * pProto = ObjectMgr::GetItemPrototype(crItem->item); if (!pProto) continue; if (!_player->isGameMaster()) { // class wrong item skip only for bindable case if ((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP) continue; // race wrong item skip always if ((pProto->Flags2 & ITEM_FLAG2_HORDE_ONLY) && _player->GetTeam() != HORDE) continue; if ((pProto->Flags2 & ITEM_FLAG2_ALLIANCE_ONLY) && _player->GetTeam() != ALLIANCE) continue; if ((pProto->AllowableRace & _player->getRaceMask()) == 0) continue; if (crItem->conditionId && !sObjectMgr.IsPlayerMeetToCondition(crItem->conditionId, _player, pCreature->GetMap(), pCreature, CONDITION_FROM_VENDOR)) continue; } // possible item coverting for BoA case if (pProto->Flags & ITEM_FLAG_BOA) { // convert if can use and then buy if (pProto->RequiredReputationFaction && uint32(_player->GetReputationRank(pProto->RequiredReputationFaction)) >= pProto->RequiredReputationRank) { // checked at convert data loading as existed if (uint32 newItemId = sObjectMgr.GetItemConvert(crItem->item, _player->getRaceMask())) pProto = ObjectMgr::GetItemPrototype(newItemId); } } ++count; if (count >= MAX_VENDOR_ITEMS) break; // reputation discount maxDurability = pProto->MaxDurability; price = (crItem->ExtendedCost == 0 || pProto->Flags2 & ITEM_FLAG2_EXT_COST_REQUIRES_GOLD) ? uint32(floor(pProto->BuyPrice * discountMod)) : 0; displayId = pProto->DisplayInfoID; maxCount = crItem->maxcount <= 0 ? -1 : int32(pCreature->GetVendorItemCurrentCount(crItem)); buyCount = pProto->BuyCount; } else if (crItem->type == VENDOR_ITEM_TYPE_CURRENCY) { CurrencyTypesEntry const * pCurrency = sCurrencyTypesStore.LookupEntry(crItem->item); if (!pCurrency) continue; if (pCurrency->Category == CURRENCY_CATEGORY_META) continue; ++count; if (count >= MAX_VENDOR_ITEMS) break; maxDurability = 0; price = 0; displayId = 0; maxCount = -1; buyCount = crItem->maxcount; } else continue; bitFlags.push_back(crItem->ExtendedCost == 0); bitFlags.push_back(true); // unk buffer << uint32(vendorslot + 1); // client size expected counting from 1 buffer << uint32(maxDurability); if (crItem->ExtendedCost) buffer << uint32(crItem->ExtendedCost); buffer << uint32(crItem->item); buffer << uint32(crItem->type); buffer << uint32(price); buffer << uint32(displayId); buffer << int32(maxCount); buffer << uint32(buyCount); } } WorldPacket data(SMSG_LIST_INVENTORY, (8 + 3 + 1 + 1 + numitems * 8 * 4)); data.WriteGuidMask<1, 0>(vendorguid); data.WriteBits(count, 21); data.WriteGuidMask<3, 6, 5, 2, 7>(vendorguid); for (uint32 i = 0; i < bitFlags.size(); ++i) data.WriteBit(bitFlags[i]); data.WriteGuidMask<4>(vendorguid); data.FlushBits(); data.append(buffer); data.WriteGuidBytes<5, 4, 1, 0, 6>(vendorguid); data << uint8(count == 0); data.WriteGuidBytes<2, 3, 7>(vendorguid); SendPacket(&data); }
void SetData(uint32 type, uint32 data) { switch(type) { case DATA_RAGEWINTERCHILLEVENT: Encounters[0] = data; break; case DATA_ANETHERONEVENT: Encounters[1] = data; break; case DATA_KAZROGALEVENT: Encounters[2] = data; break; case DATA_AZGALOREVENT: { Encounters[3] = data; if(data==DONE) { if(ArchiYell)break; ArchiYell = true; Creature* pCreature = instance->GetCreatureInMap(Azgalor); if(pCreature) { Creature* pUnit = pCreature->SummonCreature(21987,pCreature->GetPositionX(),pCreature->GetPositionY(),pCreature->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,10000); Map *map = pCreature->GetMap(); if (map->IsDungeon() && pUnit) { pUnit->SetVisibility(VISIBILITY_OFF); Map::PlayerList const &PlayerList = map->GetPlayers(); if (PlayerList.isEmpty()) return; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()) { WorldPacket data(SMSG_MESSAGECHAT, 200); pUnit->BuildMonsterChat(&data,CHAT_MSG_MONSTER_YELL,"All of your efforts have been in vain, for the draining of the World Tree has already begun. Soon the heart of your world will beat no more.",0,"Archimonde",i->getSource()->GetGUID()); i->getSource()->GetSession()->SendPacket(&data); WorldPacket data2(SMSG_PLAY_SOUND, 4); data2 << 10986; i->getSource()->GetSession()->SendPacket(&data2); } } } } } } break; case DATA_ARCHIMONDEEVENT: Encounters[4] = data; break; case DATA_RESET_TRASH_COUNT: Trash = 0; break; case DATA_TRASH: if(data) Trash = data; else Trash--; UpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash); break; case DATA_ALLIANCE_RETREAT: allianceRetreat = data; OpenDoor(HordeGate,true); SaveToDB(); break; case DATA_HORDE_RETREAT: hordeRetreat = data; OpenDoor(ElfGate,true); SaveToDB(); break; case DATA_RAIDDAMAGE: RaidDamage += data; if(RaidDamage >= MINRAIDDAMAGE) RaidDamage = MINRAIDDAMAGE; break; case DATA_RESET_RAIDDAMAGE: RaidDamage = 0; break; } debug_log("SD2: Instance Hyjal: Instance data updated for event %u (Data=%u)",type,data); if(data == DONE) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; saveStream << Encounters[0] << " " << Encounters[1] << " " << Encounters[2] << " " << Encounters[3] << " " << Encounters[4] << " " << allianceRetreat << " " << hordeRetreat << " " << RaidDamage; str_data = saveStream.str(); SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; } }
void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature) { float X,Y,Z,nx,ny,nz,wander_distance,ori,dist; creature.GetRespawnCoord(X, Y, Z, &ori, &wander_distance); Z = creature.GetPositionZ(); TerrainInfo const* map = creature.GetTerrain(); // For 2D/3D system selection //bool is_land_ok = creature.canWalk(); // not used? //bool is_water_ok = creature.canSwim(); // not used? bool is_air_ok = creature.canFly(); const float angle = rand_norm_f()*(M_PI_F*2.0f); const float range = rand_norm_f()*wander_distance; const float distanceX = range * cos(angle); const float distanceY = range * sin(angle); nx = X + distanceX; ny = Y + distanceY; nz = Z; // prevent invalid coordinates generation MaNGOS::NormalizeMapCoord(nx); MaNGOS::NormalizeMapCoord(ny); dist = distanceX*distanceX + distanceY*distanceY; if (is_air_ok) // 3D system above ground and above water (flying mode) { // Limit height change const float distanceZ = rand_norm_f() * sqrtf(dist)/2.0f; if(urand(0, 1)) nz += distanceZ; else nz -= distanceZ; if(fabs(nz-Z) > wander_distance) nz = Z; float tz = map->GetHeight(nx, ny, nz, true); // Map check only, vmap needed here but need to alter vmaps checks for height. float wz = map->GetWaterLevel(nx, ny, nz); // Problem here, we must fly above the ground and water, not under. Let's try on next tick if (tz >= nz || wz >= nz) return; } //else if (is_water_ok) // 3D system under water and above ground (swimming mode) else // 2D only { nz = Z; if (!creature.GetMap()->IsNextZcoordOK(nx, ny, nz, dist)) return; // let's forget this bad coords where a z cannot be find and retry at next tick creature.UpdateGroundPositionZ(nx, ny, nz, dist); } Traveller<Creature> traveller(creature); creature.SetOrientation(creature.GetAngle(nx, ny)); i_destinationHolder.SetDestination(traveller, nx, ny, nz); creature.addUnitState(UNIT_STAT_ROAMING_MOVE); if (is_air_ok && !(creature.canWalk() && creature.IsAtGroundLevel(Coords(nx, ny, nz)))) { i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7); } //else if (is_water_ok) // Swimming mode to be done with more than this check else { i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(), 10000+i_destinationHolder.GetTotalTravelTime())); creature.AddSplineFlag(SPLINEFLAG_WALKMODE); } }
/* Tribute Event */ void instance_dire_maul::GordokTributeEvent(uint32 diff) { if(1<2)return; Creature* pChoRush = instance->GetCreature(m_uiChoRushGUID); Creature* pMizzle = instance->GetCreature(m_uiMizzleGUID); Creature* pTrigger = instance->GetCreature(m_uiTributeTriggerGUID); Map* pMap; pMap = pChoRush->GetMap(); Map::PlayerList const &PlayerList = pMap->GetPlayers(); if ((GetData(TYPE_KING_GORDOK) == DONE) && pMap->GetCreature(m_uiChoRushGUID)->isAlive() && !pChoRushHome) { pChoRush->SetFlag(UNIT_NPC_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PASSIVE); pChoRush->setFaction(35); pChoRush->DeleteThreatList(); pChoRush->CombatStop(); pChoRush->SetCanAttackPlayer(false); pChoRush->AI()->EnterEvadeMode(); pChoRushHome = true; GossipStepGordok = 1; Text_Timer_Event = 1000; } else if ((TYPE_KING_GORDOK == DONE) && pMap->GetCreature(m_uiChoRushGUID)->isDead()) { for(Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) { Player* pPlayer = itr->getSource(); if (pPlayer->IsWithinDistInMap(pTrigger, 30.0f)) pTrigger->CastSpell(pPlayer, SPELL_KING_OF_GORDOK, false); } } if(pChoRushHome) { if (Text_Timer_Event<diff) { switch (GossipStepGordok) { case 1: DoScriptText(ChoRush_SAY_1, pChoRush); pChoRush->HandleEmote(EMOTE_STATE_TALK); pChoRush->SummonCreature(NPC_MIZZLE_THE_CRAFTY, 817.666f, 478.371f, 37.3182f, 3.07057f, TEMPSUMMON_TIMED_DESPAWN, 9000000); Text_Timer_Event = 5000; break; case 2: pChoRush->HandleEmote(EMOTE_STATE_SIT); DoScriptText(Mizzle_SAY_1, pMizzle); pMizzle->HandleEmote(EMOTE_STATE_TALK); Text_Timer_Event = 5000; break; case 3: DoScriptText(Mizzle_SAY_2, pMizzle); pMizzle->HandleEmote(EMOTE_STATE_TALK); Text_Timer_Event = 8000; break; case 4: for(Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) { Player* pPlayer = itr->getSource(); if (pPlayer->IsWithinDistInMap(pMizzle, 50.0f)) pMizzle->CastSpell(pPlayer, SPELL_KING_OF_GORDOK, false); } if (pMap->GetCreature(m_uiMoldarGUID)->isAlive() && pMap->GetCreature(m_uiMizzleGUID)->isAlive() && pMap->GetCreature(m_uiFengusGUID)->isAlive()) { pMizzle->SummonObject(pMap, GO_GORDOK_TRIBUTE, 809.899719f, 482.306366f, 37.318359f, 0.212846f); pMizzle->HandleEmote(EMOTE_ONESHOT_APPLAUD); } pChoRushHome = false; break; } } else Text_Timer_Event -= diff; } }
void WorldSession::SendListInventory(ObjectGuid vendorguid) { DEBUG_LOG("WORLD: Sent SMSG_LIST_INVENTORY"); Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR); if (!pCreature) { DEBUG_LOG("WORLD: SendListInventory - %s not found or you can't interact with him.", vendorguid.GetString().c_str()); _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, ObjectGuid(), 0); return; } // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); // Stop the npc if moving pCreature->StopMoving(); VendorItemData const* vItems = pCreature->GetVendorItems(); VendorItemData const* tItems = pCreature->GetVendorTemplateItems(); if (!vItems && !tItems) { WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + 1)); data << ObjectGuid(vendorguid); data << uint8(0); // count==0, next will be error code data << uint8(0); // "Vendor has no inventory" SendPacket(&data); return; } uint8 customitems = vItems ? vItems->GetItemCount() : 0; uint8 numitems = customitems + (tItems ? tItems->GetItemCount() : 0); uint8 count = 0; WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + numitems * 8 * 4)); data << ObjectGuid(vendorguid); size_t count_pos = data.wpos(); data << uint8(count); float discountMod = _player->GetReputationPriceDiscount(pCreature); for (int i = 0; i < numitems; ++i) { VendorItem const* crItem = i < customitems ? vItems->GetItem(i) : tItems->GetItem(i - customitems); if (crItem) { uint32 itemId = crItem->item; ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemId); if (pProto) { if (!_player->isGameMaster()) { // class wrong item skip only for bindable case if ((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP) continue; // race wrong item skip always if ((pProto->AllowableRace & _player->getRaceMask()) == 0) continue; if (crItem->conditionId && !sObjectMgr.IsPlayerMeetToCondition(crItem->conditionId, _player, pCreature->GetMap(), pCreature, CONDITION_FROM_VENDOR)) continue; } ++count; uint32 price = 0; // check if the item to sell is a mount switch (itemId) { case 1132: // all normal mounts case 2411: case 2414: case 5655: case 5656: case 5665: case 5668: case 5864: case 5872: case 5873: case 8563: case 8588: case 8591: case 8592: case 8595: case 8629: case 8631: case 8632: case 13321: case 13322: case 13331: case 13332: case 13333: case 15277: case 15290: case 28481: case 28927: case 29220: case 29221: case 29222: case 29743: case 29744: case 33224: case 33976: // apply discount for regular mount and set price price = uint32(floor(AccountTypes(sWorld.getConfig(CONFIG_UINT32_MOUNT_COST)) * discountMod)); break; case 8586: // all epic mounts case 12302: case 12303: case 12330: case 12351: case 12353: case 12354: case 13086: case 13317: case 13326: case 13327: case 13328: case 13329: case 13334: case 15292: case 15293: case 18766: case 18767: case 18772: case 18773: case 18774: case 18776: case 18777: case 18778: case 18785: case 18786: case 18787: case 18788: case 18789: case 18790: case 18791: case 18793: case 18794: case 18795: case 18796: case 18797: case 18798: case 18902: case 21176: case 21218: case 21321: case 21323: case 21324: case 28936: case 29102: case 29103: case 29104: case 29105: case 29223: case 29224: case 29227: case 29229: case 29230: case 29231: case 29745: case 29746: case 29747: case 33225: case 33977: case 35513: case 37719: case 37828: case 38576: // apply discount for epic mount and set price price = uint32(floor(AccountTypes(sWorld.getConfig(CONFIG_UINT32_EPIC_MOUNT_COST)) * discountMod)); break; default: // any other items price = uint32(floor(pProto->BuyPrice * discountMod)); break; } data << uint32(count); data << uint32(itemId); data << uint32(pProto->DisplayInfoID); data << uint32(crItem->maxcount <= 0 ? 0xFFFFFFFF : pCreature->GetVendorItemCurrentCount(crItem)); data << uint32(price); data << uint32(pProto->MaxDurability); data << uint32(pProto->BuyCount); data << uint32(crItem->ExtendedCost); } } } if (count == 0) { data << uint8(0); // "Vendor has no inventory" SendPacket(&data); return; } data.put<uint8>(count_pos, count); SendPacket(&data); }
bool WaypointMovementGenerator<Creature>::Update(Creature &unit, const uint32 &diff) { if (!&unit) return true; if (!path_id) return false; // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff if (unit.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED)) return true; // Clear the generator if the path doesn't exist if (!waypoints || !waypoints->size()) return false; Traveller<Creature> traveller(unit); i_nextMoveTime.Update(diff); i_destinationHolder.UpdateTraveller(traveller, diff, true); if (i_nextMoveTime.GetExpiry() < TIMEDIFF_NEXT_WP) { if (unit.IsStopped()) { if (StopedByPlayer) { ASSERT(node); InitTraveller(unit, *node); i_destinationHolder.SetDestination(traveller, node->x, node->y, node->z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); StopedByPlayer = false; return true; } if (i_currentNode == waypoints->size() - 1) // If that's our last waypoint { if (repeating) // If the movement is repeating i_currentNode = 0; // Start moving all over again else { unit.SetHomePosition(node->x, node->y, node->z, unit.GetOrientation()); unit.GetMotionMaster()->Initialize(); return false; // Clear the waypoint movement } } else ++i_currentNode; node = waypoints->at(i_currentNode); InitTraveller(unit, *node); i_destinationHolder.SetDestination(traveller, node->x, node->y, node->z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); //Call for creature group update if (unit.GetFormation() && unit.GetFormation()->getLeader() == &unit) unit.GetFormation()->LeaderMoveTo(node->x, node->y, node->z); } else { //Determine waittime if (node->delay) i_nextMoveTime.Reset(node->delay); //note: disable "start" for mtmap if (node->event_id && urand(0,99) < node->event_chance) unit.GetMap()->ScriptsStart(sWaypointScripts, node->event_id, &unit, NULL/*, false*/); i_destinationHolder.ResetTravelTime(); MovementInform(unit); unit.UpdateWaypointID(i_currentNode); unit.ClearUnitState(UNIT_STAT_ROAMING); unit.Relocate(node->x, node->y, node->z); } } else { if (unit.IsStopped() && !i_destinationHolder.HasArrived()) { if (!StopedByPlayer) { i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER); i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER); StopedByPlayer = true; } } } return true; }
void SetData(uint32 type, uint32 data) { switch(type) { case DATA_RAGEWINTERCHILLEVENT: Encounters[0] = data; break; case DATA_ANETHERONEVENT: Encounters[1] = data; break; case DATA_KAZROGALEVENT: Encounters[2] = data; break; case DATA_AZGALOREVENT: { Encounters[3] = data; if (data == DONE) { if (ArchiYell)break; ArchiYell = true; Creature* pCreature = instance->GetCreature(Azgalor); if (pCreature) { Creature* pUnit = pCreature->SummonCreature(21987,pCreature->GetPositionX(),pCreature->GetPositionY(),pCreature->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,10000); Map* pMap = pCreature->GetMap(); if (pMap->IsDungeon() && pUnit) { pUnit->SetVisibility(VISIBILITY_OFF); Map::PlayerList const &PlayerList = pMap->GetPlayers(); if (PlayerList.isEmpty()) return; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()) { WorldPacket data(SMSG_MESSAGECHAT, 200); pUnit->BuildMonsterChat(&data,CHAT_MSG_MONSTER_YELL,YELL_EFFORTS,0,YELL_EFFORTS_NAME,i->getSource()->GetGUID()); i->getSource()->GetSession()->SendPacket(&data); WorldPacket data2(SMSG_PLAY_SOUND, 4); data2 << 10986; i->getSource()->GetSession()->SendPacket(&data2); } } } } } } break; case DATA_ARCHIMONDEEVENT: Encounters[4] = data; break; case DATA_RESET_TRASH_COUNT: Trash = 0; break; case DATA_TRASH: if (data) Trash = data; else Trash--; UpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash); break; case DATA_ALLIANCE_RETREAT: allianceRetreat = data; OpenDoor(HordeGate,true); SaveToDB(); break; case DATA_HORDE_RETREAT: hordeRetreat = data; OpenDoor(ElfGate,true); SaveToDB(); break; case DATA_RAIDDAMAGE: RaidDamage += data; if (RaidDamage >= MINRAIDDAMAGE) RaidDamage = MINRAIDDAMAGE; break; case DATA_RESET_RAIDDAMAGE: RaidDamage = 0; break; } debug_log("BSCR: Instance Hyjal: Instance data updated for event %u (Data=%u)",type,data); if (data == DONE) SaveToDB(); }
void WorldSession::SendListInventory(ObjectGuid vendorguid) { DEBUG_LOG("WORLD: Sent SMSG_LIST_INVENTORY"); Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR); if (!pCreature) { DEBUG_LOG("WORLD: SendListInventory - %s not found or you can't interact with him.", vendorguid.GetString().c_str()); _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, nullptr, ObjectGuid(), 0); return; } // Stop the npc if moving pCreature->StopMoving(); VendorItemData const* vItems = pCreature->GetVendorItems(); VendorItemData const* tItems = pCreature->GetVendorTemplateItems(); if (!vItems && !tItems) { WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + 1)); data << ObjectGuid(vendorguid); data << uint8(0); // count==0, next will be error code data << uint8(0); // "Vendor has no inventory" SendPacket(&data); return; } uint8 customitems = vItems ? vItems->GetItemCount() : 0; uint8 numitems = customitems + (tItems ? tItems->GetItemCount() : 0); uint8 count = 0; WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + numitems * 7 * 4)); data << ObjectGuid(vendorguid); size_t count_pos = data.wpos(); data << uint8(count); float discountMod = _player->GetReputationPriceDiscount(pCreature); for (int i = 0; i < numitems; ++i) { VendorItem const* crItem = i < customitems ? vItems->GetItem(i) : tItems->GetItem(i - customitems); if (crItem) { uint32 itemId = crItem->item; ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemId); if (pProto) { if (!_player->isGameMaster()) { // class wrong item skip only for bindable case if ((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP) continue; // race wrong item skip always if ((pProto->AllowableRace & _player->getRaceMask()) == 0) continue; // when no faction required but rank > 0 will be used faction id from the vendor faction template to compare the rank if (!pProto->RequiredReputationFaction && pProto->RequiredReputationRank > 0 && ReputationRank(pProto->RequiredReputationRank) > _player->GetReputationRank(pCreature->getFactionTemplateEntry()->faction)) continue; if (crItem->conditionId && !sObjectMgr.IsPlayerMeetToCondition(crItem->conditionId, _player, pCreature->GetMap(), pCreature, CONDITION_FROM_VENDOR)) continue; } ++count; // reputation discount uint32 price = uint32(floor(pProto->BuyPrice * discountMod)); data << uint32(count); data << uint32(itemId); data << uint32(pProto->DisplayInfoID); data << uint32(crItem->maxcount <= 0 ? 0xFFFFFFFF : pCreature->GetVendorItemCurrentCount(crItem)); data << uint32(price); data << uint32(pProto->MaxDurability); data << uint32(pProto->BuyCount); } } } if (count == 0) { data << uint8(0); // "Vendor has no inventory" SendPacket(&data); return; } data.put<uint8>(count_pos, count); SendPacket(&data); }
void DoIntro() { Creature *pMadrigosa = (Creature*)me->GetUnit(pInstance->GetData64(DATA_MADRIGOSA)); if (!pMadrigosa) return; switch (IntroPhase) { case 0: DoScriptText(YELL_MADR_ICE_BARRIER, pMadrigosa); pMadrigosa->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); for (uint8 i = 0; i < 8; ++i) pMadrigosa->SetSpeed(UnitMoveType(i), 2.5); pMadrigosa->GetMotionMaster()->MovePoint(1, MADRI_FLY_X, MADRI_FLY_Y, MADRI_FLY_Z); IntroPhaseTimer = 6500; ++IntroPhase; break; case 1: pInstance->SetData(DATA_BRUTALLUS_INTRO_EVENT, IN_PROGRESS); pMadrigosa->SetLevitate(false); pMadrigosa->SetWalk(true); pMadrigosa->HandleEmoteCommand(EMOTE_ONESHOT_LAND); IntroPhaseTimer = 2500; ++IntroPhase; break; case 2: pMadrigosa->SendHeartBeat(); DoScriptText(YELL_MADR_INTRO, pMadrigosa); IntroPhaseTimer = 5000; ++IntroPhase; break; case 3: float x, y, z; pMadrigosa->GetMap()->CreatureRelocation((Creature*)pMadrigosa, MADRI_FLY_X, MADRI_FLY_Y, MADRI_FLY_Z, me->GetOrientation()); me->SetInFront(pMadrigosa); pMadrigosa->SetInFront(me); DoScriptText(YELL_INTRO, me); IntroPhaseTimer = 6000; ++IntroPhase; break; case 4: pMadrigosa->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoStartMovement(pMadrigosa); pMadrigosa->GetMotionMaster()->MoveChase(me); me->Attack(pMadrigosa, true); pMadrigosa->Attack(me, true); IntroPhaseTimer = 7000; ++IntroPhase; break; case 5: pMadrigosa->CastSpell(me, SPELL_INTRO_FROST_BREATH, false); me->CastSpell(me, SPELL_INTRO_FROST_BREATH, true); IntroPhaseTimer = 2500; ++IntroPhase; break; case 6: me->GetMotionMaster()->MoveIdle(); pMadrigosa->SetLevitate(true); pMadrigosa->GetPosition(x, y, z); pMadrigosa->GetMotionMaster()->MovePoint(2, x, y, z+15); pMadrigosa->setHover(true); IntroPhaseTimer = 4500; ++IntroPhase; case 7: pMadrigosa->SetInFront(me); pMadrigosa->CastSpell(me, SPELL_INTRO_FROST_BLAST, false); me->CastSpell(me, SPELL_INTRO_FROST_BLAST, true); DoScriptText(YELL_MADR_ICE_BLOCK, pMadrigosa); IntroFrostBoltTimer = 500; IntroPhaseTimer = 10000; ++IntroPhase; break; case 8: DoScriptText(YELL_INTRO_BREAK_ICE, me); IntroPhaseTimer = 2000; ++IntroPhase; break; case 9: me->GetMotionMaster()->MoveIdle(); me->AttackStop(); pMadrigosa->setHover(false); pMadrigosa->SetLevitate(false); pMadrigosa->SetWalk(true); pMadrigosa->HandleEmoteCommand(EMOTE_ONESHOT_LAND); pMadrigosa->SendHeartBeat(); IntroPhaseTimer = 1000; ++IntroPhase; break; case 10: pMadrigosa->GetMotionMaster()->MoveIdle(); IntroPhaseTimer = 2500; ++IntroPhase; break; case 11: pMadrigosa->GetMap()->CreatureRelocation((Creature*)pMadrigosa, MADRI_FLY_X, MADRI_FLY_Y, MADRI_FLY_Z, me->GetOrientation()); pMadrigosa->GetMotionMaster()->MoveIdle(); IntroPhaseTimer = 2000; ++IntroPhase; break; case 12: me->GetMotionMaster()->MoveIdle(); pMadrigosa->CastSpell(me, SPELL_INTRO_ENCAPSULATE, false); DoScriptText(YELL_MADR_TRAP, pMadrigosa); IntroPhaseTimer = 1000; ++IntroPhase; break; case 13: me->GetPosition(x, y, z); me->GetMotionMaster()->MovePoint(1, x-6, y-15, z+10); me->SetInFront(pMadrigosa); IntroPhaseTimer = 8000; ++IntroPhase; break; case 14: me->RemoveAurasDueToSpell(44883); pMadrigosa->InterruptNonMeleeSpells(false); pMadrigosa->GetMotionMaster()->MoveIdle(); DoScriptText(YELL_INTRO_CHARGE, me); me->SetInFront(pMadrigosa); me->GetPosition(x, y, z); me->GetMotionMaster()->MoveFall(); IntroPhaseTimer = 3500; ++IntroPhase; break; case 15: for(uint8 i = 0; i < 8; ++i) me->SetSpeed(UnitMoveType(i), 10.0); me->GetMotionMaster()->MoveCharge(MADRI_FLY_X-5, MADRI_FLY_Y-15, MADRI_FLY_Z); AddSpellToCast((Unit*)NULL, SPELL_INTRO_CHARGE); IntroPhaseTimer = 1000; ++IntroPhase; break; case 16: DoScriptText(YELL_MADR_DEATH, pMadrigosa); pMadrigosa->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); pMadrigosa->SetFlag(UNIT_DYNAMIC_FLAGS, (UNIT_DYNFLAG_DEAD | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED)); pMadrigosa->CombatStop(); pMadrigosa->DeleteThreatList(); pMadrigosa->setFaction(35); me->CombatStop(); me->RemoveFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_PET_IN_COMBAT | UNIT_FLAG_PVP_ATTACKABLE)); IntroPhaseTimer = 4000; ++IntroPhase; break; case 17: if(pInstance) me->SetFacingToObject(GameObject::GetGameObject(*me, pInstance->GetData64(DATA_BRUTALLUS_TRIGGER))); for(uint8 i = 0; i < 8; ++i) me->SetSpeed(UnitMoveType(i), 2.0); IntroPhaseTimer = 6000; ++IntroPhase; break; case 18: DoScriptText(YELL_INTRO_KILL_MADRIGOSA, me); IntroPhaseTimer = 8000; ++IntroPhase; break; case 19: DoScriptText(YELL_INTRO_TAUNT, me); AddSpellToCast(me, SPELL_INTRO_BREAK_ICE); if(pInstance) pInstance->SetData(DATA_BRUTALLUS_INTRO_EVENT, DONE); else return; if(Unit *pTrigger = me->GetUnit(pInstance->GetData64(DATA_BRUTALLUS_TRIGGER))) pTrigger->CastSpell((Unit*)NULL, SPELL_INTRO_BREAK_ICE_KNOCKBACK, false); IntroPhaseTimer = 2000; ++IntroPhase; break; case 20: EnterEvadeMode(); ++IntroPhase; break; } }
void SetData(uint32 type, uint32 data) { switch (type) { case DATA_RAGEWINTERCHILLEVENT: m_auiEncounter[0] = data; break; case DATA_ANETHERONEVENT: m_auiEncounter[1] = data; break; case DATA_KAZROGALEVENT: m_auiEncounter[2] = data; break; case DATA_AZGALOREVENT: { m_auiEncounter[3] = data; if (data == DONE) { if (ArchiYell) break; ArchiYell = true; Creature* creature = instance->GetCreature(Azgalor); if (creature) { Creature* unit = creature->SummonCreature(21987, creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000); Map* map = creature->GetMap(); if (map->IsDungeon() && unit) { unit->SetVisible(false); Map::PlayerList const &PlayerList = map->GetPlayers(); if (PlayerList.isEmpty()) return; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource()) { WorldPacket packet(SMSG_MESSAGECHAT, 200); unit->BuildMonsterChat(&packet, CHAT_MSG_MONSTER_YELL, YELL_EFFORTS, 0, YELL_EFFORTS_NAME, i->getSource()->GetGUID()); i->getSource()->GetSession()->SendPacket(&packet); WorldPacket data2(SMSG_PLAY_SOUND, 4); data2 << uint32(10986); data2 << uint64(unit->GetGUID()); i->getSource()->GetSession()->SendPacket(&data2); } } } } } } break; case DATA_ARCHIMONDEEVENT: m_auiEncounter[4] = data; break; case DATA_RESET_TRASH_COUNT: Trash = 0; break; case DATA_TRASH: if (data) Trash = data; else Trash--; DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash); break; case TYPE_RETREAT: if (data == SPECIAL) { if (!m_uiAncientGemGUID.empty()) { for (std::list<uint64>::const_iterator itr = m_uiAncientGemGUID.begin(); itr != m_uiAncientGemGUID.end(); ++itr) { //don't know how long it expected DoRespawnGameObject(*itr, DAY); } } } break; case DATA_ALLIANCE_RETREAT: allianceRetreat = data; HandleGameObject(HordeGate, true); SaveToDB(); break; case DATA_HORDE_RETREAT: hordeRetreat = data; HandleGameObject(ElfGate, true); SaveToDB(); break; case DATA_RAIDDAMAGE: RaidDamage += data; if (RaidDamage >= MINRAIDDAMAGE) RaidDamage = MINRAIDDAMAGE; break; case DATA_RESET_RAIDDAMAGE: RaidDamage = 0; break; } TC_LOG_DEBUG(LOG_FILTER_TSCR, "Instance Hyjal: Instance data updated for event %u (Data=%u)", type, data); if (data == DONE) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; saveStream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' ' << m_auiEncounter[3] << ' ' << m_auiEncounter[4] << ' ' << allianceRetreat << ' ' << hordeRetreat << ' ' << RaidDamage; str_data = saveStream.str(); SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; } }
void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle) const { DEBUG_LOG("WORLD: SendTrainerList"); Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TRAINER); if (!unit) { DEBUG_LOG("WORLD: SendTrainerList - %s not found or you can't interact with him.", guid.GetString().c_str()); return; } // trainer list loaded at check; if (!unit->IsTrainerOf(_player, true)) return; CreatureInfo const* ci = unit->GetCreatureInfo(); if (!ci) return; TrainerSpellData const* cSpells = unit->GetTrainerSpells(); TrainerSpellData const* tSpells = unit->GetTrainerTemplateSpells(); if (!cSpells && !tSpells) { DEBUG_LOG("WORLD: SendTrainerList - Training spells not found for %s", guid.GetString().c_str()); return; } uint32 maxcount = (cSpells ? cSpells->spellList.size() : 0) + (tSpells ? tSpells->spellList.size() : 0); uint32 trainer_type = cSpells && cSpells->trainerType ? cSpells->trainerType : (tSpells ? tSpells->trainerType : 0); WorldPacket data(SMSG_TRAINER_LIST, 8 + 4 + 4 + maxcount * 38 + strTitle.size() + 1); data << ObjectGuid(guid); data << uint32(trainer_type); size_t count_pos = data.wpos(); data << uint32(maxcount); // reputation discount float fDiscountMod = _player->GetReputationPriceDiscount(unit); bool can_learn_primary_prof = GetPlayer()->GetFreePrimaryProfessionPoints() > 0; uint32 count = 0; if (cSpells) { for (TrainerSpellMap::const_iterator itr = cSpells->spellList.begin(); itr != cSpells->spellList.end(); ++itr) { TrainerSpell const* tSpell = &itr->second; uint32 triggerSpell = sSpellTemplate.LookupEntry<SpellEntry>(tSpell->spell)->EffectTriggerSpell[0]; uint32 reqLevel = 0; if (!_player->IsSpellFitByClassAndRace(tSpell->spell, &reqLevel)) continue; if (tSpell->conditionId && !sObjectMgr.IsPlayerMeetToCondition(tSpell->conditionId, GetPlayer(), unit->GetMap(), unit, CONDITION_FROM_TRAINER)) continue; reqLevel = tSpell->isProvidedReqLevel ? tSpell->reqLevel : std::max(reqLevel, tSpell->reqLevel); TrainerSpellState state = _player->GetTrainerSpellState(tSpell, reqLevel); SendTrainerSpellHelper(data, tSpell, triggerSpell, state, fDiscountMod, can_learn_primary_prof, reqLevel); ++count; } } if (tSpells) { for (TrainerSpellMap::const_iterator itr = tSpells->spellList.begin(); itr != tSpells->spellList.end(); ++itr) { TrainerSpell const* tSpell = &itr->second; uint32 triggerSpell = sSpellTemplate.LookupEntry<SpellEntry>(tSpell->spell)->EffectTriggerSpell[0]; uint32 reqLevel = 0; if (!_player->IsSpellFitByClassAndRace(tSpell->spell, &reqLevel)) continue; if (tSpell->conditionId && !sObjectMgr.IsPlayerMeetToCondition(tSpell->conditionId, GetPlayer(), unit->GetMap(), unit, CONDITION_FROM_TRAINER)) continue; reqLevel = tSpell->isProvidedReqLevel ? tSpell->reqLevel : std::max(reqLevel, tSpell->reqLevel); TrainerSpellState state = _player->GetTrainerSpellState(tSpell, reqLevel); SendTrainerSpellHelper(data, tSpell, triggerSpell, state, fDiscountMod, can_learn_primary_prof, reqLevel); ++count; } } data << strTitle; data.put<uint32>(count_pos, count); SendPacket(data); }