From c238cae7d0733c76ee844d81e7c959627e5d711b Mon Sep 17 00:00:00 2001 From: Malcrom Date: Mon, 3 Jun 2013 22:33:26 -0230 Subject: Core: Remove some no longer needed gossip code. --- src/server/game/Entities/Creature/Creature.cpp | 93 -------------------------- src/server/game/Entities/Creature/Creature.h | 2 - src/server/game/Entities/Object/Object.cpp | 6 -- src/server/game/Entities/Player/Player.cpp | 17 ++--- 4 files changed, 4 insertions(+), 114 deletions(-) (limited to 'src/server/game/Entities') diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index f274f201e04..b3deb7ae7de 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -871,92 +871,6 @@ void Creature::InitializeReactState() SetReactState(REACT_DEFENSIVE);*/; } -bool Creature::isCanTrainingOf(Player* player, bool msg) const -{ - if (!isTrainer()) - return false; - - TrainerSpellData const* trainer_spells = GetTrainerSpells(); - - if ((!trainer_spells || trainer_spells->spellList.empty()) && GetCreatureTemplate()->trainer_type != TRAINER_TYPE_PETS) - { - TC_LOG_ERROR(LOG_FILTER_SQL, "Creature %u (Entry: %u) have UNIT_NPC_FLAG_TRAINER but have empty trainer spell list.", - GetGUIDLow(), GetEntry()); - return false; - } - - switch (GetCreatureTemplate()->trainer_type) - { - case TRAINER_TYPE_CLASS: - if (player->getClass() != GetCreatureTemplate()->trainer_class) - { - if (msg) - { - player->PlayerTalkClass->ClearMenus(); - switch (GetCreatureTemplate()->trainer_class) - { - case CLASS_DRUID: player->PlayerTalkClass->SendGossipMenu(4913, GetGUID()); break; - case CLASS_HUNTER: player->PlayerTalkClass->SendGossipMenu(10090, GetGUID()); break; - case CLASS_MAGE: player->PlayerTalkClass->SendGossipMenu(328, GetGUID()); break; - case CLASS_PALADIN:player->PlayerTalkClass->SendGossipMenu(1635, GetGUID()); break; - case CLASS_PRIEST: player->PlayerTalkClass->SendGossipMenu(4436, GetGUID()); break; - case CLASS_ROGUE: player->PlayerTalkClass->SendGossipMenu(4797, GetGUID()); break; - case CLASS_SHAMAN: player->PlayerTalkClass->SendGossipMenu(5003, GetGUID()); break; - case CLASS_WARLOCK:player->PlayerTalkClass->SendGossipMenu(5836, GetGUID()); break; - case CLASS_WARRIOR:player->PlayerTalkClass->SendGossipMenu(4985, GetGUID()); break; - } - } - return false; - } - break; - case TRAINER_TYPE_PETS: - if (player->getClass() != CLASS_HUNTER) - { - player->PlayerTalkClass->ClearMenus(); - player->PlayerTalkClass->SendGossipMenu(3620, GetGUID()); - return false; - } - break; - case TRAINER_TYPE_MOUNTS: - if (GetCreatureTemplate()->trainer_race && player->getRace() != GetCreatureTemplate()->trainer_race) - { - if (msg) - { - player->PlayerTalkClass->ClearMenus(); - switch (GetCreatureTemplate()->trainer_race) - { - case RACE_DWARF: player->PlayerTalkClass->SendGossipMenu(5865, GetGUID()); break; - case RACE_GNOME: player->PlayerTalkClass->SendGossipMenu(4881, GetGUID()); break; - case RACE_HUMAN: player->PlayerTalkClass->SendGossipMenu(5861, GetGUID()); break; - case RACE_NIGHTELF: player->PlayerTalkClass->SendGossipMenu(5862, GetGUID()); break; - case RACE_ORC: player->PlayerTalkClass->SendGossipMenu(5863, GetGUID()); break; - case RACE_TAUREN: player->PlayerTalkClass->SendGossipMenu(5864, GetGUID()); break; - case RACE_TROLL: player->PlayerTalkClass->SendGossipMenu(5816, GetGUID()); break; - case RACE_UNDEAD_PLAYER:player->PlayerTalkClass->SendGossipMenu(624, GetGUID()); break; - case RACE_BLOODELF: player->PlayerTalkClass->SendGossipMenu(5862, GetGUID()); break; - case RACE_DRAENEI: player->PlayerTalkClass->SendGossipMenu(5864, GetGUID()); break; - } - } - return false; - } - break; - case TRAINER_TYPE_TRADESKILLS: - if (GetCreatureTemplate()->trainer_spell && !player->HasSpell(GetCreatureTemplate()->trainer_spell)) - { - if (msg) - { - player->PlayerTalkClass->ClearMenus(); - player->PlayerTalkClass->SendGossipMenu(11031, GetGUID()); - } - return false; - } - break; - default: - return false; // checked and error output at creature_template loading - } - return true; -} - bool Creature::isCanInteractWithBattleMaster(Player* player, bool msg) const { if (!isBattleMaster()) @@ -989,13 +903,6 @@ bool Creature::isCanInteractWithBattleMaster(Player* player, bool msg) const return true; } -bool Creature::isCanTrainingAndResetTalentsOf(Player* player) const -{ - return player->getLevel() >= 10 - && GetCreatureTemplate()->trainer_type == TRAINER_TYPE_CLASS - && player->getClass() == GetCreatureTemplate()->trainer_class; -} - Player* Creature::GetLootRecipient() const { if (!m_lootRecipient) diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 1b59c273d52..6459b80a063 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -482,9 +482,7 @@ class Creature : public Unit, public GridObject, public MapCreature void InitializeReactState(); /// @todo Rename these properly - bool isCanTrainingOf(Player* player, bool msg) const; bool isCanInteractWithBattleMaster(Player* player, bool msg) const; - bool isCanTrainingAndResetTalentsOf(Player* player) const; bool canCreatureAttack(Unit const* victim, bool force = true) const; bool IsImmunedToSpell(SpellInfo const* spellInfo) const; // override Unit::IsImmunedToSpell bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; // override Unit::IsImmunedToSpellEffect diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 6d6c0be5666..262d1b1a475 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -579,12 +579,6 @@ void Object::_BuildValuesUpdate(uint8 updateType, ByteBuffer* data, UpdateMask* { if (!target->canSeeSpellClickOn(this->ToCreature())) appendValue &= ~UNIT_NPC_FLAG_SPELLCLICK; - - if (appendValue & UNIT_NPC_FLAG_TRAINER) - { - if (!creature->isCanTrainingOf(target, false)) - appendValue &= ~(UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_TRAINER_CLASS | UNIT_NPC_FLAG_TRAINER_PROFESSION); - } } *data << uint32(appendValue); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 1d3eebf4c58..7b183c508ae 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -14374,18 +14374,6 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool } break; } - case GOSSIP_OPTION_TRAINER: - if (!creature->isCanTrainingOf(this, false)) - canTalk = false; - break; - case GOSSIP_OPTION_LEARNDUALSPEC: - if (!(GetSpecsCount() == 1 && creature->isCanTrainingAndResetTalentsOf(this) && !(getLevel() < sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL)))) - canTalk = false; - break; - case GOSSIP_OPTION_UNLEARNTALENTS: - if (!creature->isCanTrainingAndResetTalentsOf(this)) - canTalk = false; - break; case GOSSIP_OPTION_UNLEARNPETTALENTS: if (!GetPet() || GetPet()->getPetType() != HUNTER_PET || GetPet()->m_spells.size() <= 1 || creature->GetCreatureTemplate()->trainer_type != TRAINER_TYPE_PETS || creature->GetCreatureTemplate()->trainer_class != CLASS_HUNTER) canTalk = false; @@ -14405,6 +14393,9 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool case GOSSIP_OPTION_QUESTGIVER: canTalk = false; break; + case GOSSIP_OPTION_TRAINER: + case GOSSIP_OPTION_LEARNDUALSPEC: + case GOSSIP_OPTION_UNLEARNTALENTS: case GOSSIP_OPTION_GOSSIP: case GOSSIP_OPTION_SPIRITGUIDE: case GOSSIP_OPTION_INNKEEPER: @@ -14418,7 +14409,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool canTalk = false; break; default: - TC_LOG_ERROR(LOG_FILTER_SQL, "Creature entry %u have unknown gossip option %u for menu %u", creature->GetEntry(), itr->second.OptionType, itr->second.MenuId); + TC_LOG_ERROR(LOG_FILTER_SQL, "Creature entry %u has unknown gossip option %u for menu %u", creature->GetEntry(), itr->second.OptionType, itr->second.MenuId); canTalk = false; break; } -- cgit v1.2.3 From cbd69f12bd2a4dcee2a1c2a9184c97e24724903f Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 4 Jun 2013 14:52:38 +0200 Subject: Core/Movement: Refactored removing transport part of movement info structure into a separate method. Also corrects seat set after exiting vehicle --- src/server/game/Entities/Object/Object.h | 9 +++++++++ src/server/game/Entities/Player/Player.cpp | 8 ++------ src/server/game/Entities/Vehicle/Vehicle.cpp | 4 +--- src/server/game/Handlers/MovementHandler.cpp | 4 +--- 4 files changed, 13 insertions(+), 12 deletions(-) (limited to 'src/server/game/Entities') diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 9acd3cc3026..ffbcd38049f 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -442,6 +442,15 @@ struct MovementInfo void SetFallTime(uint32 time) { fallTime = time; } + void ClearTransport() + { + t_guid = 0; + t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); + t_seat = -1; + t_time = 0; + t_time2 = 0; + } + void OutDebug(); }; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 7b183c508ae..ebd94b84079 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2116,9 +2116,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati { m_transport->RemovePassenger(this); m_transport = NULL; - m_movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); - m_movementInfo.t_time = 0; - m_movementInfo.t_seat = -1; + m_movementInfo.ClearTransport(); RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :) } @@ -2144,9 +2142,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati { m_transport->RemovePassenger(this); m_transport = NULL; - m_movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); - m_movementInfo.t_time = 0; - m_movementInfo.t_seat = -1; + m_movementInfo.ClearTransport(); } } diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 6d7d3f2b2ff..86ea67c2d0f 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -519,9 +519,7 @@ void Vehicle::RemovePassenger(Unit* unit) if (_me->IsInWorld()) { unit->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); - unit->m_movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); - unit->m_movementInfo.t_time = 0; - unit->m_movementInfo.t_seat = 0; + unit->m_movementInfo.ClearTransport(); } // only for flyable vehicles diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index abb4b9310be..3270b19fd48 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -348,9 +348,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData) { plrMover->m_transport->RemovePassenger(plrMover); plrMover->m_transport = NULL; - movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); - movementInfo.t_time = 0; - movementInfo.t_seat = -1; + movementInfo.ClearTransport(); } // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map). -- cgit v1.2.3 From eed1286a8c5cba31a75fd8f17fc78bef865d3a83 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 4 Jun 2013 16:28:30 +0200 Subject: Core/Vehicles: Handle vehicle seat switches through aura effects. --- src/server/game/Entities/Unit/Unit.cpp | 49 +++++++++++------------ src/server/game/Entities/Unit/Unit.h | 1 + src/server/game/Entities/Vehicle/Vehicle.cpp | 9 +++-- src/server/game/Entities/Vehicle/Vehicle.h | 2 +- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 7 +++- 5 files changed, 37 insertions(+), 31 deletions(-) (limited to 'src/server/game/Entities') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 4ad2a06a61e..b62b5124987 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -16816,29 +16816,23 @@ void Unit::EnterVehicle(Unit* base, int8 seatId) void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* aurApp) { // Must be called only from aura handler + ASSERT(aurApp); + if (!isAlive() || GetVehicleKit() == vehicle || vehicle->GetBase()->IsOnVehicle(this)) return; if (m_vehicle) { - if (m_vehicle == vehicle) - { - if (seatId >= 0 && seatId != GetTransSeat()) - { - TC_LOG_DEBUG(LOG_FILTER_VEHICLES, "EnterVehicle: %u leave vehicle %u seat %d and enter %d.", GetEntry(), m_vehicle->GetBase()->GetEntry(), GetTransSeat(), seatId); - ChangeSeat(seatId); - } - - return; - } - else + if (m_vehicle != vehicle) { TC_LOG_DEBUG(LOG_FILTER_VEHICLES, "EnterVehicle: %u exit %u and enter %u.", GetEntry(), m_vehicle->GetBase()->GetEntry(), vehicle->GetBase()->GetEntry()); ExitVehicle(); } + else if (seatId >= 0 && seatId == GetTransSeat()) + return; } - if (!aurApp || aurApp->GetRemoveMode()) + if (aurApp->GetRemoveMode()) return; if (Player* player = ToPlayer()) @@ -16868,16 +16862,22 @@ void Unit::ChangeSeat(int8 seatId, bool next) if (seat == m_vehicle->Seats.end() || seat->second.Passenger) return; - // Todo: the functions below could be consolidated and refactored to take - // SeatMap::const_iterator as parameter, to save redundant map lookups. - m_vehicle->RemovePassenger(this); + AuraEffect* rideVehicleEffect = NULL; + AuraEffectList const& vehicleAuras = m_vehicle->GetBase()->GetAuraEffectsByType(SPELL_AURA_CONTROL_VEHICLE); + for (AuraEffectList::const_iterator itr = vehicleAuras.begin(); itr != vehicleAuras.end(); ++itr) + { + if ((*itr)->GetCasterGUID() != GetGUID()) + continue; + + // Make sure there is only one ride vehicle aura on target cast by the unit changing seat + ASSERT(!rideVehicleEffect); + rideVehicleEffect = *itr; + } - // Set m_vehicle to NULL before adding passenger as adding new passengers is handled asynchronously - // and someone may call ExitVehicle again before passenger is added to new seat - Vehicle* veh = m_vehicle; - m_vehicle = NULL; - if (!veh->AddPassenger(this, seatId)) - ASSERT(false); + // Unit riding a vehicle must always have control vehicle aura on target + ASSERT(rideVehicleEffect); + + rideVehicleEffect->ChangeAmount(seat->first + 1); } void Unit::ExitVehicle(Position const* /*exitPosition*/) @@ -16907,7 +16907,8 @@ void Unit::_ExitVehicle(Position const* exitPosition) if (!m_vehicle) return; - m_vehicle->RemovePassenger(this); + // This should be done before dismiss, because there may be some aura removal + Vehicle* vehicle = m_vehicle->RemovePassenger(this); Player* player = ToPlayer(); @@ -16915,10 +16916,6 @@ void Unit::_ExitVehicle(Position const* exitPosition) if (player && player->duel && player->duel->isMounted) player->DuelComplete(DUEL_FLED); - // This should be done before dismiss, because there may be some aura removal - Vehicle* vehicle = m_vehicle; - m_vehicle = NULL; - SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT Position pos; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 67a6fa2a994..c65f08ffa6f 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2082,6 +2082,7 @@ class Unit : public WorldObject void RemoveVehicleKit(); Vehicle* GetVehicleKit()const { return m_vehicleKit; } Vehicle* GetVehicle() const { return m_vehicle; } + void SetVehicle(Vehicle* vehicle) { m_vehicle = vehicle; } bool IsOnVehicle(const Unit* vehicle) const; Unit* GetVehicleBase() const; Creature* GetVehicleCreatureBase() const; diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 86ea67c2d0f..5cfb9cc2fae 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -496,10 +496,10 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) * @param [in, out] unit The passenger to remove. */ -void Vehicle::RemovePassenger(Unit* unit) +Vehicle* Vehicle::RemovePassenger(Unit* unit) { if (unit->GetVehicle() != this) - return; + return NULL; SeatMap::iterator seat = GetSeatIteratorForPassenger(unit); ASSERT(seat != Seats.end()); @@ -531,6 +531,9 @@ void Vehicle::RemovePassenger(Unit* unit) if (GetBase()->GetTypeId() == TYPEID_UNIT) sScriptMgr->OnRemovePassenger(this, unit); + + unit->SetVehicle(NULL); + return this; } /** @@ -801,7 +804,7 @@ bool VehicleJoinEvent::Execute(uint64, uint32) Target->RemovePendingEventsForSeat(Seat->first); - Passenger->m_vehicle = Target; + Passenger->SetVehicle(Target); Seat->second.Passenger = Passenger->GetGUID(); if (Seat->second.SeatInfo->CanEnterOrExit()) { diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index c83a9fa5f33..9fb1b6614b5 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -59,7 +59,7 @@ class Vehicle : public TransportBase bool AddPassenger(Unit* passenger, int8 seatId = -1); void EjectPassenger(Unit* passenger, Unit* controller); - void RemovePassenger(Unit* passenger); + Vehicle* RemovePassenger(Unit* passenger); void RelocatePassengers(); void RemoveAllPassengers(); bool IsVehicleInUse() const; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index b65213e134d..0f1950bc860 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2926,7 +2926,12 @@ void AuraEffect::HandleAuraControlVehicle(AuraApplication const* aurApp, uint8 m if (caster->GetTypeId() == TYPEID_UNIT) caster->ToCreature()->RemoveCorpse(); } - caster->_ExitVehicle(); + + if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT)) + caster->_ExitVehicle(); + else + target->GetVehicleKit()->RemovePassenger(caster); // Only remove passenger from vehicle without launching exit movement or despawning the vehicle + // some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them caster->RemoveAurasDueToSpell(GetId()); } -- cgit v1.2.3 From e18571346400281861490b36c4d35a381bc80dd8 Mon Sep 17 00:00:00 2001 From: corbi Date: Wed, 5 Jun 2013 10:34:05 +0300 Subject: Stats Limits --- src/server/game/Entities/Unit/StatSystem.cpp | 15 +++++++++++++++ src/server/game/World/World.cpp | 7 +++++++ src/server/game/World/World.h | 5 +++++ src/server/worldserver/worldserver.conf.dist | 23 +++++++++++++++++++++++ 4 files changed, 50 insertions(+) (limited to 'src/server/game/Entities') diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index c30fa910f76..2dfe77287d4 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -575,6 +575,10 @@ void Player::UpdateBlockPercentage() value += GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_PERCENT); // Increase from rating value += GetRatingBonusValue(CR_BLOCK); + + if (sWorld->getBoolConfig(CONFIG_STATS_LIMITS_ENABLE)) + value = value > sWorld->getFloatConfig(CONFIG_STATS_LIMITS_BLOCK) ? sWorld->getFloatConfig(CONFIG_STATS_LIMITS_BLOCK) : value; + value = value < 0.0f ? 0.0f : value; } SetStatFloatValue(PLAYER_BLOCK_PERCENTAGE, value); @@ -609,6 +613,10 @@ void Player::UpdateCritPercentage(WeaponAttackType attType) float value = GetTotalPercentageModValue(modGroup) + GetRatingBonusValue(cr); // Modify crit from weapon skill and maximized defense skill of same level victim difference value += (int32(GetWeaponSkillValue(attType)) - int32(GetMaxSkillValueForLevel())) * 0.04f; + + if (sWorld->getBoolConfig(CONFIG_STATS_LIMITS_ENABLE)) + value = value > sWorld->getFloatConfig(CONFIG_STATS_LIMITS_CRIT) ? sWorld->getFloatConfig(CONFIG_STATS_LIMITS_CRIT) : value; + value = value < 0.0f ? 0.0f : value; SetStatFloatValue(index, value); } @@ -700,6 +708,10 @@ void Player::UpdateParryPercentage() nondiminishing += GetTotalAuraModifier(SPELL_AURA_MOD_PARRY_PERCENT); // apply diminishing formula to diminishing parry chance value = nondiminishing + diminishing * parry_cap[pclass] / (diminishing + parry_cap[pclass] * m_diminishing_k[pclass]); + + if (sWorld->getBoolConfig(CONFIG_STATS_LIMITS_ENABLE)) + value = value > sWorld->getFloatConfig(CONFIG_STATS_LIMITS_PARRY) ? sWorld->getFloatConfig(CONFIG_STATS_LIMITS_PARRY) : value; + value = value < 0.0f ? 0.0f : value; } SetStatFloatValue(PLAYER_PARRY_PERCENTAGE, value); @@ -735,6 +747,9 @@ void Player::UpdateDodgePercentage() uint32 pclass = getClass()-1; float value = nondiminishing + (diminishing * dodge_cap[pclass] / (diminishing + dodge_cap[pclass] * m_diminishing_k[pclass])); + if (sWorld->getBoolConfig(CONFIG_STATS_LIMITS_ENABLE)) + value = value > sWorld->getFloatConfig(CONFIG_STATS_LIMITS_DODGE) ? sWorld->getFloatConfig(CONFIG_STATS_LIMITS_DODGE) : value; + value = value < 0.0f ? 0.0f : value; SetStatFloatValue(PLAYER_DODGE_PERCENTAGE, value); } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 9d2ee2eb2ba..645c14b8758 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1222,6 +1222,13 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_WINTERGRASP_NOBATTLETIME] = ConfigMgr::GetIntDefault("Wintergrasp.NoBattleTimer", 150); m_int_configs[CONFIG_WINTERGRASP_RESTART_AFTER_CRASH] = ConfigMgr::GetIntDefault("Wintergrasp.CrashRestartTimer", 10); + // Stats limits + m_bool_configs[CONFIG_STATS_LIMITS_ENABLE] = ConfigMgr::GetBoolDefault("Stats.Limits.Enable", false); + m_float_configs[CONFIG_STATS_LIMITS_DODGE] = ConfigMgr::GetFloatDefault("Stats.Limits.Dodge", 95.0f); + m_float_configs[CONFIG_STATS_LIMITS_PARRY] = ConfigMgr::GetFloatDefault("Stats.Limits.Parry", 95.0f); + m_float_configs[CONFIG_STATS_LIMITS_BLOCK] = ConfigMgr::GetFloatDefault("Stats.Limits.Block", 95.0f); + m_float_configs[CONFIG_STATS_LIMITS_CRIT] = ConfigMgr::GetFloatDefault("Stats.Limits.Crit", 95.0f); + // call ScriptMgr if we're reloading the configuration if (reload) sScriptMgr->OnConfigLoad(reload); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 984a1709ac8..12586ed4969 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -159,6 +159,7 @@ enum WorldBoolConfigs CONFIG_WINTERGRASP_ENABLE, CONFIG_UI_QUESTLEVELS_IN_DIALOGS, // Should we add quest levels to the title in the NPC dialogs? CONFIG_EVENT_ANNOUNCE, + CONFIG_STATS_LIMITS_ENABLE, BOOL_CONFIG_VALUE_COUNT }; @@ -175,6 +176,10 @@ enum WorldFloatConfigs CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS, CONFIG_THREAT_RADIUS, CONFIG_CHANCE_OF_GM_SURVEY, + CONFIG_STATS_LIMITS_DODGE, + CONFIG_STATS_LIMITS_PARRY, + CONFIG_STATS_LIMITS_BLOCK, + CONFIG_STATS_LIMITS_CRIT, FLOAT_CONFIG_VALUE_COUNT }; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index a9b09e5d94f..9577b3d841f 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -18,6 +18,7 @@ # GAME MASTER SETTINGS # VISIBILITY AND DISTANCES # SERVER RATES +# STATS LIMITS # AUTO BROADCAST # BATTLEGROUND CONFIG # BATTLEFIELD CONFIG @@ -2003,6 +2004,28 @@ Die.Command.Mode = 1 # ################################################################################################### +################################################################################################### +# STATS LIMITS +# +# Stats.Limits.Enable +# Description: Enable or disable stats system +# Default: 0 - Disabled + +Stats.Limits.Enable = 0 + +# +# Stats.Limit.[STAT] +# Description: Set percentage limit for dodge, parry, block and crit rating +# Default: 95.0 (95%) + +Stats.Limits.Dodge = 95.0 +Stats.Limits.Parry = 95.0 +Stats.Limits.Block = 95.0 +Stats.Limits.Crit = 95.0 + +# +################################################################################################### + ################################################################################################### # AUTO BROADCAST # -- cgit v1.2.3 From 5b17964e9d509772a609f0336667ef5d68ed45e4 Mon Sep 17 00:00:00 2001 From: Shauren Date: Wed, 5 Jun 2013 15:00:43 +0200 Subject: Core: Fixed compile without PCH --- src/server/game/Entities/Unit/StatSystem.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/server/game/Entities') diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 2dfe77287d4..3538188a234 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -24,6 +24,7 @@ #include "SpellAuras.h" #include "SpellAuraEffects.h" #include "SpellMgr.h" +#include "World.h" inline bool _ModifyUInt32(bool apply, uint32& baseValue, int32& amount) { -- cgit v1.2.3 From 88bbff2236d105bd17d7bc67bd915159c3e9a054 Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 7 Jun 2013 16:05:39 +0200 Subject: Core/Creatures * Refactored setting movement flags into separate method * Falling creatures are no longer treated as flying for movement flag setting purposes --- src/server/game/Entities/Creature/Creature.cpp | 100 ++++++++----------------- src/server/game/Entities/Creature/Creature.h | 3 + src/server/game/Entities/Unit/Unit.cpp | 5 ++ src/server/game/Entities/Unit/Unit.h | 1 + src/server/game/Movement/Spline/MoveSpline.h | 1 + 5 files changed, 40 insertions(+), 70 deletions(-) (limited to 'src/server/game/Entities') diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index b3deb7ae7de..4a2408b7f0a 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -438,27 +438,7 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData* data) ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); } - // Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc) - float ground = GetPositionZ(); - GetMap()->GetWaterOrGroundLevel(GetPositionX(), GetPositionY(), GetPositionZ(), &ground); - - bool isInAir = G3D::fuzzyGt(GetPositionZ(), ground + 0.05f) || G3D::fuzzyLt(GetPositionZ(), ground - 0.05f); // Can be underground too, prevent the falling - - if (cInfo->InhabitType & INHABIT_AIR && cInfo->InhabitType & INHABIT_GROUND && isInAir) - SetCanFly(true); - else if (cInfo->InhabitType & INHABIT_AIR && isInAir) - SetDisableGravity(true); - else - { - SetCanFly(false); - SetDisableGravity(false); - } - - if (cInfo->InhabitType & INHABIT_WATER && IsInWater()) - AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING); - else - RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING); - + UpdateMovementFlags(); return true; } @@ -472,33 +452,7 @@ void Creature::Update(uint32 diff) m_vehicleKit->Reset(); } - if (IsInWater()) - { - if (canSwim()) - AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING); - } - else - { - if (canWalk()) - RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING); - } - - // Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc) - float ground = GetPositionZ(); - GetMap()->GetWaterOrGroundLevel(GetPositionX(), GetPositionY(), GetPositionZ(), &ground); - - bool isInAir = G3D::fuzzyGt(GetPositionZ(), ground + 0.05f) || G3D::fuzzyLt(GetPositionZ(), ground - 0.05f); // Can be underground too, prevent the falling - CreatureTemplate const* cinfo = GetCreatureTemplate(); - - if (cinfo->InhabitType & INHABIT_AIR && cinfo->InhabitType & INHABIT_GROUND && isInAir) - SetCanFly(true); - else if (cinfo->InhabitType & INHABIT_AIR && isInAir) - SetDisableGravity(true); - else - { - SetCanFly(false); - SetDisableGravity(false); - } + UpdateMovementFlags(); switch (m_deathState) { @@ -1495,30 +1449,10 @@ void Creature::setDeathState(DeathState s) SetFullHealth(); SetLootRecipient(NULL); ResetPlayerDamageReq(); - CreatureTemplate const* cinfo = GetCreatureTemplate(); - SetWalk(true); - - // Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc) - float ground = GetPositionZ(); - GetMap()->GetWaterOrGroundLevel(GetPositionX(), GetPositionY(), GetPositionZ(), &ground); - bool isInAir = G3D::fuzzyGt(GetPositionZ(), ground + 0.05f) || G3D::fuzzyLt(GetPositionZ(), ground - 0.05f); // Can be underground too, prevent the falling - - if (cinfo->InhabitType & INHABIT_AIR && cinfo->InhabitType & INHABIT_GROUND && isInAir) - SetCanFly(true); - else if (cinfo->InhabitType & INHABIT_AIR && isInAir) - SetDisableGravity(true); - else - { - SetCanFly(false); - SetDisableGravity(false); - } - - if (cinfo->InhabitType & INHABIT_WATER && IsInWater()) - AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING); - else - RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING); + UpdateMovementFlags(); + CreatureTemplate const* cinfo = GetCreatureTemplate(); SetUInt32Value(UNIT_NPC_FLAGS, cinfo->npcflag); ClearUnitState(uint32(UNIT_STATE_ALL_STATE)); SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool)); @@ -2588,3 +2522,29 @@ Unit* Creature::SelectNearestHostileUnitInAggroRange(bool useLOS) const return target; } + +void Creature::UpdateMovementFlags() +{ + // Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc) + float ground = GetMap()->GetHeight(GetPositionX(), GetPositionY(), GetPositionZMinusOffset()); + + bool isInAir = !IsFalling() && (G3D::fuzzyGt(GetPositionZMinusOffset(), ground + 0.05f) || G3D::fuzzyLt(GetPositionZMinusOffset(), ground - 0.05f)); // Can be underground too, prevent the falling + + if (GetCreatureTemplate()->InhabitType & INHABIT_AIR && isInAir) + { + if (GetCreatureTemplate()->InhabitType & INHABIT_GROUND) + SetCanFly(true); + else + SetDisableGravity(true); + } + else + { + SetCanFly(false); + SetDisableGravity(false); + } + + if (GetCreatureTemplate()->InhabitType & INHABIT_WATER && IsInWater()) + AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING); + else + RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING); +} diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 6459b80a063..6b6edd7454f 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -520,6 +520,9 @@ class Creature : public Unit, public GridObject, public MapCreature bool HasSpell(uint32 spellID) const; bool UpdateEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL); + + void UpdateMovementFlags(); + bool UpdateStats(Stats stat); bool UpdateAllStats(); void UpdateResistances(uint32 school); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index b62b5124987..326f41b2e0e 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -17019,6 +17019,11 @@ void Unit::BuildMovementPacket(ByteBuffer *data) const *data << (float)m_movementInfo.splineElevation; } +bool Unit::IsFalling() const +{ + return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR) || movespline->isFalling(); +} + void Unit::SetCanFly(bool apply) { if (apply) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index c65f08ffa6f..707c42fe035 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2113,6 +2113,7 @@ class Unit : public WorldObject bool isTurning() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_TURNING); } virtual bool CanFly() const = 0; bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_DISABLE_GRAVITY); } + bool IsFalling() const; void SetCanFly(bool apply); void RewardRage(uint32 damage, uint32 weaponSpeedHitFactor, bool attacker); diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h index b18166ea615..a76c552079b 100644 --- a/src/server/game/Movement/Spline/MoveSpline.h +++ b/src/server/game/Movement/Spline/MoveSpline.h @@ -115,6 +115,7 @@ namespace Movement uint32 GetId() const { return m_Id; } bool Finalized() const { return splineflags.done; } bool isCyclic() const { return splineflags.cyclic; } + bool isFalling() const { return splineflags.falling; } const Vector3 FinalDestination() const { return Initialized() ? spline.getPoint(spline.last()) : Vector3(); } const Vector3 CurrentDestination() const { return Initialized() ? spline.getPoint(point_Idx+1) : Vector3(); } int32 currentPathIdx() const; -- cgit v1.2.3 From 5254e5ead1739853120a25a7933c720f19f26e7f Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 7 Jun 2013 17:50:39 +0200 Subject: Core/PacketIO: Send item create object blocks only to their owner --- src/server/game/Entities/Player/Player.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/server/game/Entities') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index ebd94b84079..5670f08c79f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4524,16 +4524,16 @@ Mail* Player::GetMail(uint32 id) void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const { - for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) + if (target == this) { - if (m_items[i] == NULL) - continue; + for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) + { + if (m_items[i] == NULL) + continue; - m_items[i]->BuildCreateUpdateBlockForPlayer(data, target); - } + m_items[i]->BuildCreateUpdateBlockForPlayer(data, target); + } - if (target == this) - { for (uint8 i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i) { if (m_items[i] == NULL) -- cgit v1.2.3 From cd24f8521c24932f6a1896926bd24408dcaac837 Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sat, 8 Jun 2013 20:51:39 +0200 Subject: Core/Gossip: Revert unlearn and dual spec gossip stuff in c238cae7d0733c76ee844d81e7c959627e5d711b --- src/server/game/Entities/Creature/Creature.cpp | 7 +++++++ src/server/game/Entities/Creature/Creature.h | 1 + src/server/game/Entities/Player/Player.cpp | 10 ++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src/server/game/Entities') diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 4a2408b7f0a..3727e19bc2d 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -857,6 +857,13 @@ bool Creature::isCanInteractWithBattleMaster(Player* player, bool msg) const return true; } +bool Creature::isCanTrainingAndResetTalentsOf(Player* player) const +{ + return player->getLevel() >= 10 + && GetCreatureTemplate()->trainer_type == TRAINER_TYPE_CLASS + && player->getClass() == GetCreatureTemplate()->trainer_class; +} + Player* Creature::GetLootRecipient() const { if (!m_lootRecipient) diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 6b6edd7454f..b3372fc8c56 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -483,6 +483,7 @@ class Creature : public Unit, public GridObject, public MapCreature /// @todo Rename these properly bool isCanInteractWithBattleMaster(Player* player, bool msg) const; + bool isCanTrainingAndResetTalentsOf(Player* player) const; bool canCreatureAttack(Unit const* victim, bool force = true) const; bool IsImmunedToSpell(SpellInfo const* spellInfo) const; // override Unit::IsImmunedToSpell bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; // override Unit::IsImmunedToSpellEffect diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 5670f08c79f..28213785911 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -14370,6 +14370,14 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool } break; } + case GOSSIP_OPTION_LEARNDUALSPEC: + if (!(GetSpecsCount() == 1 && creature->isCanTrainingAndResetTalentsOf(this) && !(getLevel() < sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL)))) + canTalk = false; + break; + case GOSSIP_OPTION_UNLEARNTALENTS: + if (!creature->isCanTrainingAndResetTalentsOf(this)) + canTalk = false; + break; case GOSSIP_OPTION_UNLEARNPETTALENTS: if (!GetPet() || GetPet()->getPetType() != HUNTER_PET || GetPet()->m_spells.size() <= 1 || creature->GetCreatureTemplate()->trainer_type != TRAINER_TYPE_PETS || creature->GetCreatureTemplate()->trainer_class != CLASS_HUNTER) canTalk = false; @@ -14390,8 +14398,6 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool canTalk = false; break; case GOSSIP_OPTION_TRAINER: - case GOSSIP_OPTION_LEARNDUALSPEC: - case GOSSIP_OPTION_UNLEARNTALENTS: case GOSSIP_OPTION_GOSSIP: case GOSSIP_OPTION_SPIRITGUIDE: case GOSSIP_OPTION_INNKEEPER: -- cgit v1.2.3 From ef15fe8ed28cb2d65574e8c5c755d39f8a06a994 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 11 Jun 2013 15:50:08 +0200 Subject: Core/Instances: Fixed a bug that caused switching group leader inside active instance to cause players not being saved when a boss was killed. Closes #5109 --- src/server/game/Entities/Player/Player.cpp | 4 +- src/server/game/Groups/Group.cpp | 44 +++++++++++----------- .../Database/Implementation/CharacterDatabase.cpp | 2 +- 3 files changed, 27 insertions(+), 23 deletions(-) (limited to 'src/server/game/Entities') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 28213785911..a7d37dd870f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -18698,7 +18698,9 @@ void Player::ConvertInstancesToGroup(Player* player, Group* group, bool switchLe { for (BoundInstancesMap::iterator itr = player->m_boundInstances[i].begin(); itr != player->m_boundInstances[i].end();) { - group->BindToInstance(itr->second.save, itr->second.perm, false); + if (!switchLeader || !group->GetBoundInstance(itr->second.save->GetDifficulty(), itr->first)) + group->BindToInstance(itr->second.save, itr->second.perm, false); + // permanent binds are not removed if (switchLeader && !itr->second.perm) { diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index c21cc9210dc..59da04f3673 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -615,30 +615,39 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod& method /*= GROUP_REMOV } } -void Group::ChangeLeader(uint64 guid) +void Group::ChangeLeader(uint64 newLeaderGuid) { - member_witerator slot = _getMemberWSlot(guid); + member_witerator slot = _getMemberWSlot(newLeaderGuid); if (slot == m_memberSlots.end()) return; - Player* player = ObjectAccessor::FindPlayer(slot->guid); + Player* newLeader = ObjectAccessor::FindPlayer(slot->guid); // Don't allow switching leader to offline players - if (!player) + if (!newLeader) return; - sScriptMgr->OnGroupChangeLeader(this, guid, m_leaderGuid); + sScriptMgr->OnGroupChangeLeader(this, newLeaderGuid, m_leaderGuid); if (!isBGGroup() && !isBFGroup()) { + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + // Remove the groups permanent instance bindings for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end();) { - if (itr->second.perm) + // Do not unbind saves of instances that already had map created (a newLeader entered) + // forcing a new instance with another leader requires group disbanding (confirmed on retail) + if (itr->second.perm && !sMapMgr->FindMap(itr->first, itr->second.save->GetInstanceId())) { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING); + stmt->setUInt32(0, m_dbStoreId); + stmt->setUInt32(1, itr->second.save->GetInstanceId()); + trans->Append(stmt); + itr->second.save->RemoveGroup(this); m_boundInstances[i].erase(itr++); } @@ -647,29 +656,22 @@ void Group::ChangeLeader(uint64 guid) } } - // Same in the database - - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING); - - stmt->setUInt32(0, m_dbStoreId); - stmt->setUInt32(1, player->GetGUIDLow()); - - CharacterDatabase.Execute(stmt); - // Copy the permanent binds from the new leader to the group - Player::ConvertInstancesToGroup(player, this, true); + Player::ConvertInstancesToGroup(newLeader, this, true); // Update the group leader - stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_LEADER); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_LEADER); - stmt->setUInt32(0, player->GetGUIDLow()); + stmt->setUInt32(0, newLeader->GetGUIDLow()); stmt->setUInt32(1, m_dbStoreId); - CharacterDatabase.Execute(stmt); + trans->Append(stmt); + + CharacterDatabase.CommitTransaction(trans); } - m_leaderGuid = player->GetGUID(); - m_leaderName = player->GetName(); + m_leaderGuid = newLeader->GetGUID(); + m_leaderName = newLeader->GetName(); ToggleGroupMemberFlag(slot, MEMBER_FLAG_ASSISTANT, false); WorldPacket data(SMSG_GROUP_SET_LEADER, m_leaderName.size()+1); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index 446f89aef4f..427ccfd5ebf 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -378,7 +378,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_INS_GROUP, "INSERT INTO groups (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raiddifficulty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_GROUP_MEMBER, "INSERT INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_GROUP_MEMBER, "DELETE FROM group_member WHERE memberGuid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING, "DELETE FROM group_instance WHERE guid = ? AND (permanent = 1 OR instance IN (SELECT instance FROM character_instance WHERE guid = ?))", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING, "DELETE FROM group_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_GROUP_LEADER, "UPDATE groups SET leaderGuid = ? WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_GROUP_TYPE, "UPDATE groups SET groupType = ? WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_GROUP_MEMBER_SUBGROUP, "UPDATE group_member SET subgroup = ? WHERE memberGuid = ?", CONNECTION_ASYNC); -- cgit v1.2.3 From 9ec22fffa00135cd776afebe2899bf54fb52f15f Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 11 Jun 2013 17:28:16 +0200 Subject: Core/Objects: Object scale will now also affect bounding radius and combat reach fields --- src/server/collision/Models/GameObjectModel.cpp | 2 +- src/server/game/Entities/Creature/Creature.cpp | 26 ++++++++++++++++++++--- src/server/game/Entities/Creature/Creature.h | 3 +++ src/server/game/Entities/Pet/Pet.cpp | 13 ++++++++++++ src/server/game/Entities/Pet/Pet.h | 2 ++ src/server/game/Entities/Player/Player.cpp | 8 ++----- src/server/game/Entities/Player/Player.h | 9 +++++++- src/server/game/Entities/Unit/Unit.cpp | 10 --------- src/server/game/Entities/Unit/Unit.h | 2 +- src/server/game/Events/GameEventMgr.cpp | 10 ++------- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 4 +++- src/server/scripts/Commands/cs_reset.cpp | 5 ----- 12 files changed, 58 insertions(+), 36 deletions(-) (limited to 'src/server/game/Entities') diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp index e166a860cd2..9db3d706fca 100644 --- a/src/server/collision/Models/GameObjectModel.cpp +++ b/src/server/collision/Models/GameObjectModel.cpp @@ -139,7 +139,7 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn if (Creature* c = const_cast(go).SummonCreature(24440, pos.x, pos.y, pos.z, 0, TEMPSUMMON_MANUAL_DESPAWN)) { c->setFaction(35); - c->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.1f); + c->SetObjectScale(0.1f); } } #endif diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 3727e19bc2d..9077e045cef 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -330,9 +330,6 @@ bool Creature::InitEntry(uint32 entry, uint32 /*team*/, const CreatureData* data SetName(normalInfo->Name); // at normal entry always - SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, minfo->bounding_radius); - SetFloatValue(UNIT_FIELD_COMBATREACH, minfo->combat_reach); - SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); SetSpeed(MOVE_WALK, cinfo->speed_walk); @@ -340,6 +337,7 @@ bool Creature::InitEntry(uint32 entry, uint32 /*team*/, const CreatureData* data SetSpeed(MOVE_SWIM, 1.0f); // using 1.0 rate SetSpeed(MOVE_FLIGHT, 1.0f); // using 1.0 rate + // Will set UNIT_FIELD_BOUNDINGRADIUS and UNIT_FIELD_COMBATREACH SetObjectScale(cinfo->scale); SetFloatValue(UNIT_FIELD_HOVERHEIGHT, cinfo->HoverHeight); @@ -2555,3 +2553,25 @@ void Creature::UpdateMovementFlags() else RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING); } + +void Creature::SetObjectScale(float scale) +{ + Unit::SetObjectScale(scale); + + if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(GetDisplayId())) + { + SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, minfo->bounding_radius * scale); + SetFloatValue(UNIT_FIELD_COMBATREACH, minfo->combat_reach * scale); + } +} + +void Creature::SetDisplayId(uint32 modelId) +{ + Unit::SetDisplayId(modelId); + + if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(modelId)) + { + SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, minfo->bounding_radius * GetFloatValue(OBJECT_FIELD_SCALE_X)); + SetFloatValue(UNIT_FIELD_COMBATREACH, minfo->combat_reach * GetFloatValue(OBJECT_FIELD_SCALE_X)); + } +} diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index b3372fc8c56..d96cbd0eb26 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -454,6 +454,9 @@ class Creature : public Unit, public GridObject, public MapCreature void AddToWorld(); void RemoveFromWorld(); + void SetObjectScale(float scale); + void SetDisplayId(uint32 modelId); + void DisappearAndDie(); bool Create(uint32 guidlow, Map* map, uint32 phaseMask, uint32 Entry, uint32 vehId, uint32 team, float x, float y, float z, float ang, const CreatureData* data = NULL); diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 0af3fab8434..f6693ba2260 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -2078,3 +2078,16 @@ Player* Pet::GetOwner() const { return Minion::GetOwner()->ToPlayer(); } + +void Pet::SetDisplayId(uint32 modelId) +{ + Guardian::SetDisplayId(modelId); + + if (!isControlled()) + return; + + if (Unit* owner = GetOwner()) + if (Player* player = owner->ToPlayer()) + if (owner->ToPlayer()->GetGroup()) + owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID); +} diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index c7e4e850ae3..e0afef2b8e3 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -46,6 +46,8 @@ class Pet : public Guardian void AddToWorld(); void RemoveFromWorld(); + void SetDisplayId(uint32 modelId); + PetType getPetType() const { return m_petType; } void setPetType(PetType type) { m_petType = type; } bool isControlled() const { return getPetType() == SUMMON_PET || getPetType() == HUNTER_PET; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a7d37dd870f..a6ec2371837 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -965,8 +965,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) uint8 powertype = cEntry->powerType; - SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE); - SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f); + SetObjectScale(1.0f); setFactionForRace(createInfo->Race); @@ -5125,8 +5124,6 @@ void Player::BuildPlayerRepop() StopMirrorTimers(); //disable timers(bars) - SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, float(1.0f)); //see radius of death player? - // set and clear other SetByteValue(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND); } @@ -16985,8 +16982,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) _LoadIntoDataField(fields[61].GetCString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE); _LoadIntoDataField(fields[64].GetCString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE*2); - SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE); - SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f); + SetObjectScale(1.0f); SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); // load achievements before anything else to prevent multiple gains for the same achievement/criteria on every loading (as loading does call UpdateAchievementCriteria) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 1c0fa4ea93d..b05a08446c0 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1063,7 +1063,7 @@ class Player : public Unit, public GridObject friend void Item::AddToUpdateQueueOf(Player* player); friend void Item::RemoveFromUpdateQueueOf(Player* player); public: - explicit Player (WorldSession* session); + explicit Player(WorldSession* session); ~Player(); void CleanupsBeforeDelete(bool finalCleanup = true); @@ -1071,6 +1071,13 @@ class Player : public Unit, public GridObject void AddToWorld(); void RemoveFromWorld(); + void SetObjectScale(float scale) + { + Unit::SetObjectScale(scale); + SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, scale * DEFAULT_WORLD_OBJECT_SIZE); + SetFloatValue(UNIT_FIELD_COMBATREACH, scale * DEFAULT_COMBAT_REACH); + } + bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0); bool TeleportTo(WorldLocation const &loc, uint32 options = 0); bool TeleportToBGEntryPoint(); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 326f41b2e0e..3995c9ed661 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -14512,16 +14512,6 @@ bool Unit::IsPolymorphed() const void Unit::SetDisplayId(uint32 modelId) { SetUInt32Value(UNIT_FIELD_DISPLAYID, modelId); - - if (GetTypeId() == TYPEID_UNIT && ToCreature()->isPet()) - { - Pet* pet = ToPet(); - if (!pet->isControlled()) - return; - Unit* owner = GetOwner(); - if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) - owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID); - } } void Unit::RestoreDisplayId() diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 707c42fe035..4b2d9ccd64a 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1921,7 +1921,7 @@ class Unit : public WorldObject void UpdateInterruptMask(); uint32 GetDisplayId() const { return GetUInt32Value(UNIT_FIELD_DISPLAYID); } - void SetDisplayId(uint32 modelId); + virtual void SetDisplayId(uint32 modelId); uint32 GetNativeDisplayId() const { return GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID); } void RestoreDisplayId(); void SetNativeDisplayId(uint32 modelId) { SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, modelId); } diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index 7213a807168..670eed672e6 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -1331,13 +1331,10 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate) creature->LoadEquipment(itr->second.equipment_id, true); if (itr->second.modelid > 0 && itr->second.modelid_prev != itr->second.modelid) { - CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(itr->second.modelid); - if (minfo) + if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(itr->second.modelid)) { creature->SetDisplayId(itr->second.modelid); creature->SetNativeDisplayId(itr->second.modelid); - creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, minfo->bounding_radius); - creature->SetFloatValue(UNIT_FIELD_COMBATREACH, minfo->combat_reach); } } } @@ -1346,13 +1343,10 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate) creature->LoadEquipment(itr->second.equipement_id_prev, true); if (itr->second.modelid_prev > 0 && itr->second.modelid_prev != itr->second.modelid) { - CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(itr->second.modelid_prev); - if (minfo) + if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(itr->second.modelid_prev)) { creature->SetDisplayId(itr->second.modelid_prev); creature->SetNativeDisplayId(itr->second.modelid_prev); - creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, minfo->bounding_radius); - creature->SetFloatValue(UNIT_FIELD_COMBATREACH, minfo->combat_reach); } } } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 0f1950bc860..6deea0da7fd 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2069,7 +2069,9 @@ void AuraEffect::HandleAuraModScale(AuraApplication const* aurApp, uint8 mode, b Unit* target = aurApp->GetTarget(); - target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X, (float)GetAmount(), apply); + float scale = target->GetFloatValue(OBJECT_FIELD_SCALE_X); + ApplyPercentModFloatVar(scale, float(GetAmount()), apply); + target->SetObjectScale(scale); } void AuraEffect::HandleAuraCloneCaster(AuraApplication const* aurApp, uint8 mode, bool apply) const diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp index b0f57a3f609..bfb3c8aeff1 100644 --- a/src/server/scripts/Commands/cs_reset.cpp +++ b/src/server/scripts/Commands/cs_reset.cpp @@ -102,9 +102,6 @@ public: if (!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT)) player->SetShapeshiftForm(FORM_NONE); - player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE); - player->SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH); - player->setFactionForRace(player->getRace()); player->SetUInt32Value(UNIT_FIELD_BYTES_0, ((player->getRace()) | (player->getClass() << 8) | (player->getGender() << 16) | (powerType << 24))); @@ -119,8 +116,6 @@ public: //-1 is default value player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); - - //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000); return true; } -- cgit v1.2.3