GameObject* Transport::CreateGOPassenger(ObjectGuid::LowType guid, GameObjectData const* data) { Map* map = GetMap(); GameObject* go = new GameObject(); if (!go->LoadGameObjectFromDB(guid, map, false)) { delete go; return NULL; } ASSERT(data); float x = data->posX; float y = data->posY; float z = data->posZ; float o = data->orientation; go->SetTransport(this); go->m_movementInfo.transport.guid = GetGUID(); go->m_movementInfo.transport.pos.Relocate(x, y, z, o); CalculatePassengerPosition(x, y, z, &o); go->Relocate(x, y, z, o); go->RelocateStationaryPosition(x, y, z, o); if (!go->IsPositionValid()) { TC_LOG_ERROR("entities.transport", "GameObject (guidlow %d, entry %d) not created. Suggested coordinates aren't valid (X: %f Y: %f)", go->GetGUID().GetCounter(), go->GetEntry(), go->GetPositionX(), go->GetPositionY()); delete go; return NULL; } if (!map->AddToMap(go)) { delete go; return NULL; } _staticPassengers.insert(go); return go; }
void UpdateAI(const uint32 uiDiff) { if (!UpdateVictim()) return; //Common to PHASE_START && PHASE_END if (m_uiPhase == PHASE_START || m_uiPhase == PHASE_END) { //Specific to PHASE_START || PHASE_END if (m_uiPhase == PHASE_START) { if (me->GetHealth()*100 / me->GetMaxHealth() < 60) { m_uiPhase = PHASE_BREATH; if (m_pInstance) m_pInstance->SetData(DATA_ONYXIA_PHASE, m_uiPhase); SetCombatMovement(false); me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveIdle(); me->SetFlying(true); DoScriptText(SAY_PHASE_2_TRANS, me); if (m_pPointData) me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ); m_uiWhelpTimer = 1000; return; } } else { if (m_uiBellowingRoarTimer <= uiDiff) { DoCastVictim(SPELL_BELLOWING_ROAR); // Eruption GameObject* pFloor = NULL; Trinity::GameObjectInRangeCheck check(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 15); Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, pFloor, check); me->VisitNearbyGridObject(30, searcher); if (m_pInstance && pFloor) m_pInstance->SetData64(DATA_FLOOR_ERUPTION_GUID, pFloor->GetGUID()); m_uiBellowingRoarTimer = 30000; } else m_uiBellowingRoarTimer -= uiDiff; } if (m_uiFlameBreathTimer <= uiDiff) { DoCastVictim(SPELL_FLAME_BREATH); m_uiFlameBreathTimer = urand(10000, 20000); } else m_uiFlameBreathTimer -= uiDiff; if (m_uiTailSweepTimer <= uiDiff) { DoCastAOE(SPELL_TAIL_SWEEP); m_uiTailSweepTimer = urand(15000, 20000); } else m_uiTailSweepTimer -= uiDiff; if (m_uiCleaveTimer <= uiDiff) { DoCastVictim(SPELL_CLEAVE); m_uiCleaveTimer = urand(2000, 5000); } else m_uiCleaveTimer -= uiDiff; if (m_uiWingBuffetTimer <= uiDiff) { DoCastVictim(SPELL_WING_BUFFET); m_uiWingBuffetTimer = urand(15000, 30000); } else m_uiWingBuffetTimer -= uiDiff; DoMeleeAttackIfReady(); } else { if (me->GetHealth()*100 / me->GetMaxHealth() < 40) { m_uiPhase = PHASE_END; if (m_pInstance) m_pInstance->SetData(DATA_ONYXIA_PHASE, m_uiPhase); DoScriptText(SAY_PHASE_3_TRANS, me); SetCombatMovement(true); me->SetFlying(false); m_bIsMoving = false; me->GetMotionMaster()->MovePoint(9,me->GetHomePosition()); return; } if (m_uiDeepBreathTimer <= uiDiff) { if (!m_bIsMoving) { if (me->IsNonMeleeSpellCasted(false)) me->InterruptNonMeleeSpells(false); DoScriptText(EMOTE_BREATH, me); DoCast(me, m_pPointData->uiSpellId); m_uiDeepBreathTimer = 70000; } } else m_uiDeepBreathTimer -= uiDiff; if (m_uiMovementTimer <= uiDiff) { if (!m_bIsMoving) { SetNextRandomPoint(); m_pPointData = GetMoveData(); if (!m_pPointData) return; me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ); m_bIsMoving = true; m_uiMovementTimer = 25000; } } else m_uiMovementTimer -= uiDiff; if (m_uiFireballTimer <= uiDiff) { if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) { if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) DoCast(pTarget, SPELL_FIREBALL); m_uiFireballTimer = 8000; } } else m_uiFireballTimer -= uiDiff; if (m_uiLairGuardTimer <= uiDiff) { me->SummonCreature(NPC_LAIRGUARD, aSpawnLocations[2].GetPositionX(), aSpawnLocations[2].GetPositionY(), aSpawnLocations[2].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN); if (m_uiSummonLairGuardCount >= RAID_MODE(1,2)) { m_uiSummonLairGuardCount = 0; m_uiLairGuardTimer = 30000; } else m_uiLairGuardTimer = 2000; } else m_uiLairGuardTimer -= uiDiff; if (m_uiWhelpTimer <= uiDiff) { me->SummonCreature(NPC_WHELP, aSpawnLocations[0].GetPositionX(), aSpawnLocations[0].GetPositionY(), aSpawnLocations[0].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN); me->SummonCreature(NPC_WHELP, aSpawnLocations[1].GetPositionX(), aSpawnLocations[1].GetPositionY(), aSpawnLocations[1].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN); if (m_uiSummonWhelpCount >= RAID_MODE(20,40)) { m_uiSummonWhelpCount = 0; m_uiWhelpTimer = 90000; } else m_uiWhelpTimer = 500; } else m_uiWhelpTimer -= uiDiff; } }
void UpdateAI(uint32 Diff) { if (!UpdateVictim()) return; //Common to PHASE_START && PHASE_END if (Phase == PHASE_START || Phase == PHASE_END) { //Specific to PHASE_START || PHASE_END if (Phase == PHASE_START) { if (HealthBelowPct(60)) { SetCombatMovement(false); Phase = PHASE_BREATH; me->GetMotionMaster()->MovePoint(10, Phase2Location); return; } } else { if (BellowingRoarTimer <= Diff) { DoCastVictim(SPELL_BELLOWING_ROAR); // Eruption GameObject* Floor = NULL; Trinity::GameObjectInRangeCheck check(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 15); Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, Floor, check); me->VisitNearbyGridObject(30, searcher); if (instance && Floor) instance->SetData64(DATA_FLOOR_ERUPTION_GUID, Floor->GetGUID()); BellowingRoarTimer = 30000; } else BellowingRoarTimer -= Diff; } if (FlameBreathTimer <= Diff) { DoCastVictim(SPELL_FLAME_BREATH); FlameBreathTimer = urand(10000, 20000); } else FlameBreathTimer -= Diff; if (TailSweepTimer <= Diff) { DoCastAOE(SPELL_TAIL_SWEEP); TailSweepTimer = urand(15000, 20000); } else TailSweepTimer -= Diff; if (CleaveTimer <= Diff) { DoCastVictim(SPELL_CLEAVE); CleaveTimer = urand(2000, 5000); } else CleaveTimer -= Diff; if (WingBuffetTimer <= Diff) { DoCastVictim(SPELL_WING_BUFFET); WingBuffetTimer = urand(15000, 30000); } else WingBuffetTimer -= Diff; DoMeleeAttackIfReady(); } else { if (HealthBelowPct(40)) { Phase = PHASE_END; if (instance) instance->SetData(DATA_ONYXIA_PHASE, Phase); Talk(SAY_PHASE_3_TRANS); SetCombatMovement(true); me->SetCanFly(false); IsMoving = false; me->GetMotionMaster()->MovePoint(9, me->GetHomePosition()); return; } if (DeepBreathTimer <= Diff) { if (!IsMoving) { if (me->IsNonMeleeSpellCasted(false)) me->InterruptNonMeleeSpells(false); Talk(EMOTE_BREATH); DoCast(me, PointData->SpellId); DeepBreathTimer = 70000; } } else DeepBreathTimer -= Diff; if (MovementTimer <= Diff) { if (!IsMoving) { SetNextRandomPoint(); PointData = GetMoveData(); if (!PointData) return; me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ); IsMoving = true; MovementTimer = 25000; } } else MovementTimer -= Diff; if (FireballTimer <= Diff) { if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_FIREBALL); FireballTimer = 8000; } } else FireballTimer -= Diff; if (LairGuardTimer <= Diff) { me->SummonCreature(NPC_LAIRGUARD, SpawnLocations[2], TEMPSUMMON_CORPSE_DESPAWN); LairGuardTimer = 30000; } else LairGuardTimer -= Diff; if (WhelpTimer <= Diff) { me->SummonCreature(NPC_WHELP, SpawnLocations[0], TEMPSUMMON_CORPSE_DESPAWN); me->SummonCreature(NPC_WHELP, SpawnLocations[1], TEMPSUMMON_CORPSE_DESPAWN); if (SummonWhelpCount >= RAID_MODE(20, 40)) { SummonWhelpCount = 0; WhelpTimer = 90000; } else WhelpTimer = 500; } else WhelpTimer -= Diff; } }
void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket*/) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY"); uint32 count = 0; ByteBuffer byteData; WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 3 + count * (1 + 8 + 4)); size_t pos = data.bitwpos(); data.WriteBits(count, 21); // placeholder for (Player::ClientGUIDs::const_iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr) { uint32 questStatus = DIALOG_STATUS_NONE; uint32 defstatus = DIALOG_STATUS_NONE; if (IS_CRE_OR_VEH_OR_PET_GUID(*itr)) { // need also pet quests case support Creature* questgiver = ObjectAccessor::GetCreatureOrPetOrVehicle(*GetPlayer(), *itr); if (!questgiver || questgiver->IsHostileTo(_player)) continue; if (!questgiver->HasFlag(UNIT_FIELD_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER)) continue; questStatus = sScriptMgr->GetDialogStatus(_player, questgiver); if (questStatus > 6) questStatus = getDialogStatus(_player, questgiver, defstatus); ObjectGuid guid = questgiver->GetGUID(); data.WriteBit(guid[4]); data.WriteBit(guid[0]); data.WriteBit(guid[3]); data.WriteBit(guid[6]); data.WriteBit(guid[5]); data.WriteBit(guid[7]); data.WriteBit(guid[1]); data.WriteBit(guid[2]); byteData.WriteByteSeq(guid[6]); byteData.WriteByteSeq(guid[2]); byteData.WriteByteSeq(guid[7]); byteData.WriteByteSeq(guid[5]); byteData.WriteByteSeq(guid[4]); byteData << uint32(questStatus); byteData.WriteByteSeq(guid[1]); byteData.WriteByteSeq(guid[3]); byteData.WriteByteSeq(guid[0]); ++count; } else if (IS_GAMEOBJECT_GUID(*itr)) { GameObject* questgiver = GetPlayer()->GetMap()->GetGameObject(*itr); if (!questgiver) continue; if (questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER) continue; questStatus = sScriptMgr->GetDialogStatus(_player, questgiver); if (questStatus > 6) questStatus = getDialogStatus(_player, questgiver, defstatus); ObjectGuid guid = questgiver->GetGUID(); data.WriteBit(guid[4]); data.WriteBit(guid[0]); data.WriteBit(guid[3]); data.WriteBit(guid[6]); data.WriteBit(guid[5]); data.WriteBit(guid[7]); data.WriteBit(guid[1]); data.WriteBit(guid[2]); byteData.WriteByteSeq(guid[6]); byteData.WriteByteSeq(guid[2]); byteData.WriteByteSeq(guid[7]); byteData.WriteByteSeq(guid[5]); byteData.WriteByteSeq(guid[4]); byteData << uint32(questStatus); byteData.WriteByteSeq(guid[1]); byteData.WriteByteSeq(guid[3]); byteData.WriteByteSeq(guid[0]); ++count; } } data.FlushBits(); data.PutBits(pos, count, 21); data.append(byteData); SendPacket(&data); }
bool ChatHandler::HandleGOSelect(const char* args, WorldSession* m_session) { GameObject* GObj = NULL; GameObject* GObjs = m_session->GetPlayer()->GetSelectedGo(); std::set<Object*>::iterator Itr = m_session->GetPlayer()->GetInRangeSetBegin(); std::set<Object*>::iterator Itr2 = m_session->GetPlayer()->GetInRangeSetEnd(); float cDist = 9999.0f; float nDist = 0.0f; bool bUseNext = false; if(args) { if(args[0] == '1') { if(GObjs == NULL) bUseNext = true; for(;; Itr++) { if(Itr == Itr2 && GObj == NULL && bUseNext) Itr = m_session->GetPlayer()->GetInRangeSetBegin(); else if(Itr == Itr2) break; if((*Itr)->IsGameObject()) { // Find the current go, move to the next one if(bUseNext) { // Select the first. GObj = TO< GameObject* >(*Itr); break; } else { if(((*Itr) == GObjs)) { // Found him. Move to the next one, or beginning if we're at the end bUseNext = true; } } } } } } if(!GObj) { for(; Itr != Itr2; Itr++) { if((*Itr)->IsGameObject()) { if((nDist = m_session->GetPlayer()->CalcDistance(*Itr)) < cDist) { cDist = nDist; nDist = 0.0f; GObj = TO_GAMEOBJECT(*Itr); } } } } if(GObj == NULL) { RedSystemMessage(m_session, "No inrange GameObject found."); return true; } m_session->GetPlayer()->m_GM_SelectedGO = GObj->GetGUID(); GreenSystemMessage(m_session, "Selected GameObject [ %s ] which is %.3f meters away from you.", GameObjectNameStorage.LookupEntry(GObj->GetEntry())->Name, m_session->GetPlayer()->CalcDistance(GObj)); return true; }
void GameObject::Use(Unit* user) { // by default spell caster is user Unit* spellCaster = user; uint32 spellId = 0; switch(GetGoType()) { case GAMEOBJECT_TYPE_DOOR: //0 case GAMEOBJECT_TYPE_BUTTON: //1 //doors/buttons never really despawn, only reset to default state/flags UseDoorOrButton(); // activate script sWorld.ScriptsStart(sGameObjectScripts, GetDBTableGUIDLow(), spellCaster, this); return; case GAMEOBJECT_TYPE_QUESTGIVER: //2 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; player->PrepareQuestMenu( GetGUID() ); player->SendPreparedQuest( GetGUID() ); return; } //Sitting: Wooden bench, chairs enzz case GAMEOBJECT_TYPE_CHAIR: //7 { GameObjectInfo const* info = GetGOInfo(); if(!info) return; if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; // a chair may have n slots. we have to calculate their positions and teleport the player to the nearest one // check if the db is sane if(info->chair.slots > 0) { float lowestDist = DEFAULT_VISIBILITY_DISTANCE; float x_lowest = GetPositionX(); float y_lowest = GetPositionY(); // the object orientation + 1/2 pi // every slot will be on that straight line float orthogonalOrientation = GetOrientation()+M_PI*0.5f; // find nearest slot for(uint32 i=0; i<info->chair.slots; i++) { // the distance between this slot and the center of the go - imagine a 1D space float relativeDistance = (info->size*i)-(info->size*(info->chair.slots-1)/2.0f); float x_i = GetPositionX() + relativeDistance * cos(orthogonalOrientation); float y_i = GetPositionY() + relativeDistance * sin(orthogonalOrientation); // calculate the distance between the player and this slot float thisDistance = player->GetDistance2d(x_i, y_i); /* debug code. It will spawn a npc on each slot to visualize them. Creature* helper = player->SummonCreature(14496, x_i, y_i, GetPositionZ(), GetOrientation(), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10000); std::ostringstream output; output << i << ": thisDist: " << thisDistance; helper->MonsterSay(output.str().c_str(), LANG_UNIVERSAL, 0); */ if(thisDistance <= lowestDist) { lowestDist = thisDistance; x_lowest = x_i; y_lowest = y_i; } } player->TeleportTo(GetMapId(), x_lowest, y_lowest, GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET); } else { // fallback, will always work player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET); } player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR+info->chair.height); return; } //big gun, its a spell/aura case GAMEOBJECT_TYPE_GOOBER: //10 { GameObjectInfo const* info = GetGOInfo(); if(user->GetTypeId()==TYPEID_PLAYER) { Player* player = (Player*)user; // show page if(info->goober.pageId) { WorldPacket data(SMSG_GAMEOBJECT_PAGETEXT, 8); data << GetGUID(); player->GetSession()->SendPacket(&data); } // possible quest objective for active quests player->CastedCreatureOrGO(info->id, GetGUID(), 0); } // cast this spell later if provided spellId = info->goober.spellId; break; } case GAMEOBJECT_TYPE_CAMERA: //13 { GameObjectInfo const* info = GetGOInfo(); if(!info) return; if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; if(info->camera.cinematicId) { WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4); data << info->camera.cinematicId; player->GetSession()->SendPacket(&data); } return; } //fishing bobber case GAMEOBJECT_TYPE_FISHINGNODE: //17 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; if(player->GetGUID() != GetOwnerGUID()) return; switch(getLootState()) { case GO_READY: // ready for loot { // 1) skill must be >= base_zone_skill // 2) if skill == base_zone_skill => 5% chance // 3) chance is linear dependence from (base_zone_skill-skill) uint32 subzone = GetAreaId(); int32 zone_skill = objmgr.GetFishingBaseSkillLevel( subzone ); if(!zone_skill) zone_skill = objmgr.GetFishingBaseSkillLevel( GetZoneId() ); //provide error, no fishable zone or area should be 0 if(!zone_skill) sLog.outErrorDb("Fishable areaId %u are not properly defined in `skill_fishing_base_level`.",subzone); int32 skill = player->GetSkillValue(SKILL_FISHING); int32 chance = skill - zone_skill + 5; int32 roll = irand(1,100); DEBUG_LOG("Fishing check (skill: %i zone min skill: %i chance %i roll: %i",skill,zone_skill,chance,roll); if(skill >= zone_skill && chance >= roll) { // prevent removing GO at spell cancel player->RemoveGameObject(this,false); SetOwnerGUID(player->GetGUID()); //fish catched player->UpdateFishingSkill(); GameObject* ok = LookupFishingHoleAround(DEFAULT_VISIBILITY_DISTANCE); if (ok) { player->SendLoot(ok->GetGUID(),LOOT_FISHINGHOLE); SetLootState(GO_JUST_DEACTIVATED); } else player->SendLoot(GetGUID(),LOOT_FISHING); } else { // fish escaped, can be deleted now SetLootState(GO_JUST_DEACTIVATED); WorldPacket data(SMSG_FISH_ESCAPED, 0); player->GetSession()->SendPacket(&data); } break; } case GO_JUST_DEACTIVATED: // nothing to do, will be deleted at next update break; default: { SetLootState(GO_JUST_DEACTIVATED); WorldPacket data(SMSG_FISH_NOT_HOOKED, 0); player->GetSession()->SendPacket(&data); break; } } if(player->m_currentSpells[CURRENT_CHANNELED_SPELL]) { player->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); player->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(); } return; } case GAMEOBJECT_TYPE_SUMMONING_RITUAL: //18 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; Unit* caster = GetOwner(); GameObjectInfo const* info = GetGOInfo(); if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) return; // accept only use by player from same group for caster except caster itself if(((Player*)caster)==player || !((Player*)caster)->IsInSameRaidWith(player)) return; AddUniqueUse(player); // full amount unique participants including original summoner if(GetUniqueUseCount() < info->summoningRitual.reqParticipants) return; // in case summoning ritual caster is GO creator spellCaster = caster; if(!caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) return; spellId = info->summoningRitual.spellId; // finish spell caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(); // can be deleted now SetLootState(GO_JUST_DEACTIVATED); // go to end function to spell casting break; } case GAMEOBJECT_TYPE_SPELLCASTER: //22 { SetUInt32Value(GAMEOBJECT_FLAGS,2); GameObjectInfo const* info = GetGOInfo(); if(!info) return; if(info->spellcaster.partyOnly) { Unit* caster = GetOwner(); if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) return; if(user->GetTypeId()!=TYPEID_PLAYER || !((Player*)user)->IsInSameRaidWith((Player*)caster)) return; } spellId = info->spellcaster.spellId; AddUse(); break; } case GAMEOBJECT_TYPE_MEETINGSTONE: //23 { GameObjectInfo const* info = GetGOInfo(); if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; Player* targetPlayer = ObjectAccessor::FindPlayer(player->GetSelection()); // accept only use by player from same group for caster except caster itself if(!targetPlayer || targetPlayer == player || !targetPlayer->IsInSameGroupWith(player)) return; //required lvl checks! uint8 level = player->getLevel(); if (level < info->meetingstone.minLevel || level > info->meetingstone.maxLevel) return; level = targetPlayer->getLevel(); if (level < info->meetingstone.minLevel || level > info->meetingstone.maxLevel) return; spellId = 23598; break; } case GAMEOBJECT_TYPE_FLAGSTAND: // 24 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; if( player->isAllowUseBattleGroundObject() ) { // in battleground check BattleGround *bg = player->GetBattleGround(); if(!bg) return; // BG flag click // AB: // 15001 // 15002 // 15003 // 15004 // 15005 bg->EventPlayerClickedOnFlag(player, this); return; //we don;t need to delete flag ... it is despawned! } break; } case GAMEOBJECT_TYPE_FLAGDROP: // 26 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; if( player->isAllowUseBattleGroundObject() ) { // in battleground check BattleGround *bg = player->GetBattleGround(); if(!bg) return; // BG flag dropped // WS: // 179785 - Silverwing Flag // 179786 - Warsong Flag // EotS: // 184142 - Netherstorm Flag GameObjectInfo const* info = GetGOInfo(); if(info) { switch(info->id) { case 179785: // Silverwing Flag // check if it's correct bg if(bg->GetTypeID() == BATTLEGROUND_WS) bg->EventPlayerClickedOnFlag(player, this); break; case 179786: // Warsong Flag if(bg->GetTypeID() == BATTLEGROUND_WS) bg->EventPlayerClickedOnFlag(player, this); break; case 184142: // Netherstorm Flag if(bg->GetTypeID() == BATTLEGROUND_EY) bg->EventPlayerClickedOnFlag(player, this); break; } } //this cause to call return, all flags must be deleted here!! spellId = 0; Delete(); } break; } case GAMEOBJECT_TYPE_BARBER_CHAIR: //32 { GameObjectInfo const* info = GetGOInfo(); if(!info) return; if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; // fallback, will always work player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET); WorldPacket data(SMSG_ENABLE_BARBER_SHOP, 0); player->GetSession()->SendPacket(&data); player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR+info->barberChair.chairheight); return; } default: sLog.outDebug("Unknown Object Type %u", GetGoType()); break; } if(!spellId) return; SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellId ); if(!spellInfo) { sLog.outError("WORLD: unknown spell id %u at use action for gameobject (Entry: %u GoType: %u )", spellId,GetEntry(),GetGoType()); return; } Spell *spell = new Spell(spellCaster, spellInfo, false); // spell target is user of GO SpellCastTargets targets; targets.setUnitTarget( user ); spell->prepare(&targets); }
//move selected object static bool HandleGameObjectMoveCommand(ChatHandler* handler, char const* args) { // number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r char* id = handler->extractKeyFromLink((char*)args, "Hgameobject"); if (!id) return false; ObjectGuid::LowType guidLow = strtoull(id, nullptr, 10); if (!guidLow) return false; GameObject* object = NULL; // by DB guid if (GameObjectData const* gameObjectData = sObjectMgr->GetGOData(guidLow)) object = handler->GetObjectGlobalyWithGuidOrNearWithDbGuid(guidLow, gameObjectData->id); if (!object) { handler->PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, guidLow); handler->SetSentErrorMessage(true); return false; } char* toX = strtok(NULL, " "); char* toY = strtok(NULL, " "); char* toZ = strtok(NULL, " "); float x, y, z; if (!toX) { Player* player = handler->GetSession()->GetPlayer(); player->GetPosition(x, y, z); } else { if (!toY || !toZ) return false; x = (float)atof(toX); y = (float)atof(toY); z = (float)atof(toZ); if (!MapManager::IsValidMapCoord(object->GetMapId(), x, y, z)) { handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, object->GetMapId()); handler->SetSentErrorMessage(true); return false; } } object->DestroyForNearbyPlayers(); object->RelocateStationaryPosition(x, y, z, object->GetOrientation()); object->GetMap()->GameObjectRelocation(object, x, y, z, object->GetOrientation()); object->SaveToDB(); handler->PSendSysMessage(LANG_COMMAND_MOVEOBJMESSAGE, object->GetSpawnId(), object->GetGOInfo()->name.c_str(), object->GetGUID().ToString().c_str()); return true; }
//turn selected object static bool HandleGameObjectTurnCommand(ChatHandler* handler, char const* args) { // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r char* id = handler->extractKeyFromLink((char*)args, "Hgameobject"); if (!id) return false; ObjectGuid::LowType guidLow = strtoull(id, nullptr, 10); if (!guidLow) return false; GameObject* object = NULL; // by DB guid if (GameObjectData const* gameObjectData = sObjectMgr->GetGOData(guidLow)) object = handler->GetObjectGlobalyWithGuidOrNearWithDbGuid(guidLow, gameObjectData->id); if (!object) { handler->PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, guidLow); handler->SetSentErrorMessage(true); return false; } char* orientation = strtok(NULL, " "); float o; if (orientation) o = (float)atof(orientation); else { Player* player = handler->GetSession()->GetPlayer(); o = player->GetOrientation(); } object->Relocate(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), o); object->RelocateStationaryPosition(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), o); object->UpdateRotationFields(); object->DestroyForNearbyPlayers(); object->UpdateObjectVisibility(); object->SaveToDB(); handler->PSendSysMessage(LANG_COMMAND_TURNOBJMESSAGE, object->GetSpawnId(), object->GetGOInfo()->name.c_str(), object->GetGUID().ToString().c_str(), o); return true; }
void GameObject::UseFishingNode(Player *player) { sEventMgr.RemoveEvents( this ); if( GetUInt32Value( GAMEOBJECT_FLAGS ) != 32 ) // Clicking on the bobber before something is hooked { player->GetSession()->OutPacket( SMSG_FISH_NOT_HOOKED ); EndFishing( player, true ); return; } /* Unused code: sAreaStore.LookupEntry(GetMapMgr()->GetAreaID(GetPositionX(),GetPositionY()))->ZoneId*/ uint32 zone = player->GetAreaID(); if( zone == 0 ) // If the player's area ID is 0, use the zone ID instead zone = player->GetZoneId(); FishingZoneEntry *entry = FishingZoneStorage.LookupEntry( zone ); if( entry == NULL ) // No fishing information found for area or zone, log an error, and end fishing { sLog.outError( "ERROR: Fishing zone information for zone %d not found!", zone ); EndFishing( player, true ); return; } uint32 maxskill = entry->MaxSkill; uint32 minskill = entry->MinSkill; if( player->_GetSkillLineCurrent( SKILL_FISHING, false ) < maxskill ) player->_AdvanceSkillLine( SKILL_FISHING, float2int32( 1.0f * sWorld.getRate( RATE_SKILLRATE ) ) ); GameObject * school = NULL; this->AquireInrangeLock(); //make sure to release lock before exit function ! for ( InRangeSet::iterator it = GetInRangeSetBegin(); it != GetInRangeSetEnd(); ++it ) { if ( (*it) == NULL || (*it)->GetTypeId() != TYPEID_GAMEOBJECT || (*it)->GetUInt32Value(GAMEOBJECT_TYPE_ID) != GAMEOBJECT_TYPE_FISHINGHOLE) continue; school = static_cast<GameObject *>( *it ); if ( !isInRange( school, (float)school->GetInfo()->sound1 ) ) { school = NULL; continue; } else break; } this->ReleaseInrangeLock(); if ( school != NULL ) // open school loot if school exists { lootmgr.FillGOLoot( &school->loot, school->GetEntry(), school->GetMapMgr() ? ( school->GetMapMgr()->iInstanceMode ? true : false ) : false ); player->SendLoot( school->GetGUID(), LOOT_FISHING ); EndFishing( player, false ); school->CatchFish(); if ( !school->CanFish() ) sEventMgr.AddEvent( school, &GameObject::Despawn, ( 1800000 + RandomUInt( 3600000 ) ), EVENT_GAMEOBJECT_EXPIRE, 10000, 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT ); // respawn in 30 - 90 minutes } else if( Rand( ( ( player->_GetSkillLineCurrent( SKILL_FISHING, true ) - minskill ) * 100 ) / maxskill ) ) // Open loot on success, otherwise FISH_ESCAPED. { lootmgr.FillFishingLoot( &loot, zone ); player->SendLoot( GetGUID(), LOOT_FISHING ); EndFishing( player, false ); } else // Failed { player->GetSession()->OutPacket( SMSG_FISH_ESCAPED ); EndFishing( player, true ); } }