SqlPreparedStatement * SqlConnection::GetStmt( int nIndex ) { if(nIndex < 0) return NULL; //resize stmt container if(m_holder.size() <= nIndex) m_holder.resize(nIndex + 1, NULL); SqlPreparedStatement * pStmt = NULL; //create stmt if needed if(m_holder[nIndex] == NULL) { //obtain SQL request string std::string fmt = m_db.GetStmtString(nIndex); STRAWBERRY_ASSERT(fmt.length()); //allocate SQlPreparedStatement object pStmt = CreateStatement(fmt); //prepare statement if(!pStmt->prepare()) { STRAWBERRY_ASSERT(false && "Unable to prepare SQL statement"); return NULL; } //save statement in internal registry m_holder[nIndex] = pStmt; } else pStmt = m_holder[nIndex]; return pStmt; }
void WaypointManager::Cleanup() { // check if points need to be renumbered and do it if (QueryResult *result = WorldDatabase.Query("SELECT 1 from creature_movement As T WHERE point <> (SELECT COUNT(*) FROM creature_movement WHERE id = T.id AND point <= T.point) LIMIT 1")) { delete result; WorldDatabase.DirectExecute("CREATE TEMPORARY TABLE temp LIKE creature_movement"); WorldDatabase.DirectExecute("INSERT INTO temp SELECT * FROM creature_movement"); WorldDatabase.DirectExecute("ALTER TABLE creature_movement DROP PRIMARY KEY"); WorldDatabase.DirectExecute("UPDATE creature_movement AS T SET point = (SELECT COUNT(*) FROM temp WHERE id = T.id AND point <= T.point)"); WorldDatabase.DirectExecute("ALTER TABLE creature_movement ADD PRIMARY KEY (id, point)"); WorldDatabase.DirectExecute("DROP TABLE temp"); sLog.outErrorDb("Table `creature_movement` was auto corrected for using points out of order (invalid or points missing)"); STRAWBERRY_ASSERT(!(result = WorldDatabase.Query("SELECT 1 from creature_movement As T WHERE point <> (SELECT COUNT(*) FROM creature_movement WHERE id = T.id AND point <= T.point) LIMIT 1"))); } if (QueryResult *result = WorldDatabase.Query("SELECT 1 from creature_movement_template As T WHERE point <> (SELECT COUNT(*) FROM creature_movement_template WHERE entry = T.entry AND point <= T.point) LIMIT 1")) { delete result; WorldDatabase.DirectExecute("CREATE TEMPORARY TABLE temp LIKE creature_movement_template"); WorldDatabase.DirectExecute("INSERT INTO temp SELECT * FROM creature_movement_template"); WorldDatabase.DirectExecute("ALTER TABLE creature_movement_template DROP PRIMARY KEY"); WorldDatabase.DirectExecute("UPDATE creature_movement_template AS T SET point = (SELECT COUNT(*) FROM temp WHERE entry = T.entry AND point <= T.point)"); WorldDatabase.DirectExecute("ALTER TABLE creature_movement_template ADD PRIMARY KEY (entry, point)"); WorldDatabase.DirectExecute("DROP TABLE temp"); sLog.outErrorDb("Table `creature_movement_template` was auto corrected for using points out of order (invalid or points missing)"); STRAWBERRY_ASSERT(!(result = WorldDatabase.Query("SELECT 1 from creature_movement_template As T WHERE point <> (SELECT COUNT(*) FROM creature_movement_template WHERE entry = T.entry AND point <= T.point) LIMIT 1"))); } }
DungeonMap* MapManager::CreateDungeonMap(uint32 id, uint32 InstanceId, Difficulty difficulty, DungeonPersistentState *save) { // make sure we have a valid map id if (!sMapStore.LookupEntry(id)) { sLog.outError("CreateDungeonMap: no entry for map %d", id); STRAWBERRY_ASSERT(false); } if (!ObjectMgr::GetInstanceTemplate(id)) { sLog.outError("CreateDungeonMap: no instance template for map %d", id); STRAWBERRY_ASSERT(false); } // some instances only have one difficulty if (!GetMapDifficultyData(id, difficulty)) difficulty = DUNGEON_DIFFICULTY_NORMAL; DEBUG_LOG("MapInstanced::CreateDungeonMap: %s map instance %d for %d created with difficulty %d", save?"":"new ", InstanceId, id, difficulty); DungeonMap *map = new DungeonMap(id, i_gridCleanUpDelay, InstanceId, difficulty); // Dungeons can have saved instance data bool load_data = save != NULL; map->CreateInstanceData(load_data); return map; }
void BattleGroundAV::DefendNode(BG_AV_Nodes node, BattleGroundTeamIndex teamIdx) { STRAWBERRY_ASSERT(m_Nodes[node].TotalOwner == BattleGroundAVTeamIndex(teamIdx)); STRAWBERRY_ASSERT(m_Nodes[node].Owner != BattleGroundAVTeamIndex(teamIdx)); STRAWBERRY_ASSERT(m_Nodes[node].State != POINT_CONTROLLED); m_Nodes[node].PrevOwner = m_Nodes[node].Owner; m_Nodes[node].Owner = BattleGroundAVTeamIndex(teamIdx); m_Nodes[node].PrevState = m_Nodes[node].State; m_Nodes[node].State = POINT_CONTROLLED; m_Nodes[node].Timer = 0; }
void BattleGroundAV::AssaultNode(BG_AV_Nodes node, BattleGroundTeamIndex teamIdx) { STRAWBERRY_ASSERT(m_Nodes[node].TotalOwner != BattleGroundAVTeamIndex(teamIdx)); STRAWBERRY_ASSERT(m_Nodes[node].Owner != BattleGroundAVTeamIndex(teamIdx)); // only assault an assaulted node if no totalowner exists: STRAWBERRY_ASSERT(m_Nodes[node].State != POINT_ASSAULTED || m_Nodes[node].TotalOwner == BG_AV_TEAM_NEUTRAL); // the timer gets another time, if the previous owner was 0 == Neutral m_Nodes[node].Timer = (m_Nodes[node].PrevOwner != BG_AV_TEAM_NEUTRAL) ? BG_AV_CAPTIME : BG_AV_SNOWFALL_FIRSTCAP; m_Nodes[node].PrevOwner = m_Nodes[node].Owner; m_Nodes[node].Owner = BattleGroundAVTeamIndex(teamIdx); m_Nodes[node].PrevState = m_Nodes[node].State; m_Nodes[node].State = POINT_ASSAULTED; }
void BattleGroundAV::ChangeMineOwner(uint8 mine, BattleGroundAVTeamIndex teamIdx) { m_Mine_Timer[mine] = BG_AV_MINE_TICK_TIMER; // TODO implement quest 7122 // mine=0 northmine, mine=1 southmine // TODO changing the owner should result in setting respawntime to infinite for current creatures (they should fight the new ones), spawning new mine owners creatures and changing the chest - objects so that the current owning team can use them STRAWBERRY_ASSERT(mine == BG_AV_NORTH_MINE || mine == BG_AV_SOUTH_MINE); if (m_Mine_Owner[mine] == teamIdx) return; m_Mine_PrevOwner[mine] = m_Mine_Owner[mine]; m_Mine_Owner[mine] = teamIdx; SendMineWorldStates(mine); SpawnEvent(BG_AV_MINE_EVENT + mine, teamIdx, true); SpawnEvent(BG_AV_MINE_BOSSES + mine, teamIdx, true); if (teamIdx != BG_AV_TEAM_NEUTRAL) { PlaySoundToAll((teamIdx == BG_AV_TEAM_ALLIANCE) ? BG_AV_SOUND_ALLIANCE_GOOD : BG_AV_SOUND_HORDE_GOOD); m_Mine_Reclaim_Timer[mine] = BG_AV_MINE_RECLAIM_TIMER; SendYell2ToAll(LANG_BG_AV_MINE_TAKEN , LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0), (teamIdx == BG_AV_TEAM_ALLIANCE ) ? LANG_BG_ALLY : LANG_BG_HORDE, (mine == BG_AV_NORTH_MINE) ? LANG_BG_AV_MINE_NORTH : LANG_BG_AV_MINE_SOUTH); } }
void BattleGroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node) { DEBUG_LOG("BattleGroundAV: player destroyed point node %i", node); STRAWBERRY_ASSERT(m_Nodes[node].Owner != BG_AV_TEAM_NEUTRAL) BattleGroundTeamIndex ownerTeamIdx = BattleGroundTeamIndex(m_Nodes[node].Owner); Team ownerTeam = ownerTeamIdx == BG_TEAM_ALLIANCE ? ALLIANCE : HORDE; // despawn banner DestroyNode(node); PopulateNode(node); UpdateNodeWorldState(node); if (IsTower(node)) { uint8 tmp = node - BG_AV_NODES_DUNBALDAR_SOUTH; // despawn marshal (one of those guys protecting the boss) SpawnEvent(BG_AV_MARSHAL_A_SOUTH + tmp, 0, false); UpdateScore(GetOtherTeamIndex(ownerTeamIdx), (-1) * BG_AV_RES_TOWER); RewardReputationToTeam((ownerTeam == ALLIANCE) ? BG_AV_FACTION_A : BG_AV_FACTION_H, m_RepTowerDestruction, ownerTeam); RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_TOWER), ownerTeam); SendYell2ToAll(LANG_BG_AV_TOWER_TAKEN, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0), GetNodeName(node), (ownerTeam == ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE); } else { SendYell2ToAll(LANG_BG_AV_GRAVE_TAKEN, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0), GetNodeName(node), (ownerTeam == ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE); } }
MovementGenerator* selectMovementGenerator(Creature *creature) { MovementGeneratorRegistry &mv_registry(MovementGeneratorRepository::Instance()); STRAWBERRY_ASSERT( creature->GetCreatureInfo() != NULL ); MovementGeneratorCreator const * mv_factory = mv_registry.GetRegistryItem( creature->GetOwnerGuid().IsPlayer() ? FOLLOW_MOTION_TYPE : creature->GetDefaultMovementType()); /* if( mv_factory == NULL ) { int best_val = -1; std::vector<std::string> l; mv_registry.GetRegisteredItems(l); for( std::vector<std::string>::iterator iter = l.begin(); iter != l.end(); ++iter) { const MovementGeneratorCreator *factory = mv_registry.GetRegistryItem((*iter).c_str()); const SelectableMovement *p = dynamic_cast<const SelectableMovement *>(factory); ASSERT( p != NULL ); int val = p->Permit(creature); if( val > best_val ) { best_val = val; mv_factory = p; } } }*/ return ( mv_factory == NULL ? NULL : mv_factory->Create(creature) ); }
Item* Item::CreateItem( uint32 item, uint32 count, Player const* player, uint32 randomPropertyId) { if (count < 1) return NULL; //don't create item at zero count if (ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(item)) { if (count > pProto->GetMaxStackSize()) count = pProto->GetMaxStackSize(); STRAWBERRY_ASSERT(count != 0 && "pProto->Stackable == 0 but checked at loading already"); Item* pItem = NewItemOrBag(pProto); if (pItem->Create(sObjectMgr.GenerateItemLowGuid(), item, player)) { pItem->SetCount(count); if (uint32 randId = randomPropertyId ? randomPropertyId : Item::GenerateItemRandomPropertyId(item)) pItem->SetItemRandomProperties(randId); return pItem; } else delete pItem; } return NULL; }
void SqlPlainPreparedStatement::bind( const SqlStmtParameters& holder ) { //verify if we bound all needed input parameters if(m_nParams != holder.boundParams()) { STRAWBERRY_ASSERT(false); return; } //reset resulting plain SQL request m_szPlainRequest = m_szFmt; size_t nLastPos = 0; SqlStmtParameters::ParameterContainer const& _args = holder.params(); SqlStmtParameters::ParameterContainer::const_iterator iter_last = _args.end(); for (SqlStmtParameters::ParameterContainer::const_iterator iter = _args.begin(); iter != iter_last; ++iter) { //bind parameter const SqlStmtFieldData& data = (*iter); std::ostringstream fmt; DataToString(data, fmt); nLastPos = m_szPlainRequest.find('?', nLastPos); if(nLastPos != std::string::npos) { std::string tmp = fmt.str(); m_szPlainRequest.replace(nLastPos, 1, tmp); nLastPos += tmp.length(); } } }
void BattleGroundAV::SendMineWorldStates(uint32 mine) { STRAWBERRY_ASSERT(mine == BG_AV_NORTH_MINE || mine == BG_AV_SOUTH_MINE); UpdateWorldState(BG_AV_MineWorldStates[mine][m_Mine_Owner[mine]], 1); if (m_Mine_Owner[mine] != m_Mine_PrevOwner[mine]) UpdateWorldState(BG_AV_MineWorldStates[mine][m_Mine_PrevOwner[mine]], 0); }
void BattleGroundAV::EventPlayerDefendsPoint(Player* player, BG_AV_Nodes node) { STRAWBERRY_ASSERT(GetStatus() == STATUS_IN_PROGRESS); BattleGroundTeamIndex teamIdx = GetTeamIndexByTeamId(player->GetTeam()); if (m_Nodes[node].Owner == BattleGroundAVTeamIndex(teamIdx) || m_Nodes[node].State != POINT_ASSAULTED) return; if( m_Nodes[node].TotalOwner == BG_AV_TEAM_NEUTRAL ) // initial snowfall capture { // until snowfall doesn't belong to anyone it is better handled in assault - code (best would be to have a special function // for neutral nodes.. but doing this just for snowfall will be a bit to much i think STRAWBERRY_ASSERT(node == BG_AV_NODES_SNOWFALL_GRAVE); // currently the only neutral grave EventPlayerAssaultsPoint(player, node); return; } DEBUG_LOG("BattleGroundAV: player defends node: %i", node); if (m_Nodes[node].PrevOwner != BattleGroundAVTeamIndex(teamIdx)) { sLog.outError("BattleGroundAV: player defends point which doesn't belong to his team %i", node); return; } DefendNode(node, teamIdx); // set the right variables for nodeinfo PopulateNode(node); // spawn node-creatures (defender for example) UpdateNodeWorldState(node); // send new mapicon to the player if (IsTower(node)) { SendYell2ToAll( LANG_BG_AV_TOWER_DEFENDED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0), GetNodeName(node), ( teamIdx == BG_TEAM_ALLIANCE ) ? LANG_BG_ALLY:LANG_BG_HORDE); UpdatePlayerScore(player, SCORE_TOWERS_DEFENDED, 1); PlaySoundToAll(BG_AV_SOUND_BOTH_TOWER_DEFEND); } else { SendYell2ToAll(LANG_BG_AV_GRAVE_DEFENDED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0), GetNodeName(node), ( teamIdx == BG_TEAM_ALLIANCE ) ? LANG_BG_ALLY:LANG_BG_HORDE); UpdatePlayerScore(player, SCORE_GRAVEYARDS_DEFENDED, 1); // update the statistic for the defending player PlaySoundToAll((teamIdx == BG_TEAM_ALLIANCE)?BG_AV_SOUND_ALLIANCE_GOOD:BG_AV_SOUND_HORDE_GOOD); } }
bool Database::DirectExecuteStmt( const SqlStatementID& id, SqlStmtParameters * params ) { STRAWBERRY_ASSERT(params); std::auto_ptr<SqlStmtParameters> p(params); //execute statement SqlConnection::Lock _guard(getAsyncConnection()); return _guard->ExecuteStmt(id.ID(), *params); }
void RemoveItemsSetItem(Player* player, ItemPrototype const* proto) { uint32 setid = proto->ItemSet; ItemSetEntry const* set = sItemSetStore.LookupEntry(setid); if (!set) { sLog.outErrorDb("Item set #%u for item #%u not found, mods not removed.", setid,proto->ItemId); return; } ItemSetEffect* eff = NULL; size_t setindex = 0; for (; setindex < player->ItemSetEff.size(); setindex++) { if (player->ItemSetEff[setindex] && player->ItemSetEff[setindex]->setid == setid) { eff = player->ItemSetEff[setindex]; break; } } // can be in case now enough skill requirement for set appling but set has been appliend when skill requirement not enough if (!eff) return; --eff->item_count; for (uint32 x = 0; x < 8; x++) { if (!set->spells[x]) continue; // enough for spell if (set->items_to_triggerspell[x] <= eff->item_count) continue; for (uint32 z = 0; z < 8; z++) { if (eff->spells[z] && eff->spells[z]->Id == set->spells[x]) { // spell can be not active if not fit form requirement player->ApplyEquipSpell(eff->spells[z], NULL, false); eff->spells[z] = NULL; break; } } } if (!eff->item_count) // all items of a set were removed { STRAWBERRY_ASSERT(eff == player->ItemSetEff[setindex]); delete eff; player->ItemSetEff[setindex] = NULL; } }
void BattleGroundAV::DestroyNode(BG_AV_Nodes node) { STRAWBERRY_ASSERT(m_Nodes[node].State == POINT_ASSAULTED); m_Nodes[node].TotalOwner = m_Nodes[node].Owner; m_Nodes[node].PrevOwner = m_Nodes[node].Owner; m_Nodes[node].PrevState = m_Nodes[node].State; m_Nodes[node].State = POINT_CONTROLLED; m_Nodes[node].Timer = 0; }
///// returns a new or existing Instance ///// in case of battlegrounds it will only return an existing map, those maps are created by bg-system Map* MapManager::CreateInstance(uint32 id, Player * player) { Map* map = NULL; Map * pNewMap = NULL; uint32 NewInstanceId = 0; // instanceId of the resulting map const MapEntry* entry = sMapStore.LookupEntry(id); if(entry->IsBattleGroundOrArena()) { // find existing bg map for player NewInstanceId = player->GetBattleGroundId(); STRAWBERRY_ASSERT(NewInstanceId); map = FindMap(id, NewInstanceId); STRAWBERRY_ASSERT(map); } else if (DungeonPersistentState* pSave = player->GetBoundInstanceSaveForSelfOrGroup(id)) { // solo/perm/group NewInstanceId = pSave->GetInstanceId(); map = FindMap(id, NewInstanceId); // it is possible that the save exists but the map doesn't if (!map) pNewMap = CreateDungeonMap(id, NewInstanceId, pSave->GetDifficulty(), pSave); } else { // if no instanceId via group members or instance saves is found // the instance will be created for the first time NewInstanceId = sObjectMgr.GenerateInstanceLowGuid(); Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficulty(entry->IsRaid()) : player->GetDifficulty(entry->IsRaid()); pNewMap = CreateDungeonMap(id, NewInstanceId, diff); } //add a new map object into the registry if(pNewMap) { i_maps[MapID(id, NewInstanceId)] = pNewMap; map = pNewMap; } return map; }
QueryResultMysql::QueryResultMysql(MYSQL_RES *result, MYSQL_FIELD *fields, uint64 rowCount, uint32 fieldCount) : QueryResult(rowCount, fieldCount), mResult(result) { mCurrentRow = new Field[mFieldCount]; STRAWBERRY_ASSERT(mCurrentRow); for (uint32 i = 0; i < mFieldCount; i++) mCurrentRow[i].SetType(ConvertNativeType(fields[i].type)); }
CreatureAI* selectAI(Creature *creature) { // Allow scripting AI for normal creatures and not controlled pets (guardians and mini-pets) if ((!creature->IsPet() || !((Pet*)creature)->isControlled()) && !creature->isCharmed()) if (CreatureAI* scriptedAI = sEventScriptMgr.GetCreatureAI(creature)) return scriptedAI; CreatureAIRegistry &ai_registry(CreatureAIRepository::Instance()); const CreatureAICreator *ai_factory = NULL; std::string ainame=creature->GetAIName(); // select by NPC flags _first_ - otherwise EventAI might be choosen for pets/totems // excplicit check for isControlled() and owner type to allow guardian, mini-pets and pets controlled by NPCs to be scripted by EventAI Unit *owner=NULL; if ((creature->IsPet() && ((Pet*)creature)->isControlled() && ((owner=creature->GetOwner()) && owner->GetTypeId()==TYPEID_PLAYER)) || creature->isCharmed()) ai_factory = ai_registry.GetRegistryItem("PetAI"); else if (creature->IsTotem()) ai_factory = ai_registry.GetRegistryItem("TotemAI"); // select by script name if (!ai_factory && !ainame.empty()) ai_factory = ai_registry.GetRegistryItem( ainame.c_str() ); if (!ai_factory && creature->IsGuard()) ai_factory = ai_registry.GetRegistryItem("GuardAI"); // select by permit check if (!ai_factory) { int best_val = PERMIT_BASE_NO; typedef CreatureAIRegistry::RegistryMapType RMT; RMT const &l = ai_registry.GetRegisteredItems(); for( RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter) { const CreatureAICreator *factory = iter->second; const SelectableAI *p = dynamic_cast<const SelectableAI *>(factory); STRAWBERRY_ASSERT( p != NULL ); int val = p->Permit(creature); if( val > best_val ) { best_val = val; ai_factory = p; } } } // select NullCreatureAI if not another cases ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key(); DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() ); return ( ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature) ); }
bool SqlStatement::DirectExecute() { SqlStmtParameters * args = detach(); //verify amount of bound parameters if(args->boundParams() != arguments()) { sLog.outError("SQL ERROR: wrong amount of parameters (%i instead of %i)", args->boundParams(), arguments()); sLog.outError("SQL ERROR: statement: %s", m_pDB->GetStmtString(ID()).c_str()); STRAWBERRY_ASSERT(false); return false; } return m_pDB->DirectExecuteStmt(m_index, args); }
void QuestMenu::AddMenuItem( uint32 QuestId, uint8 Icon) { Quest const* qinfo = sObjectMgr.GetQuestTemplate(QuestId); if (!qinfo) return; STRAWBERRY_ASSERT( m_qItems.size() <= GOSSIP_MAX_MENU_ITEMS ); QuestMenuItem qItem; qItem.m_qId = QuestId; qItem.m_qIcon = Icon; m_qItems.push_back(qItem); }
bool StaticMapTree::isInLineOfSight(const Vector3& pos1, const Vector3& pos2) const { float maxDist = (pos2 - pos1).magnitude(); // valid map coords should *never ever* produce float overflow, but this would produce NaNs too: STRAWBERRY_ASSERT(maxDist < std::numeric_limits<float>::max()); // prevent NaN values which can cause BIH intersection to enter infinite loop if (maxDist < 1e-10f) return true; // direction with length of 1 G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist); if (getIntersectionTime(ray, maxDist, true)) return false; return true; }
Map* MapManager::CreateMap(uint32 id, const WorldObject* obj) { STRAWBERRY_ASSERT(obj); //if(!obj->IsInWorld()) sLog.outError("GetMap: called for map %d with object (typeid %d, guid %d, mapid %d, instanceid %d) who is not in world!", id, obj->GetTypeId(), obj->GetGUIDLow(), obj->GetMapId(), obj->GetInstanceId()); Guard _guard(*this); Map * m = NULL; const MapEntry* entry = sMapStore.LookupEntry(id); if(!entry) return NULL; if(entry->Instanceable()) { STRAWBERRY_ASSERT(obj->GetTypeId() == TYPEID_PLAYER); //create DungeonMap object if(obj->GetTypeId() == TYPEID_PLAYER) m = CreateInstance(id, (Player*)obj); } else { //create regular non-instanceable map m = FindMap(id); if( m == NULL ) { m = new WorldMap(id, i_gridCleanUpDelay); //add map into container i_maps[MapID(id)] = m; // non-instanceable maps always expected have saved state m->CreateInstanceData(true); } } return m; }
void GossipMenu::AddMenuItem(uint8 Icon, const std::string& Message, uint32 dtSender, uint32 dtAction, const std::string& BoxMessage, uint32 BoxMoney, bool Coded) { STRAWBERRY_ASSERT( m_gItems.size() <= GOSSIP_MAX_MENU_ITEMS ); GossipMenuItem gItem; gItem.m_gIcon = Icon; gItem.m_gMessage = Message; gItem.m_gCoded = Coded; gItem.m_gSender = dtSender; gItem.m_gOptionId = dtAction; gItem.m_gBoxMessage = BoxMessage; gItem.m_gBoxMoney = BoxMoney; m_gItems.push_back(gItem); }
bool StaticMapTree::getObjectHitPos(const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist) const { bool result=false; float maxDist = (pPos2 - pPos1).magnitude(); // valid map coords should *never ever* produce float overflow, but this would produce NaNs too: STRAWBERRY_ASSERT(maxDist < std::numeric_limits<float>::max()); // prevent NaN values which can cause BIH intersection to enter infinite loop if (maxDist < 1e-10f) { pResultHitPos = pPos2; return false; } Vector3 dir = (pPos2 - pPos1)/maxDist; // direction with length of 1 G3D::Ray ray(pPos1, dir); float dist = maxDist; if (getIntersectionTime(ray, dist, false)) { pResultHitPos = pPos1 + dir * dist; if (pModifyDist < 0) { if ((pResultHitPos - pPos1).magnitude() > -pModifyDist) { pResultHitPos = pResultHitPos + dir*pModifyDist; } else { pResultHitPos = pPos1; } } else { pResultHitPos = pResultHitPos + dir*pModifyDist; } result = true; } else { pResultHitPos = pPos2; result = false; } return result; }
void AuctionHouseObject::Update() { time_t curTime = sWorld.GetGameTime(); ///- Handle expired auctions for (AuctionEntryMap::iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ) { if (itr->second->moneyDeliveryTime) // pending auction { if (curTime > itr->second->moneyDeliveryTime) { sAuctionMgr.SendAuctionSuccessfulMail(itr->second); itr->second->DeleteFromDB(); STRAWBERRY_ASSERT(!itr->second->itemGuidLow); // already removed or send in mail at won delete itr->second; AuctionsMap.erase(itr++); continue; } } else // active auction { if (curTime > itr->second->expireTime) { ///- perform the transaction if there was bidder if (itr->second->bid) itr->second->AuctionBidWinning(); ///- cancel the auction if there was no bidder and clear the auction else { sAuctionMgr.SendAuctionExpiredMail(itr->second); itr->second->DeleteFromDB(); delete itr->second; AuctionsMap.erase(itr++); continue; } } } ++itr; } }
void ThreatManager::addThreat(Unit* pVictim, float pThreat, bool crit, SpellSchoolMask schoolMask, SpellEntry const *pThreatSpell) { //function deals with adding threat and adding players and pets into ThreatList //mobs, NPCs, guards have ThreatList and HateOfflineList //players and pets have only InHateListOf //HateOfflineList is used co contain unattackable victims (in-flight, in-water, GM etc.) // not to self if (pVictim == getOwner()) return; // not to GM if (!pVictim || (pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster()) ) return; // not to dead and not for dead if(!pVictim->isAlive() || !getOwner()->isAlive() ) return; STRAWBERRY_ASSERT(getOwner()->GetTypeId()== TYPEID_UNIT); float threat = ThreatCalcHelper::CalcThreat(pVictim, iOwner, pThreat, crit, schoolMask, pThreatSpell); if (threat > 0.0f) { if (float redirectedMod = pVictim->getHostileRefManager().GetThreatRedirectionMod()) { if (Unit* redirectedTarget = pVictim->getHostileRefManager().GetThreatRedirectionTarget()) { if (redirectedTarget != getOwner() && redirectedTarget->isAlive()) { float redirectedThreat = threat * redirectedMod; threat -= redirectedThreat; addThreatDirectly(redirectedTarget, redirectedThreat); } } } } addThreatDirectly(pVictim, threat); }
BattleGroundMap* MapManager::CreateBattleGroundMap(uint32 id, uint32 InstanceId, BattleGround* bg) { DEBUG_LOG("MapInstanced::CreateBattleGroundMap: instance:%d for map:%d and bgType:%d created.", InstanceId, id, bg->GetTypeID()); PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(),bg->GetMinLevel()); uint8 spawnMode = bracketEntry ? bracketEntry->difficulty : REGULAR_DIFFICULTY; BattleGroundMap *map = new BattleGroundMap(id, i_gridCleanUpDelay, InstanceId, spawnMode); STRAWBERRY_ASSERT(map->IsBattleGroundOrArena()); map->SetBG(bg); bg->SetBgMap(map); //add map into map container i_maps[MapID(id, InstanceId)] = map; // BGs/Arenas not have saved instance data map->CreateInstanceData(false); return map; }
inline void LoadDB2(LocalDB2Data& localeData, StoreProblemList1& errors, DB2Storage<T>& storage, std::string const& db2Path, std::string const& filename) { // compatibility format and C++ structure sizes STRAWBERRY_ASSERT(DB2FileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDB2_assert_print(DB2FileLoader::GetFormatRecordSize(storage.GetFormat()), sizeof(T), filename)); ++DB2FileCount; std::string db2Filename = db2Path + filename; if (storage.Load(db2Filename.c_str(), localeData.defaultLocale)) { for(uint8 i = 0; fullLocaleNameList[i].name; ++i) { if (!(localeData.availableDb2Locales & (1 << i))) continue; LocaleNameStr const* localStr = &fullLocaleNameList[i]; std::string db2_dir_loc = db2Path + localStr->name + "/"; std::string localizedName = db2Path + localStr->name + "/" + filename; if(!storage.LoadStringsFrom(localizedName.c_str(), localStr->locale)) localeData.availableDb2Locales &= ~(1<<i); // mark as not available for speedup next checks } } else { // sort problematic db2 to (1) non compatible and (2) nonexistent if (FILE* f = fopen(db2Filename.c_str(), "rb")) { char buf[100]; snprintf(buf, 100, " (exist, but have %d fields instead " SIZEFMTD ") Wrong client version DB2 file?", storage.GetFieldCount(), strlen(storage.GetFormat())); errors.push_back(db2Filename + buf); fclose(f); } else errors.push_back(db2Filename); } }
void BattleGroundAV::UpdateScore(BattleGroundTeamIndex teamIdx, int32 points ) { // note: to remove reinforcements points must be negative, for adding reinforcements points must be positive STRAWBERRY_ASSERT( teamIdx == BG_TEAM_ALLIANCE || teamIdx == BG_TEAM_HORDE); m_TeamScores[teamIdx] += points; // m_TeamScores is int32 - so no problems here if (points < 0) { if (m_TeamScores[teamIdx] < 1) { m_TeamScores[teamIdx] = 0; // other team will win: EndBattleGround((teamIdx == BG_TEAM_ALLIANCE)? HORDE : ALLIANCE); } else if (!m_IsInformedNearLose[teamIdx] && m_TeamScores[teamIdx] < BG_AV_SCORE_NEAR_LOSE) { SendMessageToAll((teamIdx == BG_TEAM_HORDE) ? LANG_BG_AV_H_NEAR_LOSE : LANG_BG_AV_A_NEAR_LOSE, CHAT_MSG_BG_SYSTEM_NEUTRAL); PlaySoundToAll(BG_AV_SOUND_NEAR_LOSE); m_IsInformedNearLose[teamIdx] = true; } } // must be called here, else it could display a negative value UpdateWorldState(((teamIdx == BG_TEAM_HORDE) ? BG_AV_Horde_Score : BG_AV_Alliance_Score), m_TeamScores[teamIdx]); }
void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) { Opcodes opcode = recv_data.GetOpcodeEnum(); DEBUG_LOG("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode); recv_data.hexlike(); Unit *mover = _player->m_mover; STRAWBERRY_ASSERT(mover != NULL); // there must always be a mover Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck if (plMover && plMover->IsBeingTeleported()) { recv_data.rfinish(); // prevent warnings spam return; } /* extract packet */ MovementInfo movementInfo; ReadMovementInfo(recv_data, &movementInfo); recv_data.rfinish(); // prevent warnings spam // prevent tampered movement data if (movementInfo.guid != mover->GetObjectGuid()) return; /* handle special cases */ if (movementInfo.moveFlags & MOVEFLAG_ONTRANSPORT) { // transports size limited // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) if (movementInfo.t_pos.x > 50 || movementInfo.t_pos.y > 50 || movementInfo.t_pos.z > 50) { recv_data.rfinish(); // prevent warnings spam return; } if (!Strawberry::IsValidMapCoord(movementInfo.pos.x + movementInfo.t_pos.x, movementInfo.pos.y + movementInfo.t_pos.y), movementInfo.pos.z + movementInfo.t_pos.z, movementInfo.pos.o + movementInfo.t_pos.o) { recv_data.rfinish(); // prevent warnings spam return; } // if we boarded a transport, add us to it if (plMover && !plMover->GetTransport()) { // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list for (MapManager::TransportSet::const_iterator iter = sMapMgr.m_Transports.begin(); iter != sMapMgr.m_Transports.end(); ++iter) { if ((*iter)->GetObjectGuid() == movementInfo.t_guid) { plMover->m_transport = (*iter); (*iter)->AddPassenger(plMover); break; } } } if (!mover->GetTransport() && !mover->GetVehicle()) { GameObject *go = mover->GetMap()->GetGameObject(movementInfo.t_guid); if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT) movementInfo.moveFlags &= ~MOVEFLAG_ONTRANSPORT; } } else if (plMover && plMover->GetTransport()) // if we were on a transport, leave { plMover->m_transport->RemovePassenger(plMover); plMover->m_transport = NULL; movementInfo.t_time = 0; movementInfo.t_seat = -1; } // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map). if (opcode == MSG_MOVE_FALL_LAND && plMover) plMover->HandleFall(movementInfo); if (plMover && ((movementInfo.moveFlags & MOVEFLAG_SWIMMING) != 0) != plMover->IsInWater()) { // now client not include swimming flag in case jumping under water plMover->SetInWater(!plMover->IsInWater());// || plMover->GetMap()->IsUnderWater(movementInfo.pos.x, movementInfo.pos.y, movementInfo.pos.y)); } /*----------------------*/ /* process position-change */ WorldPacket data(Opcodes(opcode), recv_data.size()); movementInfo.time = WorldTimer::getMSTime(); movementInfo.guid = mover->GetObjectGuid(); WriteMovementInfo(&data, &movementInfo); mover->SendMessageToSet(&data, _player); mover->m_movementInfo = movementInfo; // this is almost never true (not sure why it is sometimes, but it is), normally use mover->IsVehicle() if (mover->GetVehicle()) { mover->SetOrientation(movementInfo.pos.o); return; } mover->SetPosition(movementInfo.pos.x, movementInfo.pos.y, movementInfo.pos.z, movementInfo.pos.o, false); if (plMover) // nothing is charmed, or player charmed { plMover->UpdateFallInformationIfNeed(movementInfo, opcode); if (movementInfo.pos.z < -500.0f) { //if (!(plMover->InBattleground() // && plMover->GetBattleground() // && plMover->GetBattleground()->HandlePlayerUnderMap(_player))) { // NOTE: this is actually called many times while falling // even after the player has been teleported away // TODO: discard movement packets after the player is rooted if (plMover->isAlive()) { plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth()); // pl can be alive if GM/etc if (!plMover->isAlive()) { // change the death state to CORPSE to prevent the death timer from // starting in the next player update plMover->KillPlayer(); plMover->BuildPlayerRepop(); } } // cancel the death timer here if started //plMover->RepopAtGraveyard(); } } } }