void WorldSession::HandleGameObjectUseOpcode(WorldPacket& recv_data) { uint64 guid; recv_data >> guid; DEBUG_LOG("WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", GUID_LOPART(guid)); GameObject* obj = GetPlayer()->GetMap()->GetGameObject(guid); if (!obj) return; FactionTemplateEntry const* faction = sFactionTemplateStore.LookupEntry(obj->GetGOInfo()->faction); if (faction && !_player->isGameMaster() && faction->IsHostileTo(*sFactionTemplateStore.LookupEntry(_player->getFaction())) && !faction->IsNeutralToAll() && !obj->GetOwner()) return; obj->Use(_player); }
/// Begin asynchronous loading of a shader variant. /// /// @param[in] pShader Parent shader resource. /// @param[in] shaderType Shader type. /// @param[in] userOptionIndex Index associated with the user option combination for the shader variant. /// /// @return ID associated with the load procedure, or an invalid index if the load could not be started. /// /// @see TryFinishLoadVariant() size_t ShaderVariantResourceHandler::BeginLoadVariant( Shader* pShader, RShader::EType shaderType, uint32_t userOptionIndex ) { HELIUM_ASSERT( pShader ); HELIUM_ASSERT( static_cast< size_t >( shaderType ) < static_cast< size_t >( RShader::TYPE_MAX ) ); // Attempt to locate an existing load request for the specified shader variant. LoadRequest* pLoadRequest = m_loadRequestPool.Allocate(); HELIUM_ASSERT( pLoadRequest ); pLoadRequest->shaderType = shaderType; pLoadRequest->userOptionIndex = userOptionIndex; HELIUM_ASSERT( !pLoadRequest->spVariant ); pLoadRequest->requestCount = 1; LoadRequestSetType::ConstAccessor loadRequestConstAccessor; if( !m_loadRequestSet.Insert( loadRequestConstAccessor, pLoadRequest ) ) { // Request exists, so increment its reference count. m_loadRequestPool.Release( pLoadRequest ); pLoadRequest = *loadRequestConstAccessor; HELIUM_ASSERT( pLoadRequest ); AtomicIncrementAcquire( pLoadRequest->requestCount ); size_t loadId = m_loadRequestPool.GetIndex( pLoadRequest ); HELIUM_ASSERT( IsValid( loadId ) ); return loadId; } // Adding a new request, so create the variant object if it does not yet exist. tchar_t shaderTypeCharacter; if( shaderType == RShader::TYPE_VERTEX ) { shaderTypeCharacter = TXT( 'v' ); } else { HELIUM_ASSERT( shaderType == RShader::TYPE_PIXEL ); shaderTypeCharacter = TXT( 'p' ); } String variantNameString; variantNameString.Format( TXT( "%c%" ) TPRIu32, shaderTypeCharacter, userOptionIndex ); Name variantName( variantNameString ); variantNameString.Clear(); pLoadRequest->spVariant.Set( Reflect::AssertCast< ShaderVariant >( pShader->FindChild( variantName ) ) ); if( !pLoadRequest->spVariant ) { if( !GameObject::Create< ShaderVariant >( pLoadRequest->spVariant, variantName, pShader ) ) { HELIUM_TRACE( TRACE_ERROR, ( TXT( "ShaderVariantResourceHandler::BeginLoadVariant(): Failed to create shader variant object " ) TXT( "\"%s:%s\".\n" ) ), *pShader->GetPath().ToString(), *variantName ); } else { HELIUM_ASSERT( pLoadRequest->spVariant ); } } // If we have an object for the shader variant, attempt to load its resource data. ShaderVariant* pVariant = pLoadRequest->spVariant; if( pVariant && !pVariant->GetAnyFlagSet( GameObject::FLAG_PRECACHED ) ) { GameObject* pPackageObject; for( pPackageObject = pShader->GetOwner(); pPackageObject != NULL && !pPackageObject->IsPackage(); pPackageObject = pPackageObject->GetOwner() ) { // This space intentionally left blank... } HELIUM_ASSERT( pPackageObject ); PackageLoader* pPackageLoader = Reflect::AssertCast< Package >( pPackageObject )->GetLoader(); HELIUM_ASSERT( pPackageLoader ); HELIUM_ASSERT( pPackageLoader->IsSourcePackageFile() ); ObjectPreprocessor* pObjectPreprocessor = ObjectPreprocessor::GetStaticInstance(); HELIUM_ASSERT( pObjectPreprocessor ); pObjectPreprocessor->LoadResourceData( pVariant, pPackageLoader->GetFileTimestamp() ); // Resource data loaded, so deserialize the persistent data for the current platform and begin precaching. CacheManager& rCacheManager = CacheManager::GetStaticInstance(); const Resource::PreprocessedData& rPreprocessedData = pVariant->GetPreprocessedData( rCacheManager.GetCurrentPlatform() ); const DynArray< uint8_t >& rPersistentDataBuffer = rPreprocessedData.persistentDataBuffer; //PMDTODO: Implmenet this // BinaryDeserializer deserializer; // deserializer.Prepare( rPersistentDataBuffer.GetData(), rPersistentDataBuffer.GetSize() ); // deserializer.BeginSerialize(); // pVariant->SerializePersistentResourceData( deserializer ); // deserializer.EndSerialize(); Reflect::ObjectPtr persistent_resource_data = Cache::ReadCacheObjectFromBuffer(rPersistentDataBuffer); pVariant->LoadPersistentResourceObject(persistent_resource_data); pVariant->BeginPrecacheResourceData(); } size_t loadId = m_loadRequestPool.GetIndex( pLoadRequest ); HELIUM_ASSERT( IsValid( loadId ) ); return loadId; }
void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,8); uint64 guid; uint32 spellId = OPEN_CHEST; const GameObjectInfo *info; recv_data >> guid; sLog.outDebug( "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", guid); GameObject *obj = ObjectAccessor::GetGameObject(*_player, guid); if(!obj) return; //obj->SetUInt32Value(GAMEOBJECT_FLAGS,2); //obj->SetUInt32Value(GAMEOBJECT_FLAGS,2); // default spell caster is player that use GO Unit* spellCaster = GetPlayer(); // default spell target is player that use GO Unit* spellTarget = GetPlayer(); if (Script->GOHello(_player, obj)) return; switch(obj->GetGoType()) { case GAMEOBJECT_TYPE_DOOR: //0 obj->SetUInt32Value(GAMEOBJECT_FLAGS,33); obj->SetUInt32Value(GAMEOBJECT_STATE,0); //open //obj->SetUInt32Value(GAMEOBJECT_TIMESTAMP,0x465EE6D2); //load timestamp obj->SetLootState(GO_CLOSED); obj->SetRespawnTime(5); //close door in 5 seconds return; case GAMEOBJECT_TYPE_BUTTON: //1 obj->SetUInt32Value(GAMEOBJECT_FLAGS,33); obj->SetUInt32Value(GAMEOBJECT_STATE,0); //open obj->SetLootState(GO_CLOSED); obj->SetRespawnTime(2); //close in 1 seconds // activate script sWorld.ScriptsStart(sButtonScripts, obj->GetDBTableGUIDLow(), spellCaster, obj); return; case GAMEOBJECT_TYPE_QUESTGIVER: //2 _player->PrepareQuestMenu( guid ); _player->SendPreparedQuest( guid ); return; //Sitting: Wooden bench, chairs enzz case GAMEOBJECT_TYPE_CHAIR: //7 info = obj->GetGOInfo(); if(info) { //spellId = info->data0; // this is not a spell or offset _player->TeleportTo(obj->GetMapId(), obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(),false,false); _player->SetFlag(UNIT_FIELD_BYTES_1,PLAYER_STATE_SIT_LOW_CHAIR); // Using (3 + spellId) was wrong, this is a number of slot for chair/bench, not offset _player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR); return; } break; //big gun, its a spell/aura case GAMEOBJECT_TYPE_GOOBER: //10 info = obj->GetGOInfo(); spellId = info ? info->data10 : 0; break; case GAMEOBJECT_TYPE_SPELLCASTER: //22 obj->SetUInt32Value(GAMEOBJECT_FLAGS,2); info = obj->GetGOInfo(); if(info) { spellId = info->data0; if (spellId == 0) spellId = info->data3; //guid=_player->GetGUID(); } break; case GAMEOBJECT_TYPE_CAMERA: //13 info = obj->GetGOInfo(); if(info) { uint32 cinematic_id = info->data1; if(cinematic_id) { WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4); data << cinematic_id; _player->GetSession()->SendPacket(&data); } return; } break; //fishing bobber case GAMEOBJECT_TYPE_FISHINGNODE: //17 { if(_player->GetGUID() != obj->GetOwnerGUID()) return; switch(obj->getLootState()) { case GO_CLOSED: // 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) int32 skill = _player->GetSkillValue(SKILL_FISHING); int32 zone_skill = _player->FishingMinSkillForCurrentZone(); 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(obj,false); obj->SetOwnerGUID(_player->GetGUID()); //fish catched _player->UpdateFishingSkill(); _player->SendLoot(obj->GetGUID(),LOOT_FISHING); } else { // fish escaped obj->SetLootState(GO_LOOTED); // can be deleted now WorldPacket data(SMSG_FISH_ESCAPED, 0); SendPacket(&data); } break; } case GO_LOOTED: // nothing to do, will be deleted at next update break; default: { obj->SetLootState(GO_LOOTED); WorldPacket data(SMSG_FISH_NOT_HOOKED, 0); 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: { Unit* caster = obj->GetOwner(); info = obj->GetGOInfo(); if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) return; // accept only use by player from same group for caster except caster itself if(((Player*)caster)==GetPlayer() || !((Player*)caster)->IsInSameGroupWith(GetPlayer())) return; obj->AddUse(GetPlayer()); // must 2 group members use GO, or only 1 when it is meeting stone summon if(obj->GetUniqueUseCount() < (info->data0 == 2 ? 1 : 2)) return; // in case summoning ritual caster is GO creator spellCaster = caster; if(!caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) return; spellId = info->data1; // finish spell caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(); // can be deleted now obj->SetLootState(GO_LOOTED); // go to end function to spell casting break; } case GAMEOBJECT_TYPE_MEETINGSTONE: //23 { info = obj->GetGOInfo(); Player* targetPlayer = ObjectAccessor::FindPlayer(((Player*)spellCaster)->GetSelection()); // accept only use by player from same group for caster except caster itself if(!targetPlayer || targetPlayer == GetPlayer() || !targetPlayer->IsInSameGroupWith(GetPlayer())) return; //required lvl checks! uint8 level = _player->getLevel(); if (level < info->data0 || level > info->data1) return; level = targetPlayer->getLevel(); if (level < info->data0 || level > info->data1) return; spellId = 23598; break; } case GAMEOBJECT_TYPE_FLAGSTAND: // 24 if(_player->InBattleGround() && // in battleground !_player->IsMounted() && // not mounted !_player->HasStealthAura() && // not stealthed !_player->HasInvisibilityAura() && // not invisible _player->isAlive()) // live player { BattleGround *bg = _player->GetBattleGround(); if(!bg) return; // BG flag click // AB: // 15001 // 15002 // 15003 // 15004 // 15005 // WS: // 179830 - Silverwing Flag // 179831 - Warsong Flag // EotS: // 184141 - Netherstorm Flag info = obj->GetGOInfo(); if(info) { switch(info->id) { case 179830: // check if it's correct bg if(bg->GetTypeID() != BATTLEGROUND_WS) return; // check if flag dropped if(((BattleGroundWS*)bg)->GetFlagState(ALLIANCE) != BG_WS_FLAG_STATE_ON_BASE) return; // check if it's correct flag if(((BattleGroundWS*)bg)->m_bgobjects[BG_WS_OBJECT_A_FLAG] != obj->GetGUID()) return; // check player team if(_player->GetTeam() == ALLIANCE) return; spellId = 23335; // Silverwing Flag break; case 179831: // check if it's correct bg if(bg->GetTypeID() != BATTLEGROUND_WS) return; // check if flag dropped if(((BattleGroundWS*)bg)->GetFlagState(HORDE) != BG_WS_FLAG_STATE_ON_BASE) return; // check if it's correct flag if(((BattleGroundWS*)bg)->m_bgobjects[BG_WS_OBJECT_H_FLAG] != obj->GetGUID()) return; // check player team if(_player->GetTeam() == HORDE) return; spellId = 23333; // Warsong Flag break; case 184141: // check if it's correct bg if(bg->GetTypeID() != BATTLEGROUND_EY) return; spellId = 34976; // Netherstorm Flag break; } } } break; case GAMEOBJECT_TYPE_FLAGDROP: // 26 if(_player->InBattleGround() && // in battleground !_player->IsMounted() && // not mounted !_player->HasStealthAura() && // not stealthed !_player->HasInvisibilityAura() && // not invisible _player->isAlive()) // live player { BattleGround *bg = _player->GetBattleGround(); if(!bg) return; // BG flag dropped // WS: // 179785 - Silverwing Flag // 179786 - Warsong Flag // EotS: // 184142 - Netherstorm Flag info = obj->GetGOInfo(); if(info) { switch(info->id) { case 179785: // Silverwing Flag // check if it's correct bg if(bg->GetTypeID() != BATTLEGROUND_WS) return; // check if flag dropped if(((BattleGroundWS*)bg)->GetFlagState(ALLIANCE) != BG_WS_FLAG_STATE_ON_GROUND) return; obj->Delete(); if(_player->GetTeam() == ALLIANCE) { ((BattleGroundWS*)bg)->EventPlayerReturnedFlag(_player); return; } else { _player->CastSpell(_player, 23335, true); return; } break; case 179786: // Warsong Flag // check if it's correct bg if(bg->GetTypeID() != BATTLEGROUND_WS) return; // check if flag dropped if(((BattleGroundWS*)bg)->GetFlagState(HORDE) != BG_WS_FLAG_STATE_ON_GROUND) return; obj->Delete(); if(_player->GetTeam() == HORDE) { ((BattleGroundWS*)bg)->EventPlayerReturnedFlag(_player); return; } else { _player->CastSpell(_player, 23333, true); return; } break; } } obj->Delete(); } break; default: sLog.outDebug("Unknown Object Type %u\n", obj->GetGoType()); break; } if (!spellId) return; SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellId ); if(!spellInfo) { sLog.outError("WORLD: unknown spell id %u\n", spellId); return; } Spell *spell = new Spell(spellCaster, spellInfo, false, 0); SpellCastTargets targets; targets.setUnitTarget( spellTarget ); if(obj) targets.setGOTarget( obj ); spell->prepare(&targets); }
/// @copydoc GameObjectLoader::CacheObject() bool EditorObjectLoader::CacheObject( GameObject* pObject, bool bEvictPlatformPreprocessedResourceData ) { HELIUM_ASSERT( pObject ); // Don't cache broken objects or packages. if( pObject->GetAnyFlagSet( GameObject::FLAG_BROKEN ) || pObject->IsPackage() ) { return false; } // Make sure we have an object preprocessor instance with which to cache the object. ObjectPreprocessor* pObjectPreprocessor = ObjectPreprocessor::GetStaticInstance(); if( !pObjectPreprocessor ) { HELIUM_TRACE( TRACE_WARNING, TXT( "EditorObjectLoader::CacheObject(): Missing ObjectPreprocessor to use for caching.\n" ) ); return false; } // Configuration objects should not be cached. GameObjectPath objectPath = pObject->GetPath(); Config& rConfig = Config::GetStaticInstance(); GameObjectPath configPackagePath = rConfig.GetConfigContainerPackagePath(); HELIUM_ASSERT( !configPackagePath.IsEmpty() ); for( GameObjectPath testPath = objectPath; !testPath.IsEmpty(); testPath = testPath.GetParent() ) { if( testPath == configPackagePath ) { return false; } } // Get the timestamp for the object based on the timestamp of its source package file and, if it's a resource, // the timestamp of the source resource file. GameObject* pPackageObject; for( pPackageObject = pObject; pPackageObject && !pPackageObject->IsPackage(); pPackageObject = pPackageObject->GetOwner() ) { } HELIUM_ASSERT( pPackageObject ); PackageLoader* pPackageLoader = Reflect::AssertCast< Package >( pPackageObject )->GetLoader(); HELIUM_ASSERT( pPackageLoader ); HELIUM_ASSERT( pPackageLoader->IsSourcePackageFile() ); int64_t objectTimestamp = pPackageLoader->GetFileTimestamp(); if( !pObject->IsDefaultTemplate() ) { Resource* pResource = Reflect::SafeCast< Resource >( pObject ); if( pResource ) { GameObjectPath baseResourcePath = pResource->GetPath(); HELIUM_ASSERT( !baseResourcePath.IsPackage() ); for( ; ; ) { GameObjectPath parentPath = baseResourcePath.GetParent(); if( parentPath.IsEmpty() || parentPath.IsPackage() ) { break; } baseResourcePath = parentPath; } Path sourceFilePath; if ( !File::GetDataDirectory( sourceFilePath ) ) { HELIUM_TRACE( TRACE_WARNING, TXT( "EditorObjectLoader::CacheObject(): Could not obtain data directory.\n" ) ); return false; } sourceFilePath += baseResourcePath.ToFilePathString().GetData(); int64_t sourceFileTimestamp = sourceFilePath.ModifiedTime(); if( sourceFileTimestamp > objectTimestamp ) { objectTimestamp = sourceFileTimestamp; } } } // Cache the object. bool bSuccess = pObjectPreprocessor->CacheObject( pObject, objectTimestamp, bEvictPlatformPreprocessedResourceData ); if( !bSuccess ) { HELIUM_TRACE( TRACE_ERROR, TXT( "EditorObjectLoader: Failed to cache object \"%s\".\n" ), *objectPath.ToString() ); } return bSuccess; }