/* * Ascent MMORPG Server * Copyright (C) 2005-2007 Ascent Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "StdAfx.h" /** Table formats converted to strings */ const char * gItemPrototypeFormat = "uuuussssuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuffuffuffuffuffuuuuuuuuuufuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuusuuuuuuuuuuuuuuuuuuuuuuuuuuu"; const char * gCreatureNameFormat = "ussuuuuuuuffcc"; const char * gGameObjectNameFormat = "uuusuuuuuuuuuuuuuuuuuuuuuuuu"; const char * gCreatureProtoFormat = "uuuuuuufuuffuffuuuuuuuuuuuuuuuuuuffsuuuu"; const char * gAreaTriggerFormat = "uuuusffffuu"; const char * gItemPageFormat = "usu"; const char * gNpcTextFormat = "ufssuuuuuuufssuuuuuuufssuuuuuuufssuuuuuuufssuuuuuuufssuuuuuuufssuuuuuuufssuuuuuuu"; const char * gQuestFormat = "uuuuuuuuuuuuuuuuuussssssssssuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu"; const char * gSpellExtraFormat = "uuuu"; const char * gGraveyardFormat = "uffffuuuux"; const char * gTeleportCoordFormat = "uxufffx"; const char * gPvPAreaFormat = "ush"; const char * gFishingFormat = "uuu"; const char * gWorldMapInfoFormat = "uuuuufffusuuuuu"; const char * gZoneGuardsFormat = "uuu"; /** SQLStorage symbols */ SERVER_DECL SQLStorage > ItemPrototypeStorage; SERVER_DECL SQLStorage > CreatureNameStorage; SERVER_DECL SQLStorage > GameObjectNameStorage; SERVER_DECL SQLStorage > CreatureProtoStorage; SERVER_DECL SQLStorage > AreaTriggerStorage; SERVER_DECL SQLStorage > ItemPageStorage; SERVER_DECL SQLStorage > QuestStorage; SERVER_DECL SQLStorage > NpcTextStorage; SERVER_DECL SQLStorage > SpellExtraStorage; SERVER_DECL SQLStorage > GraveyardStorage; SERVER_DECL SQLStorage > TeleportCoordStorage; SERVER_DECL SQLStorage > FishingZoneStorage; SERVER_DECL SQLStorage > WorldMapInfoStorage; SERVER_DECL SQLStorage > ZoneGuardStorage; void ObjectMgr::LoadExtraCreatureProtoStuff() { { StorageContainerIterator * itr = CreatureProtoStorage.MakeIterator(); CreatureProto * cn; while(!itr->AtEnd()) { cn = itr->Get(); string auras = itr->Get()->aura_string; vector aurs = StrSplit(auras, " "); for(vector::iterator it = aurs.begin(); it != aurs.end(); ++it) { uint32 id = atol((*it).c_str()); if(id) itr->Get()->start_auras.insert( id ); } if(!itr->Get()->MinHealth) itr->Get()->MinHealth = 1; if(!itr->Get()->MaxHealth) itr->Get()->MaxHealth = 1; cn->m_canFlee = cn->m_canRangedAttack = cn->m_canCallForHelp = false; cn->m_fleeHealth = 0.0f; // please.... m_fleeDuration is a uint32... //cn->m_fleeDuration = 0.0f; cn->m_fleeDuration = 0; if(!itr->Inc()) break; } itr->Destruct(); } { StorageContainerIterator * itr = CreatureNameStorage.MakeIterator(); CreatureInfo * ci; while(!itr->AtEnd()) { ci = itr->Get(); ci->lowercase_name = string(ci->Name); for(uint32 j = 0; j < ci->lowercase_name.length(); ++j) ci->lowercase_name[j] = tolower(ci->lowercase_name[j]); // Darvaleo 2008/08/15 - Copied lowercase conversion logic from ItemPrototype task if(!itr->Inc()) break; } itr->Destruct(); } // Load AI Agents QueryResult * result = WorldDatabase.Query( "SELECT * FROM ai_agents" ); CreatureProto * cn; if( !result ) return; AI_Spell *sp; uint32 entry; do { Field *fields = result->Fetch(); entry = fields[0].GetUInt32(); cn = CreatureProtoStorage.LookupEntry(entry); if(!cn) continue; sp = new AI_Spell; sp->entryId = fields[0].GetUInt32(); sp->agent = fields[1].GetUInt16(); sp->procChance = fields[3].GetUInt32(); //sp->procCountDB = fields[4].GetUInt32(); sp->spell = ((FastIndexedDataStore*)SpellStore::getSingletonPtr())->LookupEntryForced(fields[5].GetUInt32()); sp->spellType = fields[6].GetUInt32(); sp->spelltargetType = fields[7].GetUInt32(); sp->cooldown = fields[8].GetFloat(); sp->floatMisc1 = fields[9].GetFloat(); /* if (!sp->procCountDB) sp->procCount = uint32(-1); else sp->procCount = sp->procCountDB;*/ sp->Misc2 = fields[10].GetUInt32(); if(sp->agent == AGENT_SPELL) { if(!sp->spell) { //printf("SpellId %u in ai_agent for %u is invalid.\n", (unsigned int)fields[5].GetUInt32(), (unsigned int)sp->entryId); delete sp; continue; } if(sp->spell->Effect[0] == SPELL_EFFECT_LEARN_SPELL || sp->spell->Effect[1] == SPELL_EFFECT_LEARN_SPELL || sp->spell->Effect[2] == SPELL_EFFECT_LEARN_SPELL) { //printf("Teaching spell %u in ai_agent for %u\n", (unsigned int)fields[5].GetUInt32(), (unsigned int)sp->entryId); delete sp; continue; } sp->minrange = GetMinRange(sSpellRange.LookupEntry(sp->spell->rangeIndex)); sp->maxrange = GetMaxRange(sSpellRange.LookupEntry(sp->spell->rangeIndex)); //omg the poor darling has no clue about making ai_agents if(sp->cooldown==-1) { //now this will not be exact cooldown but maybe a bigger one to not make him spam spells to often int cooldown; SpellDuration *sd=sSpellDuration.LookupEntry(sp->spell->DurationIndex); int Dur=0; int Casttime=0;//most of the time 0 int RecoveryTime=sp->spell->RecoveryTime; if(sp->spell->DurationIndex) Dur =::GetDuration(sd); Casttime=GetCastTime(sCastTime.LookupEntry(sp->spell->CastingTimeIndex)); cooldown=Dur+Casttime+RecoveryTime; if(cooldown<0) sp->cooldown=0x00FFFFFF;//huge value that should not loop while adding some timestamp to it else sp->cooldown=cooldown; } /* //now apply the morron filter if(sp->procChance==0) { //printf("SpellId %u in ai_agent for %u is invalid.\n", (unsigned int)fields[5].GetUInt32(), (unsigned int)sp->entryId); delete sp; continue; } if(sp->spellType==0) { //right now only these 2 are used if(IsBeneficSpell(sp->spell)) sp->spellType==STYPE_HEAL; else sp->spellType==STYPE_BUFF; } if(sp->spelltargetType==0) sp->spelltargetType = RecommandAISpellTargetType(sp->spell); */ } if(sp->agent == AGENT_RANGED) { cn->m_canRangedAttack = true; delete sp; } else if(sp->agent == AGENT_FLEE) { cn->m_canFlee = true; if(sp->floatMisc1) cn->m_canFlee = sp->floatMisc1; else cn->m_fleeHealth = 0.2f; if(sp->Misc2) cn->m_fleeDuration = sp->Misc2; else cn->m_fleeDuration = 10000; delete sp; } else if(sp->agent == AGENT_CALLFORHELP) { cn->m_canCallForHelp = true; if(sp->floatMisc1) cn->m_callForHelpHealth = 0.2f; delete sp; } else { cn->spells.push_back(sp); } } while( result->NextRow() ); delete result; } void ObjectMgr::LoadExtraItemStuff() { StorageContainerIterator * itr = ItemPrototypeStorage.MakeIterator(); ItemPrototype * pItemPrototype; while(!itr->AtEnd()) { pItemPrototype = itr->Get(); if(pItemPrototype->ItemSet > 0) { ItemSetContentMap::iterator itr = mItemSets.find(pItemPrototype->ItemSet); std::list* l; if(itr == mItemSets.end()) { l = new std::list; mItemSets.insert( ItemSetContentMap::value_type( pItemPrototype->ItemSet, l) ); } else { l = itr->second; } l->push_back(pItemPrototype); } // lowercase name, used for searches pItemPrototype->lowercase_name = pItemPrototype->Name1; for(uint32 j = 0; j < pItemPrototype->lowercase_name.length(); ++j) pItemPrototype->lowercase_name[j] = tolower(pItemPrototype->lowercase_name[j]); if(!itr->Inc()) break; } itr->Destruct(); } #define make_task(storage, itype, storagetype, tablename, format) tl.AddTask( new Task( \ new CallbackP2< SQLStorage< itype, storagetype< itype > >, const char *, const char *> \ (&storage, &SQLStorage< itype, storagetype< itype > >::Load, tablename, format) ) ) void Storage_FillTaskList(TaskList & tl) { make_task(ItemPrototypeStorage, ItemPrototype, ArrayStorageContainer, "items", gItemPrototypeFormat); make_task(CreatureNameStorage, CreatureInfo, HashMapStorageContainer, "creature_names", gCreatureNameFormat); make_task(GameObjectNameStorage, GameObjectInfo, HashMapStorageContainer, "gameobject_names", gGameObjectNameFormat); make_task(CreatureProtoStorage, CreatureProto, HashMapStorageContainer, "creature_proto", gCreatureProtoFormat); make_task(AreaTriggerStorage, AreaTrigger, HashMapStorageContainer, "areatriggers", gAreaTriggerFormat); make_task(ItemPageStorage, ItemPage, HashMapStorageContainer, "itempages", gItemPageFormat); make_task(QuestStorage, Quest, HashMapStorageContainer, "quests", gQuestFormat); make_task(SpellExtraStorage, SpellExtraInfo, HashMapStorageContainer, "spellextra", gSpellExtraFormat); make_task(GraveyardStorage, GraveyardTeleport, HashMapStorageContainer, "graveyards", gGraveyardFormat); make_task(TeleportCoordStorage, TeleportCoords, HashMapStorageContainer, "teleport_coords", gTeleportCoordFormat); make_task(FishingZoneStorage, FishingZoneEntry, HashMapStorageContainer, "fishing", gFishingFormat); make_task(NpcTextStorage, GossipText, HashMapStorageContainer, "npc_text", gNpcTextFormat); make_task(WorldMapInfoStorage, MapInfo, ArrayStorageContainer, "worldmap_info", gWorldMapInfoFormat); make_task(ZoneGuardStorage, ZoneGuardEntry, HashMapStorageContainer, "zoneguards", gZoneGuardsFormat); } void Storage_Cleanup() { { StorageContainerIterator * itr = CreatureProtoStorage.MakeIterator(); CreatureProto * p; while(!itr->AtEnd()) { p = itr->Get(); for(list::iterator it = p->spells.begin(); it != p->spells.end(); ++it) delete (*it); p->spells.clear(); p->start_auras.clear(); if(!itr->Inc()) break; } itr->Destruct(); } ItemPrototypeStorage.Cleanup(); CreatureNameStorage.Cleanup(); GameObjectNameStorage.Cleanup(); CreatureProtoStorage.Cleanup(); AreaTriggerStorage.Cleanup(); ItemPageStorage.Cleanup(); QuestStorage.Cleanup(); SpellExtraStorage.Cleanup(); GraveyardStorage.Cleanup(); TeleportCoordStorage.Cleanup(); FishingZoneStorage.Cleanup(); NpcTextStorage.Cleanup(); WorldMapInfoStorage.Cleanup(); ZoneGuardStorage.Cleanup(); } bool Storage_ReloadTable(const char * TableName) { // bur: mah god this is ugly :P if(!stricmp(TableName, "items")) // Items ItemPrototypeStorage.Reload(); else if(!stricmp(TableName, "creature_proto")) // Creature Proto CreatureProtoStorage.Reload(); else if(!stricmp(TableName, "creature_names")) // Creature Names CreatureNameStorage.Reload(); else if(!stricmp(TableName, "gameobject_names")) // GO Names GameObjectNameStorage.Reload(); else if(!stricmp(TableName, "areatriggers")) // Areatriggers AreaTriggerStorage.Reload(); else if(!stricmp(TableName, "itempages")) // Item Pages ItemPageStorage.Reload(); else if(!stricmp(TableName, "spellextra")) // Spell Extra Info SpellExtraStorage.Reload(); else if(!stricmp(TableName, "quests")) // Quests QuestStorage.Reload(); else if(!stricmp(TableName, "npc_text")) // NPC Text Storage NpcTextStorage.Reload(); else if(!stricmp(TableName, "fishing")) // Fishing Zones FishingZoneStorage.Reload(); else if(!stricmp(TableName, "teleport_coords")) // Teleport coords TeleportCoordStorage.Reload(); else if(!stricmp(TableName, "graveyards")) // Graveyards TeleportCoordStorage.Reload(); else if(!stricmp(TableName, "worldmap_info")) // WorldMapInfo WorldMapInfoStorage.Reload(); else if(!stricmp(TableName, "zoneguards")) ZoneGuardStorage.Reload(); else return false; return true; }