l2-unlegits/l2detect/HealItemsTable.cpp
2012-02-01 05:25:08 +00:00

497 lines
12 KiB
C++

#include "stdafx.h"
#include "HealItemsTable.h"
#include "utils.h"
#include "Logger.h"
HealItem::HealItem()
{
itemName[0] = 0;
itemID = reuseDelayMsec = 0;
priority = 0;
lastUseTime = 0;
percentUse = 0;
}
HealItem::HealItem( const HealItem &other )
{
strcpy( itemName, other.itemName );
itemID = other.itemID;
reuseDelayMsec = other.reuseDelayMsec;
priority = other.priority;
lastUseTime = other.lastUseTime;
percentUse = other.percentUse;
}
/*HealItem& HealItem::operator=( const HealItem& other )
{
strcpy( itemName, other.itemName );
itemID = other.itemID;
reuseDelaySecs = other.reuseDelaySecs;
priority = other.priority;
lastUseTime = other.lastUseTime;
return (*this);
}*/
void HealItem::GetItemNameW( wchar_t *out )
{
if( !out ) return;
out[0] = 0;
if( itemName[0] == 0 ) return;
MultiByteToWideChar( CP_ACP, 0, itemName, -1, out, 127 );
}
HealItemsTable::HealItemsTable()
{
clear();
}
HealItemsTable::~HealItemsTable()
{
clear();
}
void HealItemsTable::clear()
{
int i;
for( i=0; i<MAXNUMHEALITEMS; i++ )
{
hp_healers[i].itemID = mp_healers[i].itemID = cp_healers[i].itemID = 0;
}
enableHealHP = true;
enableHealMP = true;
enableHealCP = true;
}
bool HealItemsTable::LoadFromFile( const char *fileName )
{
if( !fileName ) return false;
clear();
int last_added = 0;
FILE *f = fopen( fileName, "rt" );
if( !f ) return false;
char line[512] = {0};
//
char itemName[128] = {0};
unsigned int itemID = 0;
unsigned int reuseDelay = 0;
int priority = 0;
int percentUse = 0;
//
int cur_read = 0;
const int READ_CP = 1;
const int READ_HP = 2;
const int READ_MP = 3;
//
char *token;
char delim[] = "=;\r\n";
//
while( !feof( f ) )
{
if( freadline( f, line, sizeof(line)-1 ) == 0 ) continue;
if( line[0] == '#' ) continue;
if( strcmp( line, "[CP healers]" ) == 0 )
{
cur_read = READ_CP;
last_added = 0;
continue;
}
if( strcmp( line, "[HP healers]" ) == 0 )
{
cur_read = READ_HP;
last_added = 0;
continue;
}
if( strcmp( line, "[MP healers]" ) == 0 )
{
cur_read = READ_MP;
last_added = 0;
continue;
}
if( !strchr( line, '=' ) ) continue;
if( strstr( line, "CPHealEnable" ) == line )
{
token = strtok( line, "=" );
if( token ) token = strtok( NULL, "=" );
if( token ) sscanf( token, "%d", &(this->enableHealCP) );
continue;
}
if( strstr( line, "HPHealEnable" ) == line )
{
token = strtok( line, "=" );
if( token ) token = strtok( NULL, "=" );
if( token ) sscanf( token, "%d", &(this->enableHealHP) );
continue;
}
if( strstr( line, "MPHealEnable" ) == line )
{
token = strtok( line, "=" );
if( token ) token = strtok( NULL, "=" );
if( token ) sscanf( token, "%d", &(this->enableHealMP) );
continue;
}
// token itemName
token = strtok( line, delim );
if( !token ) continue;
strcpy( itemName, token );
// token itemID
token = strtok( NULL, delim );
if( !token ) continue;
sscanf( token, "%u", &itemID );
// token reuseDelay
token = strtok( NULL, delim );
if( !token ) continue;
sscanf( token, "%u", &reuseDelay );
// token priority
token = strtok( NULL, delim );
if( !token ) continue;
sscanf( token, "%d", &priority );
// token percentUse
token = strtok( NULL, delim );
if( !token ) continue;
sscanf( token, "%d", &percentUse );
// log
//switch( cur_read )
//{
//case READ_HP: log_error( LOG_USERAI, "HealItemTable: READ_HP: %s [ID=%u] (%d sec, %d priotiy)\n", itemName, itemID, reuseDelay, priority ); break;
//case READ_MP: log_error( LOG_USERAI, "HealItemTable: READ_MP: %s [ID=%u] (%d sec, %d priotiy)\n", itemName, itemID, reuseDelay, priority ); break;
//case READ_CP: log_error( LOG_USERAI, "HealItemTable: READ_CP: %s [ID=%u] (%d sec, %d priotiy)\n", itemName, itemID, reuseDelay, priority ); break;
//}
//
//add
switch( cur_read )
{
case READ_HP:
{
strcpy( hp_healers[last_added].itemName, itemName );
hp_healers[last_added].itemID = itemID;
hp_healers[last_added].reuseDelayMsec = reuseDelay;
hp_healers[last_added].priority = priority;
hp_healers[last_added].lastUseTime = 0;
hp_healers[last_added].percentUse = percentUse;
last_added++;
} break;
case READ_MP:
{
strcpy( mp_healers[last_added].itemName, itemName );
mp_healers[last_added].itemID = itemID;
mp_healers[last_added].reuseDelayMsec = reuseDelay;
mp_healers[last_added].priority = priority;
mp_healers[last_added].lastUseTime = 0;
mp_healers[last_added].percentUse = percentUse;
last_added++;
} break;
case READ_CP:
{
strcpy( cp_healers[last_added].itemName, itemName );
cp_healers[last_added].itemID = itemID;
cp_healers[last_added].reuseDelayMsec = reuseDelay;
cp_healers[last_added].priority = priority;
cp_healers[last_added].lastUseTime = 0;
cp_healers[last_added].percentUse = percentUse;
last_added++;
} break;
}
}
fclose( f );
sort();
return true;
}
void HealItemsTable::sort()
{
int i, j;
HealItem temp;
// hp healers
for( i=0; i<=(MAXNUMHEALITEMS-2); i++ )
{
for( j=i+1; j<=(MAXNUMHEALITEMS-1); j++ )
{
if( hp_healers[j].priority > hp_healers[i].priority )
{
// save temp
//temp = hp_healers[i];
strcpy( temp.itemName, hp_healers[i].itemName );
temp.itemID = hp_healers[i].itemID;
temp.priority = hp_healers[i].priority;
temp.reuseDelayMsec = hp_healers[i].reuseDelayMsec;
temp.percentUse = hp_healers[i].percentUse;
// copy j -=> i
//hp_healers[i] = hp_healers[j];
strcpy( hp_healers[i].itemName, hp_healers[j].itemName );
hp_healers[i].itemID = hp_healers[j].itemID;
hp_healers[i].priority = hp_healers[j].priority;
hp_healers[i].reuseDelayMsec = hp_healers[j].reuseDelayMsec;
hp_healers[i].percentUse = hp_healers[j].percentUse;
//restore i
//hp_healers[j] = temp;
strcpy( hp_healers[j].itemName, temp.itemName );
hp_healers[j].itemID = temp.itemID;
hp_healers[j].priority = temp.priority;
hp_healers[j].reuseDelayMsec = temp.reuseDelayMsec;
hp_healers[j].percentUse = temp.percentUse;
}
}
}
// mp healers
for( i=0; i<=(MAXNUMHEALITEMS-2); i++ )
{
for( j=i+1; j<=(MAXNUMHEALITEMS-1); j++ )
{
if( mp_healers[j].priority > mp_healers[i].priority )
{
// save temp
temp = mp_healers[i];
// copy j -=> i
mp_healers[i] = mp_healers[j];
//restore i
mp_healers[j] = temp;
}
}
}
// cp healers
for( i=0; i<=(MAXNUMHEALITEMS-2); i++ )
{
for( j=i+1; j<=(MAXNUMHEALITEMS-1); j++ )
{
if( cp_healers[j].priority > cp_healers[i].priority )
{
// save temp
temp = cp_healers[i];
// copy j -=> i
cp_healers[i] = cp_healers[j];
//restore i
cp_healers[j] = temp;
}
}
}
}
bool HealItemsTable::getHPItem( int idx, HealItem& out )
{
if( (idx<0) || (idx>=MAXNUMHEALITEMS) ) return false;
out.itemID = 0;
out.itemName[0] = 0;
if( hp_healers[idx].itemID == 0 ) return false;
//out = hp_healers[idx];
strcpy( out.itemName, hp_healers[idx].itemName );
out.itemID = hp_healers[idx].itemID;
out.lastUseTime = hp_healers[idx].lastUseTime;
out.priority = hp_healers[idx].priority;
out.reuseDelayMsec = hp_healers[idx].reuseDelayMsec;
out.percentUse = hp_healers[idx].percentUse;
return true;
}
bool HealItemsTable::getMPItem( int idx, HealItem& out )
{
if( (idx<0) || (idx>=MAXNUMHEALITEMS) ) return false;
out.itemID = 0;
out.itemName[0] = 0;
if( mp_healers[idx].itemID == 0 ) return false;
out = mp_healers[idx];
return true;
}
bool HealItemsTable::getCPItem( int idx, HealItem& out )
{
if( (idx<0) || (idx>=MAXNUMHEALITEMS) ) return false;
out.itemID = 0;
out.itemName[0] = 0;
if( cp_healers[idx].itemID == 0 ) return false;
out = cp_healers[idx];
return true;
}
// type: 0 - hp; 1 - mp; 2 - cp
bool HealItemsTable::markUsedNow( HEALITEM_TYPE type, int idx, unsigned int tickCount )
{
if( (idx<0) || (idx>=MAXNUMHEALITEMS) ) return false;
switch( type )
{
case HIT_HP:
{
if( hp_healers[idx].itemID == 0 ) return false;
hp_healers[idx].lastUseTime = tickCount;
} break;
case HIT_MP:
{
if( mp_healers[idx].itemID == 0 ) return false;
mp_healers[idx].lastUseTime = tickCount;
} break;
case HIT_CP:
{
if( cp_healers[idx].itemID == 0 ) return false;
cp_healers[idx].lastUseTime = tickCount;
} break;
default: return false; break;
}
return true;
}
bool HealItemsTable::delItemFromTable( HEALITEM_TYPE type, int index )
{
if( (index<0) || (index>=MAXNUMHEALITEMS) ) return false;
int i;
switch( type )
{
case HIT_MARKUSED_HP:
{
hp_healers[index].itemID = 0;
hp_healers[index].priority = 0;
// shift
i=index;
while( i<=(MAXNUMHEALITEMS-2) )
{
hp_healers[i] = hp_healers[i+1];
i++;
}
} break;
case HIT_MARKUSED_MP:
{
mp_healers[index].itemID = 0;
mp_healers[index].priority = 0;
// shift
i=index;
while( i<=(MAXNUMHEALITEMS-2) )
{
mp_healers[i] = mp_healers[i+1];
i++;
}
} break;
case HIT_MARKUSED_CP:
{
cp_healers[index].itemID = 0;
cp_healers[index].priority = 0;
// shift
i=index;
while( i<=(MAXNUMHEALITEMS-2) )
{
cp_healers[i] = cp_healers[i+1];
i++;
}
} break;
default: return false; break;
}
//sort();
return true;
}
bool HealItemsTable::SaveToFile( const char *fileName )
{
if( !fileName ) return false;
FILE *f = fopen( fileName, "wt" );
if( !f ) return false;
// header
fprintf( f,
"# Format:\n"
"# Item Name=ItemID;reuseDelay(milliSeconds);priority;activatePercent\n"
"# No spaces between '=', ';' !\n"
"# priority is number between 1 and 100, determines which item will be used first\n"
"# priority 0 means 'do not use this item' :)\n"
"# ActivatePercent is stat value in percent from maximum, when this item can be used\n"
"\n" );
int i;
// CP healers
fprintf( f,
"[CP healers]\n"
"CPHealEnable=%d\n", this->enableHealCP );
for( i=0; i<MAXNUMHEALITEMS; i++ )
{
if( this->cp_healers[i].itemID == 0 ) continue;
fprintf( f, "%s=%u;%u;%d;%d\n",
this->cp_healers[i].itemName,
this->cp_healers[i].itemID,
this->cp_healers[i].reuseDelayMsec,
this->cp_healers[i].priority,
this->cp_healers[i].percentUse );
}
fprintf( f, "\n" );
// HP healers
fprintf( f,
"[HP healers]\n"
"HPHealEnable=%d\n", this->enableHealHP );
for( i=0; i<MAXNUMHEALITEMS; i++ )
{
if( this->hp_healers[i].itemID == 0 ) continue;
fprintf( f, "%s=%u;%u;%d;%d\n",
this->hp_healers[i].itemName,
this->hp_healers[i].itemID,
this->hp_healers[i].reuseDelayMsec,
this->hp_healers[i].priority,
this->hp_healers[i].percentUse );
}
fprintf( f, "\n" );
// MP healers
fprintf( f,
"[MP healers]\n"
"MPHealEnable=%d\n", this->enableHealMP );
for( i=0; i<MAXNUMHEALITEMS; i++ )
{
if( this->mp_healers[i].itemID == 0 ) continue;
fprintf( f, "%s=%u;%u;%d;%d\n",
this->mp_healers[i].itemName,
this->mp_healers[i].itemID,
this->mp_healers[i].reuseDelayMsec,
this->mp_healers[i].priority,
this->mp_healers[i].percentUse );
}
fprintf( f, "\n" );
fclose( f );
return true;
}
bool HealItemsTable::addHealItem( HEALITEM_TYPE type, const HealItem *example )
{
if( !example ) return false;
int free_idx = -1;
int i;
unsigned int itemID;
for( i=0; i<MAXNUMHEALITEMS; i++ )
{
itemID = 0;
switch( type )
{
case HIT_HP: itemID = hp_healers[i].itemID; break;
case HIT_MP: itemID = mp_healers[i].itemID; break;
case HIT_CP: itemID = cp_healers[i].itemID; break;
}
if( itemID == 0 )
{
free_idx = i;
break;
}
}
if( free_idx == -1 ) return false;
switch( type )
{
case HIT_HP: hp_healers[free_idx] = (*example); break;
case HIT_MP: mp_healers[free_idx] = (*example); break;
case HIT_CP: cp_healers[free_idx] = (*example); break;
}
sort();
return true;
}
bool HealItemsTable::setHealItem( HEALITEM_TYPE type, int idx, const HealItem *example )
{
if( !example ) return false;
if( (idx<0) || (idx>=MAXNUMHEALITEMS) ) return false;
switch( type )
{
case HIT_HP: hp_healers[idx] = (*example); break;
case HIT_MP: mp_healers[idx] = (*example); break;
case HIT_CP: cp_healers[idx] = (*example); break;
default: return false; break;
}
return true;
}