Initial MSVC 2008 projects workspace
This commit is contained in:
94
L2C_Server/datatables/CharNameTable.cpp
Normal file
94
L2C_Server/datatables/CharNameTable.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "pch.h"
|
||||
#include "CharNameTable.h"
|
||||
#include "GS.h"
|
||||
#include "Log.h"
|
||||
|
||||
CharNameTable *CharNameTable::s_instance = NULL;
|
||||
int CharNameTable::s_refCount = 0;
|
||||
|
||||
CharNameTable *CharNameTable::getInstance()
|
||||
{
|
||||
if( !s_instance )
|
||||
{
|
||||
s_instance = new CharNameTable();
|
||||
s_refCount++;
|
||||
}
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void CharNameTable::freeInstance()
|
||||
{
|
||||
if( s_instance == NULL ) return;
|
||||
s_refCount--;
|
||||
if( s_refCount == 0 )
|
||||
{
|
||||
delete s_instance;
|
||||
s_instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CharNameTable::CharNameTable()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
CharNameTable::~CharNameTable()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
void CharNameTable::LockDB()
|
||||
{
|
||||
m_lock.Lock();
|
||||
}
|
||||
|
||||
void CharNameTable::UnlockDB()
|
||||
{
|
||||
m_lock.Unlock();
|
||||
}
|
||||
|
||||
bool CharNameTable::doesCharNameExist( const wchar_t *charName )
|
||||
{
|
||||
bool ret = true;
|
||||
m_lock.Lock();
|
||||
{
|
||||
GameServer *gs = GameServer::getInstance();
|
||||
MysqlConnection *con = gs->getDBConnection();
|
||||
MysqlQuery q;
|
||||
q.create( L"SELECT account_name FROM characters WHERE char_name='%s'", charName );
|
||||
if( con->executeQuery( q ) )
|
||||
{
|
||||
int num_chars = q.getNumRows();
|
||||
assert( num_chars >= 0 );
|
||||
if( num_chars == 0 ) ret = false;
|
||||
}
|
||||
else
|
||||
LogError( L"CharNameTable::doesCharNameExist(): MySQL ERROR: %s\n", con->getErrorStr() );
|
||||
gs->releaseDBConnection( con );
|
||||
}
|
||||
m_lock.Unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CharNameTable::getAccountCharCount( const wchar_t *accountName )
|
||||
{
|
||||
if( !accountName ) return 0;
|
||||
// SELECT COUNT(char_name) FROM characters WHERE account_name=?
|
||||
int num_chars = 0;
|
||||
m_lock.Lock();
|
||||
{
|
||||
GameServer *gs = GameServer::getInstance();
|
||||
MysqlConnection *con = gs->getDBConnection();
|
||||
MysqlQuery q;
|
||||
q.create( L"SELECT COUNT(char_name) FROM characters WHERE account_name='%s'", accountName );
|
||||
if( con->executeQuery( q ) )
|
||||
{
|
||||
if( q.getNextRow() ) num_chars = q.getFieldInt( 0 );
|
||||
}
|
||||
else
|
||||
LogError( L"CharNameTable::getAccountCharCount(): MySQL ERROR: %s\n", con->getErrorStr() );
|
||||
gs->releaseDBConnection( con );
|
||||
}
|
||||
m_lock.Unlock();
|
||||
return num_chars;
|
||||
}
|
24
L2C_Server/datatables/CharNameTable.h
Normal file
24
L2C_Server/datatables/CharNameTable.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "l2c_utils.h"
|
||||
|
||||
class CharNameTable
|
||||
{
|
||||
protected:
|
||||
CharNameTable();
|
||||
~CharNameTable();
|
||||
static CharNameTable *s_instance;
|
||||
static int s_refCount;
|
||||
public:
|
||||
static CharNameTable *getInstance();
|
||||
static void freeInstance();
|
||||
|
||||
public:
|
||||
bool doesCharNameExist( const wchar_t *charName );
|
||||
int getAccountCharCount( const wchar_t *accountName );
|
||||
|
||||
void LockDB();
|
||||
void UnlockDB();
|
||||
|
||||
protected:
|
||||
CriticalSection m_lock;
|
||||
};
|
198
L2C_Server/datatables/CharTemplateTable.cpp
Normal file
198
L2C_Server/datatables/CharTemplateTable.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
#include "pch.h"
|
||||
#include "Log.h"
|
||||
#include "CharTemplateTable.h"
|
||||
#include "world/model/base/ClassIdTree.h"
|
||||
#include "ItemTable.h"
|
||||
#include "GS.h"
|
||||
|
||||
CharTemplateTable *CharTemplateTable::s_instance = NULL;
|
||||
int CharTemplateTable::s_refCount = 0;
|
||||
|
||||
CharTemplateTable *CharTemplateTable::getInstance()
|
||||
{
|
||||
if( s_instance == NULL )
|
||||
{
|
||||
s_instance = new CharTemplateTable();
|
||||
s_refCount++;
|
||||
}
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void CharTemplateTable::freeInstance()
|
||||
{
|
||||
if( s_instance )
|
||||
{
|
||||
s_refCount--;
|
||||
if( s_refCount == 0 )
|
||||
{
|
||||
delete s_instance;
|
||||
s_instance = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CharTemplateTable::CharTemplateTable()
|
||||
{
|
||||
m_templates.clear();
|
||||
}
|
||||
|
||||
CharTemplateTable::~CharTemplateTable()
|
||||
{
|
||||
std::map<int, L2PlayerTemplate *>::const_iterator iter = m_templates.begin();
|
||||
while( iter != m_templates.end() )
|
||||
{
|
||||
L2PlayerTemplate *tmpl = iter->second;
|
||||
if( tmpl ) delete tmpl;
|
||||
iter++;
|
||||
}
|
||||
m_templates.clear();
|
||||
}
|
||||
|
||||
void CharTemplateTable::load()
|
||||
{
|
||||
GameServer *gs = GameServer::getInstance();
|
||||
MysqlConnection *con = gs->getDBConnection();
|
||||
//
|
||||
MysqlQuery q;
|
||||
q.create( L"SELECT * FROM class_list, char_templates, lvlupgain "
|
||||
L"WHERE class_list.id = char_templates.classId AND class_list.id = lvlupgain.classId "
|
||||
L"ORDER BY class_list.id" );
|
||||
if( con->executeQuery( q ) )
|
||||
{
|
||||
while( q.getNextRow() )
|
||||
{
|
||||
StatsSet set;
|
||||
int classId;
|
||||
// l2 player template vars
|
||||
classId = q.getFieldInt( "id" );
|
||||
set.setInt( "classId", classId );
|
||||
set.setInt( "raceId", q.getFieldInt( "raceId" ) );
|
||||
set.setInt( "spawnX", q.getFieldInt( "x" ) );
|
||||
set.setInt( "spawnY", q.getFieldInt( "y" ) );
|
||||
set.setInt( "spawnZ", q.getFieldInt( "z" ) );
|
||||
set.setInt( "classBaseLevel", q.getFieldInt( "class_lvl" ) );
|
||||
set.setDouble( "lvlHpAdd", q.getFieldDouble( "defaultHpAdd" ) );
|
||||
set.setDouble( "lvlHpMod", q.getFieldDouble( "defaultHpMod" ) );
|
||||
set.setDouble( "lvlCpAdd", q.getFieldDouble( "defaultCpAdd" ) );
|
||||
set.setDouble( "lvlCpMod", q.getFieldDouble( "defaultCpMod" ) );
|
||||
set.setDouble( "lvlMpAdd", q.getFieldDouble( "defaultMpAdd" ) );
|
||||
set.setDouble( "lvlMpMod", q.getFieldDouble( "defaultMpMod" ) );
|
||||
set.setDouble( "baseHpMax", q.getFieldDouble( "defaultHpBase" ) );
|
||||
set.setDouble( "baseMpMax", q.getFieldDouble( "defaultMpBase" ) );
|
||||
set.setDouble( "baseCpMax", q.getFieldDouble( "defaultCpBase" ) );
|
||||
set.setDouble( "baseHpReg", 1.5 ); // O_o constants...?
|
||||
set.setDouble( "baseMpReg", 0.9 );
|
||||
// l2 char template vars
|
||||
set.setInt( "baseSTR", q.getFieldInt( "STR" ) );
|
||||
set.setInt( "baseCON", q.getFieldInt( "CON" ) );
|
||||
set.setInt( "baseDEX", q.getFieldInt( "DEX" ) );
|
||||
set.setInt( "baseINT", q.getFieldInt( "_INT" ) );
|
||||
set.setInt( "baseWIT", q.getFieldInt( "WIT" ) );
|
||||
set.setInt( "baseMEN", q.getFieldInt( "MEN" ) );
|
||||
//
|
||||
set.setInt( "basePAtk", q.getFieldInt( "P_ATK" ) );
|
||||
set.setInt( "basePDef", q.getFieldInt( "P_DEF" ) );
|
||||
set.setInt( "baseMAtk", q.getFieldInt( "M_ATK" ) );
|
||||
set.setInt( "baseMDef", q.getFieldInt( "M_DEF" ) );
|
||||
set.setInt( "basePAtkSpd", q.getFieldInt( "P_SPD" ) );
|
||||
set.setInt( "baseMAtkSpd", q.getFieldInt( "M_SPD" ) );
|
||||
set.setInt( "baseCritRate", q.getFieldInt( "CRITICAL" ) );
|
||||
set.setInt( "baseRunSpd", q.getFieldInt( "MOVE_SPD" ) );
|
||||
set.setInt( "baseWalkSpd", 0 );
|
||||
set.setInt( "baseShldDef", 0 );
|
||||
set.setInt( "baseShldRate", 0 );
|
||||
set.setInt( "baseAtkRange", 40 );
|
||||
set.setInt( "collision_radius", (int)q.getFieldDouble( "M_COL_R" ) );
|
||||
set.setInt( "collision_height", (int)q.getFieldDouble( "M_COL_H" ) );
|
||||
// TODO: MISSED char_templates vars
|
||||
set.setInt( "baseAccuracy", q.getFieldInt( "ACC" ) );
|
||||
set.setInt( "baseEvasion", q.getFieldInt( "EVASION" ) );
|
||||
set.setInt( "baseLoad", q.getFieldInt( "_LOAD" ) );
|
||||
set.setBool( "canCraft", q.getFieldBool( "canCraft" ) );
|
||||
//
|
||||
L2PlayerTemplate *tmpl = new L2PlayerTemplate( set );
|
||||
m_templates[classId] = tmpl;
|
||||
}
|
||||
Log( L"CharTemplateTable: loaded %u character templates.", m_templates.size() );
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError( L"CharTemplateTable::load(): Mysql error: %s", con->getErrorStr() );
|
||||
}
|
||||
|
||||
// load starting items
|
||||
ItemTable *itemTable = ItemTable::getInstance();
|
||||
q.create( L"SELECT classId, itemId, amount, equipped FROM char_creation_items" );
|
||||
if( con->executeQuery( q ) )
|
||||
{
|
||||
int classId, itemId, amount;
|
||||
bool equipped;
|
||||
while( q.getNextRow() )
|
||||
{
|
||||
classId = q.getFieldInt( "classId" );
|
||||
itemId = q.getFieldInt( "itemId" );
|
||||
amount = q.getFieldInt( "amount" );
|
||||
equipped = false;
|
||||
if( strcmp( q.getFieldStr( "equipped" ), "true" ) == 0 ) equipped = true;
|
||||
// check for item existance
|
||||
if( itemTable->getTemplate( itemId ) != NULL )
|
||||
{
|
||||
if( classId == -1 )
|
||||
{
|
||||
this->addItemToAllTemplates( itemId, amount, equipped );
|
||||
}
|
||||
else
|
||||
{
|
||||
L2PlayerTemplate *pct = const_cast<L2PlayerTemplate *>(CharTemplateTable::getTemplate( classId ));
|
||||
if( pct != NULL )
|
||||
pct->addItem( itemId, amount, equipped );
|
||||
else
|
||||
LogWarning( L"CharTemplateTable: load: Entry for undefined class, classId: %d", classId );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const wchar_t * className = L"(all)";
|
||||
if( classId >= 0 ) className = ClassIdTree::getInstance()->getClassId( classId )->getName();
|
||||
LogWarning( L"CharTemplateTable: load: No data for itemId: %d defined for classId %d (%s)",
|
||||
itemId, classId, className );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError( L"CharTemplateTable::load(): Mysql error: %s", con->getErrorStr() );
|
||||
}
|
||||
|
||||
//
|
||||
gs->releaseDBConnection( con );
|
||||
}
|
||||
|
||||
const wchar_t *CharTemplateTable::getClassNameById( int classId )
|
||||
{
|
||||
ClassIdTree *cidtree = ClassIdTree::getInstance();
|
||||
const ClassId *cls = cidtree->getClassId( classId );
|
||||
if( !cls ) return NULL;
|
||||
return cls->getName();
|
||||
}
|
||||
|
||||
const L2PlayerTemplate *CharTemplateTable::getTemplate( int classId )
|
||||
{
|
||||
CharTemplateTable *ctt = CharTemplateTable::getInstance();
|
||||
std::map<int, L2PlayerTemplate *>::const_iterator iter;
|
||||
iter = ctt->m_templates.find( classId );
|
||||
if( iter == ctt->m_templates.end() ) return NULL;
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
void CharTemplateTable::addItemToAllTemplates( int itemId, int amount, bool equipped )
|
||||
{
|
||||
std::map<int, L2PlayerTemplate *>::const_iterator iter;
|
||||
iter = m_templates.begin();
|
||||
while( iter != m_templates.end() )
|
||||
{
|
||||
L2PlayerTemplate *tmpl = iter->second;
|
||||
if( tmpl ) tmpl->addItem( itemId, amount, equipped );
|
||||
iter++;
|
||||
}
|
||||
}
|
25
L2C_Server/datatables/CharTemplateTable.h
Normal file
25
L2C_Server/datatables/CharTemplateTable.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "world/templates/chars/L2PlayerTemplate.h"
|
||||
|
||||
class CharTemplateTable
|
||||
{
|
||||
protected:
|
||||
static CharTemplateTable *s_instance;
|
||||
static int s_refCount;
|
||||
CharTemplateTable();
|
||||
~CharTemplateTable();
|
||||
public:
|
||||
static CharTemplateTable *getInstance();
|
||||
static void freeInstance();
|
||||
|
||||
public:
|
||||
void load();
|
||||
static const wchar_t *getClassNameById( int classId );
|
||||
static const L2PlayerTemplate *getTemplate( int classId );
|
||||
|
||||
protected:
|
||||
void addItemToAllTemplates( int itemId, int amount, bool equipped );
|
||||
|
||||
protected:
|
||||
std::map<int, L2PlayerTemplate *> m_templates;
|
||||
};
|
525
L2C_Server/datatables/ItemTable.cpp
Normal file
525
L2C_Server/datatables/ItemTable.cpp
Normal file
@@ -0,0 +1,525 @@
|
||||
#include "pch.h"
|
||||
#include "ItemTable.h"
|
||||
#include "Log.h"
|
||||
#include "../GS.h"
|
||||
#include "utils/Exception.h"
|
||||
|
||||
ItemTable *ItemTable::s_instance = NULL;
|
||||
int ItemTable::s_refCount = 0;
|
||||
|
||||
ItemTable *ItemTable::getInstance()
|
||||
{
|
||||
if( s_instance == NULL )
|
||||
{
|
||||
s_instance = new ItemTable();
|
||||
s_refCount++;
|
||||
}
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void ItemTable::freeInstance()
|
||||
{
|
||||
if( !s_instance ) return;
|
||||
s_refCount--;
|
||||
if( s_refCount > 0 ) return;
|
||||
delete s_instance;
|
||||
s_instance = NULL;
|
||||
}
|
||||
|
||||
ItemTable::ItemTable()
|
||||
{
|
||||
m_allTemplates = NULL;
|
||||
//m_armorTemplates = NULL;
|
||||
//m_weaponTemplates = NULL;
|
||||
//m_etcItemTemplates = NULL;
|
||||
m_cnt_all = 0;
|
||||
//m_cnt_armors = m_cnt_weapons = m_cnt_etcItems = 0;
|
||||
m_nTotalBytesAllocated = 0;
|
||||
m_maxItemId = 0;
|
||||
}
|
||||
|
||||
ItemTable::~ItemTable()
|
||||
{
|
||||
m_lock.Lock();
|
||||
unsigned int i;
|
||||
if( m_allTemplates )
|
||||
{
|
||||
if( m_maxItemId > 0 )
|
||||
{
|
||||
for( i=0; i<m_maxItemId; i++ )
|
||||
{
|
||||
if( m_allTemplates[i] ) delete m_allTemplates[i];
|
||||
m_allTemplates[i] = NULL;
|
||||
}
|
||||
}
|
||||
free( m_allTemplates );
|
||||
m_allTemplates = NULL;
|
||||
}
|
||||
m_lock.Unlock();
|
||||
m_nTotalBytesAllocated = 0;
|
||||
m_maxItemId = 0;
|
||||
m_cnt_all = 0;
|
||||
}
|
||||
|
||||
unsigned int ItemTable::select_count( void *vcon, const wchar_t *table )
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
MysqlConnection *con = (MysqlConnection *)vcon;
|
||||
MysqlQuery q;
|
||||
q.create( L"SELECT COUNT(*) FROM `%s`", table );
|
||||
if( con->executeQuery( q ) )
|
||||
{
|
||||
if( q.getNextRow() ) ret = q.getFieldUInt( 0 );
|
||||
else LogError( L"ItemTable::select_count( %s ): q.getNextRow() failed!", table );
|
||||
}
|
||||
else LogError( L"ItemTable::select_count( %s ): Mysql error: %s", table, con->getErrorStr() );
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int ItemTable::select_max( void *vcon, const wchar_t *table )
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
MysqlConnection *con = (MysqlConnection *)vcon;
|
||||
MysqlQuery q;
|
||||
q.create( L"SELECT MAX(item_id) FROM `%s`", table );
|
||||
if( con->executeQuery( q ) )
|
||||
{
|
||||
if( q.getNextRow() ) ret = q.getFieldUInt( 0 );
|
||||
else LogError( L"ItemTable::select_max( %s ): q.getNextRow() failed!", table );
|
||||
}
|
||||
else LogError( L"ItemTable::select_max( %s ): Mysql error: %s", table, con->getErrorStr() );
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ItemTable::load()
|
||||
{
|
||||
m_lock.Lock();
|
||||
try
|
||||
{
|
||||
// get GS DB conn
|
||||
GameServer *gs = GameServer::getInstance();
|
||||
MysqlConnection *con = gs->getDBConnection();
|
||||
// count items, armors, weapons in DB
|
||||
unsigned int etc_count = select_count( con, L"etcitem" );
|
||||
unsigned int arm_count = select_count( con, L"armor" );
|
||||
unsigned int wea_count = select_count( con, L"weapon" );
|
||||
Log( L"ItemTable: loading %u armors, %u weapons, %u etcitems", arm_count, wea_count, etc_count );
|
||||
unsigned int max_itemId = 0;
|
||||
unsigned int max_armor = select_max( con, L"armor" );
|
||||
unsigned int max_etcItem = select_max( con, L"etcitem" );
|
||||
unsigned int max_weapon = select_max( con, L"weapon" );
|
||||
max_itemId = max_armor;
|
||||
if( max_weapon > max_itemId ) max_itemId = max_weapon;
|
||||
if( max_etcItem > max_itemId ) max_itemId = max_etcItem;
|
||||
LogDebug( L"ItemTable: max itemId = %u (armor %u, etc %u, weapon %u)", max_itemId, max_armor, max_etcItem, max_weapon );
|
||||
// allocate m_allTemplates
|
||||
m_allTemplates = (L2ItemTemplate **)malloc( sizeof(void *) * (max_itemId+1) );
|
||||
if( !m_allTemplates )
|
||||
{
|
||||
m_lock.Unlock();
|
||||
LogError( L"ItemTable::load(): cannot allocate %u bytes\n", (unsigned int)(sizeof(void *) * (max_itemId+1)) );
|
||||
return;
|
||||
}
|
||||
memset( m_allTemplates, 0, sizeof(void *) * (max_itemId+1) );
|
||||
m_cnt_all = etc_count + arm_count + wea_count;
|
||||
m_maxItemId = max_itemId;
|
||||
m_nTotalBytesAllocated = sizeof(void *) * (max_itemId+1);
|
||||
//
|
||||
loadEtcItems( con );
|
||||
loadArmors( con );
|
||||
loadWeapons( con );
|
||||
//
|
||||
// release GS DB conn
|
||||
gs->releaseDBConnection( con );
|
||||
}
|
||||
catch( Exception& e )
|
||||
{
|
||||
LogError( L"ItemTable load error: %S", e.what() );
|
||||
e.logStackTrace();
|
||||
}
|
||||
m_lock.Unlock();
|
||||
Log( L"ItemTable: loaded, used %I64u bytes", m_nTotalBytesAllocated );
|
||||
}
|
||||
|
||||
void ItemTable::reload()
|
||||
{
|
||||
// TODO: maybe better way?
|
||||
Log( L"ItemTable: reload starting..." );
|
||||
m_lock.Lock();
|
||||
this->~ItemTable();
|
||||
this->load();
|
||||
m_lock.Unlock();
|
||||
Log( L"ItemTable: reload complete." );
|
||||
}
|
||||
|
||||
void ItemTable::loadEtcItems( void *vcon )
|
||||
{
|
||||
MysqlConnection *con = (MysqlConnection *)vcon;
|
||||
MysqlQuery q;
|
||||
q.create( L"SELECT item_id, name, crystallizable, item_type, weight, consume_type, material, "
|
||||
L" crystal_type, duration, time, price, crystal_count, sellable, dropable, destroyable, "
|
||||
L" tradeable, handler, skill FROM etcitem" );
|
||||
if( con->executeQuery( q ) )
|
||||
{
|
||||
while( q.getNextRow() )
|
||||
{
|
||||
StatsSet set;
|
||||
L2ItemSubType etcItemType = SYBTYPE_INCORRECT;
|
||||
int item_id = 0;
|
||||
char *str = NULL;
|
||||
L2ItemSlot bodypart = SLOT_NONE;
|
||||
int type2 = L2ItemTemplate::TYPE2_OTHER;
|
||||
wchar_t wname[256] = {0};
|
||||
|
||||
// get item ID
|
||||
item_id = q.getFieldInt( "item_id" );
|
||||
set.setInt( "item_id", item_id );
|
||||
|
||||
str = q.getFieldStr( "item_type" );
|
||||
if( _stricmp( str, "none" ) == 0 )
|
||||
etcItemType = ETCITEM_OTHER; // only for default
|
||||
else if ( _stricmp( str, "castle_guard") == 0 )
|
||||
etcItemType = ETCITEM_SCROLL; // dummy
|
||||
else if( _stricmp( str, "material") == 0 )
|
||||
etcItemType = ETCITEM_MATERIAL;
|
||||
else if( _stricmp( str, "pet_collar") == 0 )
|
||||
etcItemType = ETCITEM_PET_COLLAR;
|
||||
else if( _stricmp( str, "potion") == 0 )
|
||||
etcItemType = ETCITEM_POTION;
|
||||
else if( _stricmp( str, "recipe") == 0 )
|
||||
etcItemType = ETCITEM_RECEIPE;
|
||||
else if( _stricmp( str, "scroll") == 0 )
|
||||
etcItemType = ETCITEM_SCROLL;
|
||||
else if( _stricmp( str, "seed") == 0 )
|
||||
etcItemType = ETCITEM_SEED;
|
||||
else if( _stricmp( str, "shot") == 0 )
|
||||
etcItemType = ETCITEM_SHOT;
|
||||
else if( _stricmp( str, "spellbook") == 0 )
|
||||
etcItemType = ETCITEM_SPELLBOOK; // Spellbook, Amulet, Blueprint
|
||||
else if( _stricmp( str, "herb") == 0 )
|
||||
etcItemType = ETCITEM_HERB;
|
||||
else if( _stricmp( str, "arrow") == 0 )
|
||||
{
|
||||
etcItemType = ETCITEM_ARROW;
|
||||
bodypart = SLOT_L_HAND;
|
||||
}
|
||||
else if( _stricmp( str, "bolt") == 0 )
|
||||
{
|
||||
etcItemType = ETCITEM_BOLT;
|
||||
bodypart = SLOT_L_HAND;
|
||||
}
|
||||
else if( _stricmp( str, "quest") == 0 )
|
||||
{
|
||||
etcItemType = ETCITEM_QUEST;
|
||||
type2 = L2ItemTemplate::TYPE2_QUEST;
|
||||
}
|
||||
else if( _stricmp( str, "lure") == 0 )
|
||||
{
|
||||
etcItemType = ETCITEM_OTHER;
|
||||
bodypart = SLOT_L_HAND;
|
||||
}
|
||||
else if( _stricmp( str, "dye") == 0 )
|
||||
etcItemType = ETCITEM_DYE;
|
||||
else if( _stricmp( str, "lotto") == 0 )
|
||||
etcItemType = ETCITEM_OTHER;
|
||||
else if( _stricmp( str, "race_ticket") == 0 )
|
||||
etcItemType = ETCITEM_OTHER;
|
||||
else if( _stricmp( str, "harvest") == 0 )
|
||||
etcItemType = ETCITEM_OTHER;
|
||||
else if( _stricmp( str, "ticket_of_lord") == 0 )
|
||||
etcItemType = ETCITEM_OTHER;
|
||||
else
|
||||
{
|
||||
q.getFieldStrW( "name", wname, 255 ); wname[255] = 0;
|
||||
LogWarning( L"ItemTable::loadEtcItems(): unknown etcitem type: %S (item_id %d [%s])",
|
||||
str, item_id, wname );
|
||||
etcItemType = ETCITEM_OTHER;
|
||||
}
|
||||
|
||||
set.setInt( "type1", L2ItemTemplate::TYPE1_ITEM_QUESTITEM_ADENA );
|
||||
set.setInt( "type2", type2 );
|
||||
set.setInt( "bodypart", (int)bodypart );
|
||||
set.setBool( "crystallizable", q.getFieldBool( "crystallizable" ) );
|
||||
set.setInt( "crystal_count", q.getFieldInt( "crystal_count" ) );
|
||||
set.setBool( "sellable", q.getFieldBool( "sellable" ) );
|
||||
set.setBool( "dropable", q.getFieldBool( "dropable" ) );
|
||||
set.setBool( "destroyable", q.getFieldBool( "destroyable" ) );
|
||||
set.setBool( "tradeable", q.getFieldBool( "tradeable" ) );
|
||||
set.setString( "handler", q.getFieldStr( "handler" ) );
|
||||
// item.set.set("skill", rset.getString("skill")); // TODO: etc item skills
|
||||
|
||||
str = q.getFieldStr( "consume_type" );
|
||||
if( _stricmp( str, "asset" ) == 0 )
|
||||
{
|
||||
etcItemType = ETCITEM_MONEY;
|
||||
set.setBool( "stackable", true );
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_MONEY );
|
||||
}
|
||||
else if ( _stricmp( str, "stackable" ) == 0 )
|
||||
{
|
||||
set.setBool( "stackable", true );
|
||||
}
|
||||
else
|
||||
{
|
||||
set.setBool( "stackable", false );
|
||||
}
|
||||
|
||||
L2ItemMaterial material = L2ItemTemplate::getMaterialByName( q.getFieldStr( "material" ) );
|
||||
set.setInt( "material", (int)material );
|
||||
L2ItemCrystal crystal = L2ItemTemplate::getCrystalTypeByName( q.getFieldStr( "crystal_type" ) );
|
||||
set.setInt( "crystal_type", (int)crystal );
|
||||
set.setInt( "weight", q.getFieldInt( "weight" ) );
|
||||
// name
|
||||
q.getFieldStrW( "name", wname, 255 ); wname[255] = 0;
|
||||
set.setWString( "name", wname );
|
||||
//
|
||||
set.setInt( "duration", q.getFieldInt( "duration" ) );
|
||||
set.setInt( "time", q.getFieldInt( "time" ) );
|
||||
set.setInt( "price", q.getFieldInt( "price" ) );
|
||||
//
|
||||
// create and insert template
|
||||
L2EtcItemTemplate *tmpl = new L2EtcItemTemplate( etcItemType, set );
|
||||
m_allTemplates[item_id] = (L2ItemTemplate *)tmpl;
|
||||
|
||||
// count bytes allocated
|
||||
if( tmpl ) m_nTotalBytesAllocated += (sizeof(L2EtcItemTemplate) + 2*wcslen(tmpl->getName()));
|
||||
} // next row
|
||||
}
|
||||
else
|
||||
LogError( L"ItemTable::loadEtcItems(): MySQL error: %s", con->getErrorStr() );
|
||||
}
|
||||
|
||||
void ItemTable::loadArmors( void *vcon )
|
||||
{
|
||||
MysqlConnection *con = (MysqlConnection *)vcon;
|
||||
MysqlQuery q;
|
||||
q.create( L"SELECT item_id, name, bodypart, crystallizable, armor_type, weight,"
|
||||
L" material, crystal_type, avoid_modify, duration, time, p_def, m_def, mp_bonus,"
|
||||
L" price, crystal_count, sellable, dropable, destroyable, tradeable, enchant4_skill, skill FROM armor" );
|
||||
if( con->executeQuery( q ) )
|
||||
{
|
||||
while( q.getNextRow() )
|
||||
{
|
||||
StatsSet set;
|
||||
int item_id;
|
||||
int bodypart_i = 0;
|
||||
L2ItemSlot bodypart = SLOT_NONE;
|
||||
wchar_t wstr[256] = {0};
|
||||
char *str = NULL;
|
||||
//
|
||||
L2ItemSubType armorType = L2ItemTemplate::getArmorTypeByName( q.getFieldStr( "armor_type" ) );
|
||||
item_id = q.getFieldInt( 0 );
|
||||
set.setInt( "item_id", item_id );
|
||||
q.getFieldStrW( "name", wstr, 255 );
|
||||
set.setWString( "name", wstr );
|
||||
bodypart = L2ItemTemplate::getSlotByName( q.getFieldStr( "bodypart" ) );
|
||||
bodypart_i = (int)bodypart;
|
||||
set.setInt( "bodypart", bodypart_i );
|
||||
set.setBool( "crystallizable", q.getFieldBool( "crystallizable" ) );
|
||||
set.setInt( "crystal_count", q.getFieldInt( "crystal_count" ) );
|
||||
set.setBool( "sellable", q.getFieldBool( "sellable" ) );
|
||||
set.setBool( "dropable", q.getFieldBool( "dropable" ) );
|
||||
set.setBool( "destroyable", q.getFieldBool( "destroyable" ) );
|
||||
set.setBool( "tradeable", q.getFieldBool( "tradeable" ) );
|
||||
set.setString( "enchant4_skill", q.getFieldStr( "enchant4_skill" ) );
|
||||
set.setString( "skill", str = q.getFieldStr( "skill" ) );
|
||||
|
||||
// determine type1 & type2
|
||||
if( bodypart == SLOT_NECK || bodypart == SLOT_HAIR
|
||||
|| bodypart == SLOT_HAIR2 || bodypart == SLOT_HAIRALL
|
||||
|| (bodypart & SLOT_L_EAR) != 0 || (bodypart & SLOT_L_FINGER) != 0)
|
||||
{
|
||||
set.setInt( "type1", L2ItemTemplate::TYPE1_WEAPON_RING_EARRING_NECKLACE );
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_ACCESSORY );
|
||||
}
|
||||
else
|
||||
{
|
||||
set.setInt( "type1", L2ItemTemplate::TYPE1_SHIELD_ARMOR );
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_SHIELD_ARMOR );
|
||||
}
|
||||
|
||||
set.setInt( "weight", q.getFieldInt( "weight" ) );
|
||||
set.setInt( "material", (int)L2ItemTemplate::getMaterialByName( q.getFieldStr( "material" ) ) );
|
||||
set.setInt( "crystal_type", (int)L2ItemTemplate::getCrystalTypeByName( q.getFieldStr( "crystal_type" ) ) );
|
||||
set.setInt( "avoid_modify", q.getFieldInt( "avoid_modify" ) );
|
||||
set.setInt( "duration", q.getFieldInt( "duration" ) );
|
||||
set.setInt( "time", q.getFieldInt( "time" ) );
|
||||
set.setInt( "p_def", q.getFieldInt( "p_def" ) );
|
||||
set.setInt( "m_def", q.getFieldInt( "m_def" ) );
|
||||
set.setInt( "mp_bonus", q.getFieldInt( "mp_bonus" ) );
|
||||
set.setInt( "price", q.getFieldInt( "price" ) );
|
||||
|
||||
// deal with pet items: type1, type2 & bodypart
|
||||
if( armorType == ARMOR_PET )
|
||||
{
|
||||
if( bodypart == SLOT_NECK )
|
||||
{
|
||||
set.setInt( "type1", L2ItemTemplate::TYPE1_WEAPON_RING_EARRING_NECKLACE );
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_ACCESSORY );
|
||||
set.setInt( "bodypart", (int)SLOT_NECK );
|
||||
}
|
||||
else
|
||||
{
|
||||
set.setInt( "type1", L2ItemTemplate::TYPE1_SHIELD_ARMOR );
|
||||
L2ItemSlot temp_b = SLOT_NONE;
|
||||
//int temp_b = 0;
|
||||
set.getInt( "bodypart", (int *)&temp_b );
|
||||
switch( temp_b )
|
||||
{
|
||||
case SLOT_WOLF:
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_PET_WOLF );
|
||||
break;
|
||||
case SLOT_GREATWOLF:
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_PET_EVOLVEDWOLF );
|
||||
break;
|
||||
case SLOT_HATCHLING:
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_PET_HATCHLING );
|
||||
break;
|
||||
case SLOT_BABYPET:
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_PET_BABY );
|
||||
break;
|
||||
default:
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_PET_STRIDER );
|
||||
break;
|
||||
}
|
||||
set.setInt( "bodypart", (int)SLOT_CHEST );
|
||||
}
|
||||
}
|
||||
|
||||
// create and insert template
|
||||
L2ArmorTemplate *tmpl = new L2ArmorTemplate( armorType, set );
|
||||
m_allTemplates[item_id] = (L2ItemTemplate *)tmpl;
|
||||
|
||||
// count bytes allocated
|
||||
if( tmpl ) m_nTotalBytesAllocated += (sizeof(L2ArmorTemplate) + 2*wcslen(tmpl->getName()));
|
||||
//else throw std::bad_alloc( "ItemTable:loadArmors: new L2ArmorTemplate" );
|
||||
}
|
||||
}
|
||||
else
|
||||
LogError( L"ItemTable::loadArmors(): MySQL error: %s", con->getErrorStr() );
|
||||
}
|
||||
|
||||
void ItemTable::loadWeapons( void *vcon )
|
||||
{
|
||||
MysqlConnection *con = (MysqlConnection *)vcon;
|
||||
MysqlQuery q;
|
||||
q.create( L"SELECT item_id, name, bodypart, crystallizable, weight, soulshots, spiritshots,"
|
||||
L" material, crystal_type, p_dam, rnd_dam, weaponType, critical, hit_modify, avoid_modify,"
|
||||
L" shield_def, shield_def_rate, atk_speed, mp_consume, m_dam, duration, time, price, crystal_count,"
|
||||
L" sellable, dropable, destroyable, tradeable, skill,enchant4_skill_id,enchant4_skill_lvl, "
|
||||
L" onCast_skill_id, onCast_skill_lvl, onCast_skill_chance, onCrit_skill_id, "
|
||||
L" onCrit_skill_lvl, onCrit_skill_chance, change_weaponId FROM weapon" );
|
||||
if( con->executeQuery( q ) )
|
||||
{
|
||||
while( q.getNextRow() )
|
||||
{
|
||||
StatsSet set;
|
||||
int item_id;
|
||||
int bodypart_i = 0;
|
||||
L2ItemSlot bodypart = SLOT_NONE;
|
||||
wchar_t wstr[256] = {0};
|
||||
//
|
||||
L2ItemSubType weaponType = L2ItemTemplate::getWeaponTypeByName( q.getFieldStr( "weaponType" ) );
|
||||
item_id = q.getFieldInt( 0 );
|
||||
set.setInt( "item_id", item_id );
|
||||
q.getFieldStrW( "name", wstr, 255 );
|
||||
set.setWString( "name", wstr );
|
||||
|
||||
// lets see if this is a shield
|
||||
if( weaponType == WEAPON_NONE )
|
||||
{
|
||||
set.setInt( "type1", L2ItemTemplate::TYPE1_SHIELD_ARMOR );
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_SHIELD_ARMOR );
|
||||
}
|
||||
else
|
||||
{
|
||||
set.setInt( "type1", L2ItemTemplate::TYPE1_WEAPON_RING_EARRING_NECKLACE );
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_WEAPON );
|
||||
}
|
||||
|
||||
bodypart = L2ItemTemplate::getSlotByName( q.getFieldStr( "bodypart" ) );
|
||||
bodypart_i = (int)bodypart;
|
||||
set.setInt( "bodypart", bodypart_i );
|
||||
|
||||
set.setInt( "material", (int)L2ItemTemplate::getMaterialByName( q.getFieldStr( "material" ) ) );
|
||||
set.setInt( "crystal_type", (int)L2ItemTemplate::getCrystalTypeByName( q.getFieldStr( "crystal_type" ) ) );
|
||||
|
||||
set.setBool( "crystallizable", q.getFieldBool( "crystallizable" ) );
|
||||
set.setInt( "weight", q.getFieldInt( "weight" ) );
|
||||
set.setInt( "soulshots", q.getFieldInt( "soulshots" ) );
|
||||
set.setInt( "spiritshots", q.getFieldInt( "spiritshots" ) );
|
||||
set.setInt( "p_dam", q.getFieldInt( "p_dam" ) );
|
||||
set.setInt( "rnd_dam", q.getFieldInt( "rnd_dam" ) );
|
||||
set.setInt( "critical", q.getFieldInt( "critical" ) );
|
||||
set.setInt( "hit_modify", q.getFieldInt( "hit_modify" ) );
|
||||
set.setInt( "avoid_modify", q.getFieldInt( "avoid_modify" ) );
|
||||
set.setInt( "shield_def", q.getFieldInt( "shield_def" ) );
|
||||
set.setInt( "shield_def_rate", q.getFieldInt( "shield_def_rate" ) );
|
||||
set.setInt( "atk_speed", q.getFieldInt( "atk_speed" ) );
|
||||
set.setInt( "mp_consume", q.getFieldInt( "mp_consume" ) );
|
||||
set.setInt( "m_dam", q.getFieldInt( "m_dam" ) );
|
||||
set.setInt( "duration", q.getFieldInt( "duration" ) );
|
||||
set.setInt( "time", q.getFieldInt( "time" ) );
|
||||
set.setInt( "price", q.getFieldInt( "price" ) );
|
||||
set.setInt( "crystal_count", q.getFieldInt( "crystal_count" ) );
|
||||
set.setBool( "sellable", q.getFieldBool( "sellable" ) );
|
||||
set.setBool( "dropable", q.getFieldBool( "dropable" ) );
|
||||
set.setBool( "destroyable", q.getFieldBool( "destroyable" ) );
|
||||
set.setBool( "tradeable", q.getFieldBool( "tradeable" ) );
|
||||
set.setString( "skill", q.getFieldStr( "skill" ) );
|
||||
|
||||
set.setInt( "enchant4_skill_id", q.getFieldInt( "enchant4_skill_id" ) );
|
||||
set.setInt( "enchant4_skill_lvl", q.getFieldInt( "enchant4_skill_lvl" ) );
|
||||
|
||||
/*item.set.set("onCast_skill_id", rset.getInt("onCast_skill_id"));
|
||||
item.set.set("onCast_skill_lvl", rset.getInt("onCast_skill_lvl"));
|
||||
item.set.set("onCast_skill_chance", rset.getInt("onCast_skill_chance"));
|
||||
|
||||
item.set.set("onCrit_skill_id", rset.getInt("onCrit_skill_id"));
|
||||
item.set.set("onCrit_skill_lvl", rset.getInt("onCrit_skill_lvl"));
|
||||
item.set.set("onCrit_skill_chance", rset.getInt("onCrit_skill_chance"));*/
|
||||
|
||||
set.setInt( "change_weaponId", q.getFieldInt( "change_weaponId" ) );
|
||||
|
||||
if( weaponType == WEAPON_PET )
|
||||
{
|
||||
set.setInt( "type1", L2ItemTemplate::TYPE1_WEAPON_RING_EARRING_NECKLACE );
|
||||
if( bodypart == SLOT_WOLF )
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_PET_WOLF );
|
||||
else if( bodypart == SLOT_GREATWOLF )
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_PET_EVOLVEDWOLF );
|
||||
else if( bodypart == SLOT_HATCHLING )
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_PET_HATCHLING );
|
||||
else if( bodypart == SLOT_BABYPET )
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_PET_BABY );
|
||||
else
|
||||
set.setInt( "type2", L2ItemTemplate::TYPE2_PET_STRIDER );
|
||||
|
||||
bodypart = SLOT_R_HAND;
|
||||
set.setInt( "bodypart", (int)SLOT_R_HAND);
|
||||
}
|
||||
|
||||
// create and insert template
|
||||
L2WeaponTemplate *tmpl = new L2WeaponTemplate( weaponType, set );
|
||||
m_allTemplates[item_id] = (L2ItemTemplate *)tmpl;
|
||||
|
||||
// count bytes allocated
|
||||
if( tmpl ) m_nTotalBytesAllocated += (sizeof(L2WeaponTemplate) + 2*wcslen(tmpl->getName()));
|
||||
//else throw std::bad_alloc( "ItemTable:loadWeapons new L2WeaponTemplate" );
|
||||
}
|
||||
}
|
||||
else
|
||||
LogError( L"ItemTable::loadWeapons(): MySQL error: %s", con->getErrorStr() );
|
||||
}
|
||||
|
||||
const L2ItemTemplate *ItemTable::getTemplate( unsigned int itemId )
|
||||
{
|
||||
if( !m_allTemplates ) return NULL;
|
||||
if( itemId < 0 || itemId > m_maxItemId )
|
||||
{
|
||||
LogError( L"ItemTable::getTemplate( %u ): request to incorrect itemId (max id is %u)\n",
|
||||
itemId, m_maxItemId );
|
||||
return NULL;
|
||||
}
|
||||
return (const L2ItemTemplate *)m_allTemplates[itemId];
|
||||
}
|
47
L2C_Server/datatables/ItemTable.h
Normal file
47
L2C_Server/datatables/ItemTable.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include "l2c_utils.h"
|
||||
#include "../world/templates/StatsSet.h"
|
||||
#include "../world/templates/item/L2ItemTemplate.h"
|
||||
#include "../world/templates/item/L2ArmorTemplate.h"
|
||||
#include "../world/templates/item/L2EtcItemTemplate.h"
|
||||
#include "../world/templates/item/L2WeaponTemplate.h"
|
||||
|
||||
class ItemTable
|
||||
{
|
||||
protected:
|
||||
ItemTable();
|
||||
~ItemTable();
|
||||
static ItemTable *s_instance;
|
||||
static int s_refCount;
|
||||
|
||||
public:
|
||||
static ItemTable *getInstance();
|
||||
static void freeInstance();
|
||||
|
||||
public:
|
||||
void load();
|
||||
void reload();
|
||||
|
||||
public:
|
||||
const L2ItemTemplate *getTemplate( unsigned int itemId );
|
||||
|
||||
protected:
|
||||
static unsigned int select_count( void *vcon, const wchar_t *table );
|
||||
static unsigned int select_max( void *vcon, const wchar_t *table );
|
||||
void loadEtcItems( void *vcon );
|
||||
void loadArmors( void *vcon );
|
||||
void loadWeapons( void *vcon );
|
||||
|
||||
protected:
|
||||
CriticalSection m_lock;
|
||||
L2ItemTemplate **m_allTemplates;
|
||||
//L2ArmorTemplate *m_armorTemplates;
|
||||
//L2WeaponTemplate *m_weaponTemplates;
|
||||
//L2EtcItemTemplate *m_etcItemTemplates;
|
||||
unsigned int m_cnt_all;
|
||||
unsigned int m_maxItemId;
|
||||
//unsigned int m_cnt_armors;
|
||||
//unsigned int m_cnt_weapons;
|
||||
//unsigned int m_cnt_etcItems;
|
||||
unsigned long long int m_nTotalBytesAllocated;
|
||||
};
|
Reference in New Issue
Block a user