aboutsummaryrefslogtreecommitdiff
path: root/src/game/Player.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Player.cpp')
-rw-r--r--src/game/Player.cpp103
1 files changed, 79 insertions, 24 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 1a5775845b1..8b7bcdf8c06 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -566,7 +566,9 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_,
setFactionForRace(m_race);
- SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( race ) | ( class_ << 8 ) | ( gender << 16 ) | ( powertype << 24 ) ) );
+ uint32 RaceClassGender = ( race ) | ( class_ << 8 ) | ( gender << 16 );
+
+ SetUInt32Value(UNIT_FIELD_BYTES_0, ( RaceClassGender | ( powertype << 24 ) ) );
SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield);
SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 );
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE );
@@ -674,8 +676,10 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_,
SetPower(POWER_MANA,GetMaxPower(POWER_MANA));
}
+ // original spells
learnDefaultSpells(true);
+ // original action bar
std::list<uint16>::const_iterator action_itr[4];
for(int i=0; i<4; i++)
action_itr[i] = info->action[i].begin();
@@ -692,37 +696,59 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_,
++action_itr[i];
}
- for (PlayerCreateInfoItems::const_iterator item_id_itr = info->item.begin(); item_id_itr!=info->item.end(); ++item_id_itr++)
+ // original items
+ CharStartOutfitEntry const* oEntry = NULL;
+ for (uint32 i = 1; i < sCharStartOutfitStore.GetNumRows(); ++i)
{
- uint32 titem_id = item_id_itr->item_id;
- uint32 titem_amount = item_id_itr->item_amount;
-
- sLog.outDebug("STORAGE: Creating initial item, itemId = %u, count = %u",titem_id, titem_amount);
-
- // attempt equip
- uint16 eDest;
- uint8 msg = CanEquipNewItem( NULL_SLOT, eDest, titem_id, titem_amount, false );
- if( msg == EQUIP_ERR_OK )
+ if(CharStartOutfitEntry const* entry = sCharStartOutfitStore.LookupEntry(i))
{
- EquipNewItem( eDest, titem_id, titem_amount, true);
- AutoUnequipOffhandIfNeed();
- continue; // equipped, to next
+ if(entry->RaceClassGender == RaceClassGender)
+ {
+ oEntry = entry;
+ break;
+ }
}
+ }
- // attempt store
- ItemPosCountVec sDest;
- // store in main bag to simplify second pass (special bags can be not equipped yet at this moment)
- msg = CanStoreNewItem( INVENTORY_SLOT_BAG_0, NULL_SLOT, sDest, titem_id, titem_amount );
- if( msg == EQUIP_ERR_OK )
+ if(oEntry)
+ {
+ for(int j = 0; j < MAX_OUTFIT_ITEMS; ++j)
{
- StoreNewItem( sDest, titem_id, true, Item::GenerateItemRandomPropertyId(titem_id) );
- continue; // stored, to next
- }
+ if(oEntry->ItemId[j] <= 0)
+ continue;
+
+ uint32 item_id = oEntry->ItemId[j];
- // item can't be added
- sLog.outError("STORAGE: Can't equip or store initial item %u for race %u class %u , error msg = %u",titem_id,race,class_,msg);
+ ItemPrototype const* iProto = objmgr.GetItemPrototype(item_id);
+ if(!iProto)
+ {
+ sLog.outErrorDb("Initial item id %u (race %u class %u) from CharStartOutfit.dbc not listed in `item_template`, ignoring.",item_id,getRace(),getClass());
+ continue;
+ }
+
+ uint32 count = iProto->Stackable; // max stack by default (mostly 1)
+ if(iProto->Class==ITEM_CLASS_CONSUMABLE && iProto->SubClass==ITEM_SUBCLASS_FOOD)
+ {
+ switch(iProto->Spells[0].SpellCategory)
+ {
+ case 11: // food
+ if(iProto->Stackable > 4)
+ count = 4;
+ break;
+ case 59: // drink
+ if(iProto->Stackable > 2)
+ count = 2;
+ break;
+ }
+ }
+
+ StoreNewItemInBestSlot(item_id, count);
+ }
}
+ for (PlayerCreateInfoItems::const_iterator item_id_itr = info->item.begin(); item_id_itr!=info->item.end(); ++item_id_itr++)
+ StoreNewItemInBestSlot(item_id_itr->item_id, item_id_itr->item_amount);
+
// bags and main-hand weapon must equipped at this moment
// now second pass for not equipped (offhand weapon/shield if it attempt equipped before main-hand weapon)
// or ammo not equipped in special bag
@@ -761,6 +787,35 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_,
return true;
}
+bool Player::StoreNewItemInBestSlot(uint32 titem_id, uint32 titem_amount)
+{
+ sLog.outDebug("STORAGE: Creating initial item, itemId = %u, count = %u",titem_id, titem_amount);
+
+ // attempt equip
+ uint16 eDest;
+ uint8 msg = CanEquipNewItem( NULL_SLOT, eDest, titem_id, titem_amount, false );
+ if( msg == EQUIP_ERR_OK )
+ {
+ EquipNewItem( eDest, titem_id, titem_amount, true);
+ AutoUnequipOffhandIfNeed();
+ return true; // equipped
+ }
+
+ // attempt store
+ ItemPosCountVec sDest;
+ // store in main bag to simplify second pass (special bags can be not equipped yet at this moment)
+ msg = CanStoreNewItem( INVENTORY_SLOT_BAG_0, NULL_SLOT, sDest, titem_id, titem_amount );
+ if( msg == EQUIP_ERR_OK )
+ {
+ StoreNewItem( sDest, titem_id, true, Item::GenerateItemRandomPropertyId(titem_id) );
+ return true; // stored
+ }
+
+ // item can't be added
+ sLog.outError("STORAGE: Can't equip or store initial item %u for race %u class %u , error msg = %u",titem_id,getRace(),getClass(),msg);
+ return false;
+}
+
void Player::StartMirrorTimer(MirrorTimerType Type, uint32 MaxValue)
{
uint32 BreathRegen = (uint32)-1;