diff options
author | silinoron <none@none> | 2010-08-24 15:04:34 -0700 |
---|---|---|
committer | silinoron <none@none> | 2010-08-24 15:04:34 -0700 |
commit | aaaeecc916cf567877fbf835fb9e805f5227e3f6 (patch) | |
tree | 701d747297f9da0437237405f3a546020e3fbbb4 | |
parent | c0dda8b492d073472f1a4de9641b882ac6b90211 (diff) |
Add support for vehicle scaling based on item level.
Requires database data.
Fixes issue #2754
--HG--
branch : trunk
-rw-r--r-- | sql/base/world_database.sql | 25 | ||||
-rw-r--r-- | sql/updates/9578_world_vehicle_scaling_info.sql | 7 | ||||
-rw-r--r-- | src/server/game/Entities/Item/ItemPrototype.h | 23 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 20 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/SocialMgr.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Vehicle/Vehicle.cpp | 28 | ||||
-rw-r--r-- | src/server/game/Entities/Vehicle/Vehicle.h | 9 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 45 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 10 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 3 |
11 files changed, 151 insertions, 23 deletions
diff --git a/sql/base/world_database.sql b/sql/base/world_database.sql index 5857baec290..7c9b38ecdb4 100644 --- a/sql/base/world_database.sql +++ b/sql/base/world_database.sql @@ -15801,6 +15801,31 @@ LOCK TABLES `vehicle_accessory` WRITE; /*!40000 ALTER TABLE `vehicle_accessory` DISABLE KEYS */; /*!40000 ALTER TABLE `vehicle_accessory` ENABLE KEYS */; UNLOCK TABLES; + +-- +-- Table structure for table `vehicle_scaling_info` +-- + +DROP TABLE IF EXISTS `vehicle_scaling_info`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `vehicle_scaling_info` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `baseItemLevel` float NOT NULL default '0', + `scalingFactor` float NOT NULL default '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `vehicle_scaling_info` +-- + +LOCK TABLES `vehicle_scaling_info` WRITE; +/*!40000 ALTER TABLE `vehicle_scaling_info` DISABLE KEYS */; +/*!40000 ALTER TABLE `vehicle_scaling_info` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `version` -- diff --git a/sql/updates/9578_world_vehicle_scaling_info.sql b/sql/updates/9578_world_vehicle_scaling_info.sql new file mode 100644 index 00000000000..88eabb88cb0 --- /dev/null +++ b/sql/updates/9578_world_vehicle_scaling_info.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS `vehicle_scaling_info`; +CREATE TABLE `vehicle_scaling_info` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `baseItemLevel` float NOT NULL default '0', + `scalingFactor` float NOT NULL default '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED; diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h index 5941aea792f..ecdbbe7cafe 100644 --- a/src/server/game/Entities/Item/ItemPrototype.h +++ b/src/server/game/Entities/Item/ItemPrototype.h @@ -703,6 +703,29 @@ struct ItemPrototype return 0; } + float GetItemLevelIncludingQuality() const + { + float itemLevel = (float)ItemLevel; + switch (Quality) + { + case ITEM_QUALITY_POOR: + case ITEM_QUALITY_NORMAL: + case ITEM_QUALITY_UNCOMMON: + case ITEM_QUALITY_ARTIFACT: + case ITEM_QUALITY_HEIRLOOM: + itemLevel -= 13; // leaving this as a separate statement since we do not know the real behavior in this case + break; + case ITEM_QUALITY_RARE: + itemLevel -= 13; + break; + case ITEM_QUALITY_EPIC: + case ITEM_QUALITY_LEGENDARY: + default: + break; + } + return itemLevel; + } + bool IsPotion() const { return Class == ITEM_CLASS_CONSUMABLE && SubClass == ITEM_SUBCLASS_POTION; } bool IsWeaponVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT; } bool IsArmorVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 775489c2266..978078e5b85 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -13577,22 +13577,6 @@ void Player::PrepareGossipMenu(WorldObject *pSource, uint32 menuId, bool showQue pMenu->GetGossipMenu().AddGossipMenuItemData(itr->second.action_menu_id, itr->second.action_poi_id, itr->second.action_script_id); } } - - // some gossips aren't handled in normal way ... so we need to do it this way .. TODO: handle it in normal way ;-) - /*if (pMenu->Empty()) - { - if (pCreature->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_TRAINER)) - { - // output error message if need - pCreature->isCanTrainingOf(this, true); - } - - if (pCreature->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_BATTLEMASTER)) - { - // output error message if need - pCreature->isCanInteractWithBattleMaster(this, true); - } - }*/ } void Player::SendPreparedGossip(WorldObject *pSource) @@ -24137,7 +24121,7 @@ void Player::_LoadRandomBGStatus(QueryResult_AutoPtr result) float Player::GetAverageItemLevel() { - uint32 sum = 0; + float sum = 0; uint32 count = 0; for (int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i) @@ -24147,7 +24131,7 @@ float Player::GetAverageItemLevel() continue; if (m_items[i] && m_items[i]->GetProto()) - sum += m_items[i]->GetProto()->ItemLevel; + sum += m_items[i]->GetProto()->GetItemLevelIncludingQuality(); count++; } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 5e9a89d31d6..1f35aed6799 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -238,7 +238,7 @@ typedef std::list<PlayerCreateInfoAction> PlayerCreateInfoActions; struct PlayerInfo { - // existence checked by displayId != 0 // existence checked by displayId != 0 + // existence checked by displayId != 0 PlayerInfo() : displayId_m(0),displayId_f(0),levelInfo(NULL) { } diff --git a/src/server/game/Entities/Player/SocialMgr.h b/src/server/game/Entities/Player/SocialMgr.h index 30789ca0e02..4ac6154a3c1 100644 --- a/src/server/game/Entities/Player/SocialMgr.h +++ b/src/server/game/Entities/Player/SocialMgr.h @@ -44,7 +44,7 @@ enum SocialFlag SOCIAL_FLAG_FRIEND = 0x01, SOCIAL_FLAG_IGNORED = 0x02, SOCIAL_FLAG_MUTED = 0x04, // guessed - SOCIAL_FLAG_RAF = 0x08 // Recruit A Friend + SOCIAL_FLAG_UNK = 0x08 // Unknown - does not appear to be RaF }; struct FriendInfo diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 58036eb454b..4cc20680cd9 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -27,7 +27,7 @@ #include "CreatureAI.h" #include "ZoneScript.h" -Vehicle::Vehicle(Unit *unit, VehicleEntry const *vehInfo) : me(unit), m_vehicleInfo(vehInfo), m_usableSeatNum(0) +Vehicle::Vehicle(Unit *unit, VehicleEntry const *vehInfo) : me(unit), m_vehicleInfo(vehInfo), m_usableSeatNum(0), m_bonusHP(0) { for (uint32 i = 0; i < 8; ++i) { @@ -306,8 +306,6 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId) if (seat->second.seatInfo->m_flags && !(seat->second.seatInfo->m_flags & 0x400)) unit->addUnitState(UNIT_STAT_ONVEHICLE); - //SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); - unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); VehicleSeatEntry const *veSeat = seat->second.seatInfo; unit->m_movementInfo.t_pos.m_positionX = veSeat->m_attachmentOffsetX; @@ -320,9 +318,24 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId) if (me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->m_flags & 0x800) // not right + { if (!me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE)) ASSERT(false); + if (VehicleScalingInfo const *scalingInfo = sObjectMgr.GetVehicleScalingInfo(m_vehicleInfo->m_ID)) + { + Player *plr = unit->ToPlayer(); + float averageItemLevel = plr->GetAverageItemLevel(); + if (averageItemLevel < scalingInfo->baseItemLevel) + averageItemLevel = scalingInfo->baseItemLevel; + averageItemLevel -= scalingInfo->baseItemLevel; + + m_bonusHP = uint32(me->GetMaxHealth() * (averageItemLevel * scalingInfo->scalingFactor)); + me->SetMaxHealth(me->GetMaxHealth() + m_bonusHP); + me->SetHealth(me->GetHealth() + m_bonusHP); + } + } + if (me->IsInWorld()) { unit->SendMonsterMoveTransport(me); @@ -377,8 +390,17 @@ void Vehicle::RemovePassenger(Unit *unit) if (me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->m_flags & 0x800) + { me->RemoveCharmedBy(unit); + if (m_bonusHP) + { + me->SetHealth(me->GetHealth() - m_bonusHP); + me->SetMaxHealth(me->GetMaxHealth() - m_bonusHP); + m_bonusHP = 0; + } + } + if (me->GetTypeId() == TYPEID_UNIT && me->ToCreature()->IsAIEnabled) me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, false); diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index 339ab1ad188..93464b3699e 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -46,8 +46,16 @@ struct VehicleAccessory uint32 bMinion; }; +struct VehicleScalingInfo +{ + uint32 ID; + float baseItemLevel; + float scalingFactor; +}; + typedef std::vector<VehicleAccessory> VehicleAccessoryList; typedef std::map<uint32, VehicleAccessoryList> VehicleAccessoryMap; +typedef std::map<uint32, VehicleScalingInfo> VehicleScalingMap; typedef std::map<int8, VehicleSeat> SeatMap; @@ -82,6 +90,7 @@ class Vehicle Unit *me; VehicleEntry const *m_vehicleInfo; uint32 m_usableSeatNum; + uint32 m_bonusHP; void InstallAccessory(uint32 entry, int8 seatId, bool minion = true); }; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 4ea4b1ca033..80dfedc357d 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2647,6 +2647,51 @@ void ObjectMgr::LoadVehicleAccessories() sLog.outString(">> Loaded %u Vehicle Accessories", count); } +void ObjectMgr::LoadVehicleScaling() +{ + m_VehicleScalingMap.clear(); // needed for reload case + + uint32 count = 0; + + QueryResult_AutoPtr result = WorldDatabase.Query("SELECT `entry`,`baseItemLevel`,`scalingFactor` FROM `vehicle_scaling_info`"); + + if (!result) + { + barGoLink bar(1); + bar.step(); + sLog.outString(); + sLog.outErrorDb(">> Loaded 0 vehicle scaling entries. DB table `vehicle_scaling_info` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 vehicleEntry = fields[0].GetUInt32(); + float baseItemLevel = fields[1].GetFloat(); + float scalingFactor = fields[2].GetFloat(); + + if (!sVehicleStore.LookupEntry(vehicleEntry)) + { + sLog.outErrorDb("Table `vehicle_scaling_info`: vehicle entry %u does not exist.", vehicleEntry); + continue; + } + + m_VehicleScalingMap[vehicleEntry].ID = vehicleEntry; + m_VehicleScalingMap[vehicleEntry].baseItemLevel = baseItemLevel; + m_VehicleScalingMap[vehicleEntry].scalingFactor = scalingFactor; + + ++count; + } while (result->NextRow()); + + sLog.outString(); + sLog.outString(">> Loaded %u vehicle scaling entries.", count); +} + void ObjectMgr::LoadPetLevelInfo() { // Loading levels data diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 4394280625b..46b10e1b171 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -599,6 +599,14 @@ class ObjectMgr return NULL; } + VehicleScalingInfo const* GetVehicleScalingInfo(uint32 vehicleEntry) const + { + VehicleScalingMap::const_iterator itr = m_VehicleScalingMap.find(vehicleEntry); + if (itr != m_VehicleScalingMap.end()) + return &itr->second; + return NULL; + } + void LoadGuilds(); void LoadArenaTeams(); void LoadGroups(); @@ -665,6 +673,7 @@ class ObjectMgr void LoadInstanceTemplate(); void LoadMailLevelRewards(); void LoadVehicleAccessories(); + void LoadVehicleScaling(); void LoadGossipText(); @@ -1056,6 +1065,7 @@ class ObjectMgr ItemRequiredTargetMap m_ItemRequiredTarget; VehicleAccessoryMap m_VehicleAccessoryMap; + VehicleScalingMap m_VehicleScalingMap; typedef std::vector<LocaleConstant> LocalForIndex; LocalForIndex m_LocalForIndex; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 0927794122b..64d4fd02c7d 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1359,6 +1359,9 @@ void World::SetInitialWorldSettings() sLog.outString("Loading Creature templates..."); sObjectMgr.LoadCreatureTemplates(); + sLog.outString("Loading Vehicle scaling information..."); + sObjectMgr.LoadVehicleScaling(); + sLog.outString("Loading Reputation Reward Rates..."); sObjectMgr.LoadReputationRewardRate(); |