aboutsummaryrefslogtreecommitdiff
path: root/src/game/Creature.cpp
diff options
context:
space:
mode:
authorNeo2003 <none@none>2008-10-06 04:48:59 -0500
committerNeo2003 <none@none>2008-10-06 04:48:59 -0500
commit1fc5c0d6d7200048009f99c2cb4d3fd12858ed2f (patch)
tree58895d02973f2387143bc3d1c1e5ecf8a28984fc /src/game/Creature.cpp
parent010ed993e1a00246dd15df97a3ba6893410d2d3f (diff)
[svn] * Little fix in RandomMovementGenerator
* Updated to 6731 and 680 --HG-- branch : trunk rename : 6721-676 => 6731-680
Diffstat (limited to 'src/game/Creature.cpp')
-rw-r--r--src/game/Creature.cpp161
1 files changed, 127 insertions, 34 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index d0800c9b77f..555bb4db02a 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -62,15 +62,36 @@ TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
return NULL;
}
+bool VendorItemData::RemoveItem( uint32 item_id )
+{
+ for(VendorItemList::iterator i = m_items.begin(); i != m_items.end(); ++i )
+ {
+ if((*i)->item==item_id)
+ {
+ m_items.erase(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+VendorItem const* VendorItemData::FindItem(uint32 item_id) const
+{
+ for(VendorItemList::const_iterator i = m_items.begin(); i != m_items.end(); ++i )
+ if((*i)->item==item_id)
+ return *i;
+ return NULL;
+}
+
Creature::Creature() :
Unit(), i_AI(NULL),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
-m_itemsLoaded(false), m_lootMoney(0), m_lootRecipient(0),
+m_lootMoney(0), m_lootRecipient(0),
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),
m_gossipOptionLoaded(false),m_emoteState(0), m_isPet(false), m_isTotem(false),
m_regenTimer(2000), m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0),
m_AlreadyCallAssistence(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false),
-m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),m_creatureInfo(NULL)
+m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),m_creatureInfo(NULL), m_DBTableGuid(0)
{
m_valuesCount = UNIT_END;
@@ -87,7 +108,7 @@ Creature::~Creature()
{
CleanupsBeforeDelete();
- m_vendor_items.clear();
+ m_vendorItemCounts.clear();
delete i_AI;
i_AI = NULL;
@@ -503,6 +524,7 @@ bool Creature::Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, cons
m_corpseDelay = sWorld.getConfig(CONFIG_CORPSE_DECAY_NORMAL);
break;
}
+ LoadCreaturesAddon();
}
return bResult;
@@ -673,16 +695,16 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
cantalking=false;
break;
case GOSSIP_OPTION_VENDOR:
- // load vendor items if not yet
- LoadGoods();
-
- if(!GetItemCount())
+ {
+ VendorItemData const* vItems = GetVendorItems();
+ if(!vItems || vItems->Empty())
{
sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.",
GetGUIDLow(),GetEntry());
cantalking=false;
}
break;
+ }
case GOSSIP_OPTION_TRAINER:
if(!isCanTrainingOf(pPlayer,false))
cantalking=false;
@@ -934,6 +956,9 @@ uint32 Creature::GetGossipTextId(uint32 action, uint32 zoneid)
uint32 Creature::GetNpcTextId()
{
+ if (!m_DBTableGuid)
+ return DEFAULT_GOSSIP_MESSAGE;
+
if(uint32 pos = objmgr.GetNpcGossip(m_DBTableGuid))
return pos;
@@ -1046,6 +1071,8 @@ void Creature::SaveToDB()
void Creature::SaveToDB(uint32 mapid, uint8 spawnMask)
{
// update in loaded data
+ if (!m_DBTableGuid)
+ m_DBTableGuid = GetGUIDLow();
CreatureData& data = objmgr.NewOrExistCreatureData(m_DBTableGuid);
uint32 displayId = GetNativeDisplayId();
@@ -1237,7 +1264,6 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const
Object::_Create(guidlow, Entry, HIGHGUID_UNIT);
- m_DBTableGuid = guidlow;
if(!UpdateEntry(Entry, team, data))
return false;
@@ -1263,7 +1289,7 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
return false;
}
- uint32 stored_guid = guid;
+ m_DBTableGuid = guid;
if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT);
uint16 team = 0;
@@ -1278,9 +1304,6 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
return false;
}
- m_DBTableGuid = stored_guid;
- LoadCreaturesAddon();
-
m_respawnradius = data->spawndist;
m_respawnDelay = data->spawntimesecs;
@@ -1346,24 +1369,6 @@ void Creature::LoadEquipment(uint32 equip_entry, bool force)
}
}
-void Creature::LoadGoods()
-{
- // already loaded;
- if(m_itemsLoaded)
- return;
-
- m_vendor_items.clear();
-
- VendorItemList const* vList = objmgr.GetNpcVendorItemList(GetEntry());
- if(!vList)
- return;
-
- for (VendorItemList::const_iterator _item_iter = vList->begin(); _item_iter != vList->end(); ++_item_iter)
- AddItem( (*_item_iter)->item, (*_item_iter)->maxcount, (*_item_iter)->incrtime, (*_item_iter)->ExtendedCost);
-
- m_itemsLoaded = true;
-}
-
bool Creature::hasQuest(uint32 quest_id) const
{
QuestRelations const& qr = objmgr.mCreatureQuestRelations;
@@ -1388,6 +1393,12 @@ bool Creature::hasInvolvedQuest(uint32 quest_id) const
void Creature::DeleteFromDB()
{
+ if (!m_DBTableGuid)
+ {
+ sLog.outDebug("Trying to delete not saved creature!");
+ return;
+ }
+
objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0);
objmgr.DeleteCreatureData(m_DBTableGuid);
@@ -1494,7 +1505,8 @@ void Creature::Respawn()
if(getDeathState()==DEAD)
{
- objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0);
+ if (m_DBTableGuid)
+ objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0);
m_respawnTime = time(NULL); // respawn at next tick
}
}
@@ -1716,7 +1728,7 @@ void Creature::CallAssistence()
void Creature::SaveRespawnTime()
{
- if(isPet())
+ if(isPet() || !m_DBTableGuid)
return;
if(m_respawnTime > time(NULL)) // dead (no corpse)
@@ -1752,8 +1764,11 @@ bool Creature::IsOutOfThreatArea(Unit* pVictim) const
CreatureDataAddon const* Creature::GetCreatureAddon() const
{
- if(CreatureDataAddon const* addon = ObjectMgr::GetCreatureAddon(m_DBTableGuid))
- return addon;
+ if (m_DBTableGuid)
+ {
+ if(CreatureDataAddon const* addon = ObjectMgr::GetCreatureAddon(m_DBTableGuid))
+ return addon;
+ }
// dependent from heroic mode entry
return ObjectMgr::GetCreatureTemplateAddon(GetCreatureInfo()->Entry);
@@ -1956,6 +1971,84 @@ char const* Creature::GetScriptName() const
return ObjectMgr::GetCreatureTemplate(GetEntry())->ScriptName;
}
+
+VendorItemData const* Creature::GetVendorItems() const
+{
+ return objmgr.GetNpcVendorItemList(GetEntry());
+}
+
+uint32 Creature::GetVendorItemCurrentCount(VendorItem const* vItem)
+{
+ if(!vItem->maxcount)
+ return vItem->maxcount;
+
+ VendorItemCounts::iterator itr = m_vendorItemCounts.begin();
+ for(; itr != m_vendorItemCounts.end(); ++itr)
+ if(itr->itemId==vItem->item)
+ break;
+
+ if(itr == m_vendorItemCounts.end())
+ return vItem->maxcount;
+
+ VendorItemCount* vCount = &*itr;
+
+ time_t ptime = time(NULL);
+
+ if( vCount->lastIncrementTime + vItem->incrtime <= ptime )
+ {
+ ItemPrototype const* pProto = objmgr.GetItemPrototype(vItem->item);
+
+ uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime);
+ if((vCount->count + diff * pProto->BuyCount) >= vItem->maxcount )
+ {
+ m_vendorItemCounts.erase(itr);
+ return vItem->maxcount;
+ }
+
+ vCount->count += diff * pProto->BuyCount;
+ vCount->lastIncrementTime = ptime;
+ }
+
+ return vCount->count;
+}
+
+uint32 Creature::UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count)
+{
+ if(!vItem->maxcount)
+ return 0;
+
+ VendorItemCounts::iterator itr = m_vendorItemCounts.begin();
+ for(; itr != m_vendorItemCounts.end(); ++itr)
+ if(itr->itemId==vItem->item)
+ break;
+
+ if(itr == m_vendorItemCounts.end())
+ {
+ uint32 new_count = vItem->maxcount > used_count ? vItem->maxcount-used_count : 0;
+ m_vendorItemCounts.push_back(VendorItemCount(vItem->item,new_count));
+ return new_count;
+ }
+
+ VendorItemCount* vCount = &*itr;
+
+ time_t ptime = time(NULL);
+
+ if( vCount->lastIncrementTime + vItem->incrtime <= ptime )
+ {
+ ItemPrototype const* pProto = objmgr.GetItemPrototype(vItem->item);
+
+ uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime);
+ if((vCount->count + diff * pProto->BuyCount) < vItem->maxcount )
+ vCount->count += diff * pProto->BuyCount;
+ else
+ vCount->count = vItem->maxcount;
+ }
+
+ vCount->count = vCount->count > used_count ? vCount->count-used_count : 0;
+ vCount->lastIncrementTime = ptime;
+ return vCount->count;
+}
+
TrainerSpellData const* Creature::GetTrainerSpells() const
{
return objmgr.GetNpcTrainerSpells(GetEntry());