server/game/src/ani.cpp

372 lines
7.6 KiB
C++

/*********************************************************************
* date : 2007.11.16
* file : ani.cpp
* author : mhh
* description :
*/
#define _ani_cpp_
#include "stdafx.h"
#include "char.h"
#include "item.h"
#include "ani.h"
#include "dev_log.h"
const char* FN_race_name(int race)
{
#define FN_NAME(race) case race: return #race
switch (race)
{
FN_NAME(MAIN_RACE_WARRIOR_M);
FN_NAME(MAIN_RACE_ASSASSIN_W);
FN_NAME(MAIN_RACE_SURA_M);
FN_NAME(MAIN_RACE_SHAMAN_W);
FN_NAME(MAIN_RACE_WARRIOR_W);
FN_NAME(MAIN_RACE_ASSASSIN_M);
FN_NAME(MAIN_RACE_SURA_W);
FN_NAME(MAIN_RACE_SHAMAN_M);
FN_NAME(MAIN_RACE_MAX_NUM);
}
return "UNKNOWN";
#undef FN_NAME
}
const char* FN_weapon_type(int weapon)
{
#define FN_NAME(weapon) case weapon: return #weapon
switch (weapon)
{
FN_NAME(WEAPON_SWORD);
FN_NAME(WEAPON_DAGGER);
FN_NAME(WEAPON_BOW);
FN_NAME(WEAPON_TWO_HANDED);
FN_NAME(WEAPON_BELL);
FN_NAME(WEAPON_FAN);
FN_NAME(WEAPON_ARROW);
FN_NAME(WEAPON_MOUNT_SPEAR);
FN_NAME(WEAPON_NUM_TYPES);
}
return "UNKNOWN";
#undef FN_NAME
}
class ANI
{
protected:
// [Á¾Á·][ÀϹÝ0Å»°Í1][¹«±â][ÄÞº¸]
DWORD m_speed[MAIN_RACE_MAX_NUM][2][WEAPON_NUM_TYPES][9];
public:
ANI();
public:
bool load();
bool load_one_race(int race, const char *dir_name);
DWORD load_one_weapon(const char *dir_name, int weapon, BYTE combo, bool horse);
DWORD attack_speed(int race, int weapon, BYTE combo = 0, bool horse = false);
void print_attack_speed();
};
static class ANI s_ANI;
DWORD FN_attack_speed_from_file(const char *file)
{
FILE * fp = fopen(file, "r");
if (NULL == fp)
return 0;
int speed = 1000;
const char *key = "DirectInputTime";
const char *delim = " \t\r\n";
const char *field, *value;
char buf[1024];
while (fgets(buf, 1024, fp))
{
field = strtok(buf, delim);
value = strtok(NULL, delim);
if (field && value)
{
if (0 == strcasecmp(field, key))
{
float f_speed = strtof(value, NULL);
speed = (int) (f_speed * 1000.0);
break;
}
}
}
fclose(fp);
return speed;
}
ANI::ANI()
{
// set default value
for (int race = 0; race < MAIN_RACE_MAX_NUM; ++race)
{
for (int weapon = 0; weapon < WEAPON_NUM_TYPES; ++weapon)
{
for (BYTE combo = 0; combo <= 8; ++combo)
{
m_speed[race][0][weapon][combo] = 1000;
m_speed[race][1][weapon][combo] = 1000;
}
}
}
}
bool ANI::load()
{
const char* dir_name[MAIN_RACE_MAX_NUM] = {
"data/pc/warrior", // ¹«»ç(³²)
"data/pc/assassin", // ÀÚ°´(¿©)
"data/pc/sura", // ¼ö¶ó(³²)
"data/pc/shaman", // ¹«´ç(¿©)
"data/pc2/warrior", // ¹«»ç(¿©)
"data/pc2/assassin", // ÀÚ°´(³²)
"data/pc2/sura", // ¼ö¶ó(¿©)
"data/pc2/shaman" // ¹«´ç(³²)
};
for (int race = 0; race <MAIN_RACE_MAX_NUM; ++race)
{
if (false == load_one_race(race, dir_name[race]))
{
sys_err("ANI directory = %s", dir_name[race]);
return false;
}
}
return true;
}
DWORD ANI::load_one_weapon(const char *dir_name, int weapon, BYTE combo, bool horse)
{
char format[128];
char filename[256];
switch (weapon)
{
case WEAPON_SWORD:
strncpy(format, "%s/%sonehand_sword/combo_%02d.msa", sizeof(format));
break;
case WEAPON_DAGGER:
strncpy(format, "%s/%sdualhand_sword/combo_%02d.msa", sizeof(format));
break;
case WEAPON_BOW:
strncpy(format, "%s/%sbow/attack.msa", sizeof(format));
break;
case WEAPON_TWO_HANDED:
strncpy(format, "%s/%stwohand_sword/combo_%02d.msa", sizeof(format));
break;
case WEAPON_BELL:
strncpy(format, "%s/%sbell/combo_%02d.msa", sizeof(format));
break;
case WEAPON_FAN:
strncpy(format, "%s/%sfan/combo_%02d.msa", sizeof(format));
break;
default:
return 1000;
}
snprintf(filename, sizeof(filename), format, dir_name, horse ? "horse_" : "", combo);
DWORD speed = FN_attack_speed_from_file(filename);
if (speed == 0)
return 1000;
return speed;
}
bool ANI::load_one_race(int race, const char *dir_name)
{
if (NULL == dir_name || '\0' == dir_name[0])
return false;
for (int weapon = WEAPON_SWORD; weapon < WEAPON_NUM_TYPES; ++weapon)
{
dev_log(LOG_DEB0, "ANI (%s,%s)", FN_race_name(race), FN_weapon_type(weapon));
for (BYTE combo = 1; combo <= 8; ++combo)
{
// ¸» ¾ÈÅÀÀ» ¶§
m_speed[race][0][weapon][combo] = load_one_weapon(dir_name, weapon, combo, false);
m_speed[race][0][weapon][0] = MIN(m_speed[race][0][weapon][0], m_speed[race][0][weapon][combo]); // ÃÖ¼Ò°ª
// ¸» ÅÀÀ» ¶§
m_speed[race][1][weapon][combo] = load_one_weapon(dir_name, weapon, combo, true);
m_speed[race][1][weapon][0] = MIN(m_speed[race][1][weapon][0], m_speed[race][1][weapon][combo]); // ÃÖ¼Ò°ª
dev_log(LOG_DEB0, "combo%02d speed=%d horse=%d",
combo, m_speed[race][0][weapon][combo], m_speed[race][1][weapon][combo]);
}
dev_log(LOG_DEB0, "minspeed=%u", m_speed[race][0][weapon][0]);
}
return true;
}
DWORD ANI::attack_speed(int race, int weapon, BYTE combo, bool horse)
{
switch (race)
{
case MAIN_RACE_WARRIOR_M:
case MAIN_RACE_ASSASSIN_W:
case MAIN_RACE_SURA_M:
case MAIN_RACE_SHAMAN_W:
case MAIN_RACE_WARRIOR_W:
case MAIN_RACE_ASSASSIN_M:
case MAIN_RACE_SURA_W:
case MAIN_RACE_SHAMAN_M:
break;
default:
return 1000;
}
switch (weapon)
{
case WEAPON_SWORD:
case WEAPON_DAGGER:
case WEAPON_BOW:
case WEAPON_TWO_HANDED:
case WEAPON_BELL:
case WEAPON_FAN:
case WEAPON_ARROW:
case WEAPON_MOUNT_SPEAR:
break;
default:
return 1000;
}
return m_speed[race][horse ? 1 : 0][weapon][combo];
}
const char* FN_race_string(int race)
{
switch (race)
{
case MAIN_RACE_WARRIOR_M: return "WARRIOR_M";
case MAIN_RACE_ASSASSIN_W: return "ASSASSIN_W";
case MAIN_RACE_SURA_M: return "SURA_M";
case MAIN_RACE_SHAMAN_W: return "SHAMAN_W";
case MAIN_RACE_WARRIOR_W: return "WARRIOR_W";
case MAIN_RACE_ASSASSIN_M: return "ASSASSIN_M";
case MAIN_RACE_SURA_W: return "SURA_W";
case MAIN_RACE_SHAMAN_M: return "SHAMAN_M";
}
return "UNKNOWN_RACE";
}
const char* FN_weapon_string(int weapon)
{
switch (weapon)
{
case WEAPON_SWORD: return "SWORD";
case WEAPON_DAGGER: return "DAGGER";
case WEAPON_BOW: return "BOW";
case WEAPON_TWO_HANDED: return "TWO_HANDED";
case WEAPON_BELL: return "BELL";
case WEAPON_FAN: return "FAN";
case WEAPON_ARROW: return "ARROW";
case WEAPON_MOUNT_SPEAR:return "WEAPON_MOUNT_SPEAR";
}
return "UNKNOWN";
}
void ANI::print_attack_speed()
{
for (int race = 0; race < MAIN_RACE_MAX_NUM; ++race)
{
for (int weapon = 0; weapon < WEAPON_NUM_TYPES; ++weapon)
{
printf("[%s][%s] = %u\n",
FN_race_string(race),
FN_weapon_string(weapon),
attack_speed(race, weapon));
}
printf("\n");
}
}
void ani_init()
{
s_ANI.load();
}
DWORD ani_attack_speed(LPCHARACTER ch)
{
DWORD speed = 1000;
if (NULL == ch)
return speed;
LPITEM item = ch->GetWear(WEAR_WEAPON);
if (NULL == item)
return speed;
if (ITEM_WEAPON != item->GetType())
return speed;
int race = ch->GetRaceNum();
int weapon = item->GetSubType();
/*
dev_log(LOG_DEB0, "%s : (race,weapon) = (%s,%s) POINT_ATT_SPEED = %d",
ch->GetName(),
FN_race_name(race),
FN_weapon_type(weapon),
ch->GetPoint(POINT_ATT_SPEED));
*/
/* ÅõÇÚµðµå ¼ÒµåÀÇ °æ¿ì »ï¿¬Âü°ø°Ý°ú ½Â¸¶½Ã */
/* ¿À·ù°¡ ¸¹¾Æ ÇÑ¼Õ°Ë ¼Óµµ·Î »ý°¢ÇÏÀÚ */
if (weapon == WEAPON_TWO_HANDED)
weapon = WEAPON_SWORD;
return s_ANI.attack_speed(race, weapon);
}
DWORD ani_combo_speed(LPCHARACTER ch, BYTE combo)
{
LPITEM item = ch->GetWear(WEAR_WEAPON);
if (NULL == item || combo > 8)
return 1000;
return s_ANI.attack_speed(ch->GetRaceNum(), item->GetSubType(), combo, ch->IsRiding());
}
void ani_print_attack_speed()
{
s_ANI.print_attack_speed();
}
#if 0
int main(int argc, char **argv)
{
ani_init();
ani_print_attack_speed();
exit(0);
}
#endif