Skip to content

Commit

Permalink
Skill ID Processing Overhaul
Browse files Browse the repository at this point in the history
  • Loading branch information
shennetsind committed Apr 27, 2013
1 parent 1f6360f commit 0f4a50d
Show file tree
Hide file tree
Showing 16 changed files with 614 additions and 563 deletions.
4 changes: 0 additions & 4 deletions conf/battle/skill.conf
Expand Up @@ -234,10 +234,6 @@ emergency_call: 11
//16: Disable skill from affecting Guild Master
guild_aura: 31

// Max Possible Level of Monster skills
// Note: If your MVPs are too tough, reduce it to 10.
mob_max_skilllvl: 100

// Allows players to skip menu when casting Teleport level 1
// Menu contains two options. "Random" and "Cancel"
skip_teleport_lv1_menu: no
Expand Down
42 changes: 25 additions & 17 deletions src/char/char.c
Expand Up @@ -146,6 +146,8 @@ unsigned int save_flag = 0;
// Initial position (it's possible to set it in conf file)
struct point start_point = { 0, 53, 111 };

unsigned short skillid2idx[MAX_SKILL_ID];

//-----------------------------------------------------
// Auth database
//-----------------------------------------------------
Expand Down Expand Up @@ -565,18 +567,10 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
strcat(save_status, " memo");
}

//FIXME: is this neccessary? [ultramage]
for(i=0;i<MAX_SKILL;i++)
if ((p->skill[i].lv != 0) && (p->skill[i].id == 0))
p->skill[i].id = i; // Fix skill tree


//skills
if( memcmp(p->skill, cp->skill, sizeof(p->skill)) )
{
if( memcmp(p->skill, cp->skill, sizeof(p->skill)) ) {
//`skill` (`char_id`, `id`, `lv`)
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", skill_db, p->char_id) )
{
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", skill_db, p->char_id) ) {
Sql_ShowDebug(sql_handle);
errors++;
}
Expand Down Expand Up @@ -1278,10 +1272,9 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
if( tmp_skill.flag != SKILL_FLAG_PERM_GRANTED )
tmp_skill.flag = SKILL_FLAG_PERMANENT;

for( i = 0; i < MAX_SKILL && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
{
if( tmp_skill.id < ARRAYLENGTH(p->skill) )
memcpy(&p->skill[tmp_skill.id], &tmp_skill, sizeof(tmp_skill));
for( i = 0; i < MAX_SKILL && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i ) {
if( skillid2idx[tmp_skill.id] )
memcpy(&p->skill[skillid2idx[tmp_skill.id]], &tmp_skill, sizeof(tmp_skill));
else
ShowWarning("mmo_char_fromsql: ignoring invalid skill (id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", tmp_skill.id, tmp_skill.lv, p->name, p->account_id, p->char_id);
}
Expand Down Expand Up @@ -2702,7 +2695,22 @@ int parse_frommap(int fd)
RFIFOSKIP(fd,RFIFOW(fd,2));
break;


case 0x2b0b:
if( RFIFOREST(fd) < RFIFOW(fd, 2) )
return 0;
memset(&skillid2idx, 0, sizeof(skillid2idx));
j = RFIFOW(fd, 2) - 4;
if( j )
j /= 4;
for(i = 0; i < j; i++) {
if( RFIFOW(fd, 4 + (i*4)) > MAX_SKILL_ID ) {
ShowWarning("Error skillid2dx[%d] = %d failed, %d is higher than MAX_SKILL_ID (%d)\n",RFIFOW(fd, 4 + (i*4)), RFIFOW(fd, 6 + (i*4)),RFIFOW(fd, 4 + (i*4)),MAX_SKILL_ID);
continue;
}
skillid2idx[RFIFOW(fd, 4 + (i*4))] = RFIFOW(fd, 6 + (i*4));
}
RFIFOSKIP(fd, RFIFOW(fd, 2));
break;
case 0x2afa: // Receiving map names list from the map-server
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
return 0;
Expand Down Expand Up @@ -4920,8 +4928,8 @@ void do_shutdown(void)
}


int do_init(int argc, char **argv)
{
int do_init(int argc, char **argv) {
memset(&skillid2idx, 0, sizeof(skillid2idx));
//Read map indexes
mapindex_init();
start_point.map = mapindex_name2id("new_zone01");
Expand Down
3 changes: 2 additions & 1 deletion src/common/mmo.h
Expand Up @@ -79,7 +79,8 @@
#define MAX_ZENY 1000000000
#define MAX_FAME 1000000000
#define MAX_CART 100
#define MAX_SKILL 3100
#define MAX_SKILL 1460
#define MAX_SKILL_ID 10015 //[Ind/Hercules] max used skill id
#define GLOBAL_REG_NUM 256 // max permanent character variables per char
#define ACCOUNT_REG_NUM 64 // max permanent local account variables per account
#define ACCOUNT_REG2_NUM 16 // max permanent global account variables per account
Expand Down
31 changes: 16 additions & 15 deletions src/map/atcommand.c
Expand Up @@ -3111,7 +3111,7 @@ ACMD(allskill)
*------------------------------------------*/
ACMD(questskill)
{
uint16 skill_id;
uint16 skill_id, index;
nullpo_retr(-1, sd);

if (!message || !*message || (skill_id = atoi(message)) <= 0)
Expand All @@ -3131,15 +3131,15 @@ ACMD(questskill)

return false;
}
if (skill_id >= MAX_SKILL_DB) {
if( !(index = skill->get_index(skill_id)) ) {
clif->message(fd, msg_txt(198)); // This skill number doesn't exist.
return false;
}
if (!(skill->get_inf2(skill_id) & INF2_QUEST_SKILL)) {
clif->message(fd, msg_txt(197)); // This skill number doesn't exist or isn't a quest skill.
return false;
}
if (pc_checkskill(sd, skill_id) > 0) {
if (pc_checkskill2(sd, index) > 0) {
clif->message(fd, msg_txt(196)); // You already have this quest skill.
return false;
}
Expand All @@ -3155,7 +3155,7 @@ ACMD(questskill)
*------------------------------------------*/
ACMD(lostskill)
{
uint16 skill_id;
uint16 skill_id, index;
nullpo_retr(-1, sd);

if (!message || !*message || (skill_id = atoi(message)) <= 0)
Expand All @@ -3175,21 +3175,21 @@ ACMD(lostskill)

return false;
}
if (skill_id >= MAX_SKILL) {
if ( !( index = skill->get_index(skill_id) ) ) {
clif->message(fd, msg_txt(198)); // This skill number doesn't exist.
return false;
}
if (!(skill->get_inf2(skill_id) & INF2_QUEST_SKILL)) {
clif->message(fd, msg_txt(197)); // This skill number doesn't exist or isn't a quest skill.
return false;
}
if (pc_checkskill(sd, skill_id) == 0) {
if (pc_checkskill2(sd, index) == 0) {
clif->message(fd, msg_txt(201)); // You don't have this quest skill.
return false;
}

sd->status.skill[skill_id].lv = 0;
sd->status.skill[skill_id].flag = 0;
sd->status.skill[index].lv = 0;
sd->status.skill[index].flag = 0;
clif->deleteskill(sd,skill_id);
clif->message(fd, msg_txt(71)); // You have forgotten the skill.

Expand Down Expand Up @@ -8728,13 +8728,14 @@ ACMD(unloadnpcfile) {
return true;
}
ACMD(cart) {
#define MC_CART_MDFY(x) \
sd->status.skill[MC_PUSHCART].id = x?MC_PUSHCART:0; \
sd->status.skill[MC_PUSHCART].lv = x?1:0; \
sd->status.skill[MC_PUSHCART].flag = x?1:0;
#define MC_CART_MDFY(x,idx) \
sd->status.skill[idx].id = x?MC_PUSHCART:0; \
sd->status.skill[idx].lv = x?1:0; \
sd->status.skill[idx].flag = x?1:0;

int val = atoi(message);
bool need_skill = pc_checkskill(sd, MC_PUSHCART) ? false : true;
unsigned int index = skill->get_index(MC_PUSHCART);

if( !message || !*message || val < 0 || val > MAX_CARTS ) {
sprintf(atcmd_output, msg_txt(1390),command,MAX_CARTS); // Unknown Cart (usage: %s <0-%d>).
Expand All @@ -8748,18 +8749,18 @@ sd->status.skill[MC_PUSHCART].flag = x?1:0;
}

if( need_skill ) {
MC_CART_MDFY(1);
MC_CART_MDFY(1,index);
}

if( pc_setcart(sd, val) ) {
if( need_skill ) {
MC_CART_MDFY(0);
MC_CART_MDFY(0,index);
}
return false;/* @cart failed */
}

if( need_skill ) {
MC_CART_MDFY(0);
MC_CART_MDFY(0,index);
}

clif->message(fd, msg_txt(1392)); // Cart Added
Expand Down
5 changes: 2 additions & 3 deletions src/map/battle.c
Expand Up @@ -5047,9 +5047,9 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
if (sd) {
if( wd.flag&BF_SHORT && sc && sc->data[SC__AUTOSHADOWSPELL] && rnd()%100 < sc->data[SC__AUTOSHADOWSPELL]->val3 &&
sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].id != 0 && sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].flag == SKILL_FLAG_PLAGIARIZED )
sd->status.skill[skill->get_index(sc->data[SC__AUTOSHADOWSPELL]->val1)].id != 0 && sd->status.skill[skill->get_index(sc->data[SC__AUTOSHADOWSPELL]->val1)].flag == SKILL_FLAG_PLAGIARIZED )
{
int r_skill = sd->status.skill[sc->data[SC__AUTOSHADOWSPELL]->val1].id,
int r_skill = sd->status.skill[skill->get_index(sc->data[SC__AUTOSHADOWSPELL]->val1)].id,
r_lv = sc->data[SC__AUTOSHADOWSPELL]->val2;

if (r_skill != AL_HOLYLIGHT && r_skill != PR_MAGNUS) {
Expand Down Expand Up @@ -5849,7 +5849,6 @@ static const struct _battle_data {
{ "show_hp_sp_gain", &battle_config.show_hp_sp_gain, 1, 0, 1, },
{ "mob_npc_event_type", &battle_config.mob_npc_event_type, 1, 0, 1, },
{ "character_size", &battle_config.character_size, 1|2, 0, 1|2, },
{ "mob_max_skilllvl", &battle_config.mob_max_skilllvl, MAX_SKILL_LEVEL, 1, MAX_SKILL_LEVEL, },
{ "retaliate_to_master", &battle_config.retaliate_to_master, 1, 0, 1, },
{ "rare_drop_announce", &battle_config.rare_drop_announce, 0, 0, 10000, },
{ "duel_allow_pvp", &battle_config.duel_allow_pvp, 0, 0, 1, },
Expand Down
1 change: 0 additions & 1 deletion src/map/battle.h
Expand Up @@ -360,7 +360,6 @@ struct Battle_Config {
int mob_npc_event_type; //Determines on who the npc_event is executed. [Skotlex]

int character_size; // if riders have size=2, and baby class riders size=1 [Lupus]
int mob_max_skilllvl; // Max possible skill level [Lupus]
int rare_drop_announce; // chance <= to show rare drops global announces

int retaliate_to_master; //Whether when a mob is attacked by another mob, it will retaliate versus the mob or the mob's master. [Skotlex]
Expand Down
54 changes: 38 additions & 16 deletions src/map/chrif.c
Expand Up @@ -68,7 +68,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
//2b08: Outgoing, chrif_searchcharid -> '...'
//2b09: Incoming, map_addchariddb -> 'Adds a name to the nick db'
//2b0a: Incoming/Outgoing, socket_datasync()
//2b0b: FREE
//2b0b: Outgoing, update charserv skillid2idx
//2b0c: Outgoing, chrif_changeemail -> 'change mail address ...'
//2b0d: Incoming, chrif_changedsex -> 'Change sex of acc XY'
//2b0e: Outgoing, chrif_char_ask_name -> 'Do some operations (change sex, ban / unban etc)'
Expand Down Expand Up @@ -470,6 +470,7 @@ int chrif_connectack(int fd) {
}

socket_datasync(fd, true);
chrif_skillid2idx(fd);

return 0;
}
Expand Down Expand Up @@ -882,21 +883,23 @@ int chrif_changedsex(int fd) {

// reset skill of some job
if ((sd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER) {
int i;
int i, idx = 0;
// remove specifical skills of Bard classes
for(i = 315; i <= 322; i++) {
if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
sd->status.skill_point += sd->status.skill[i].lv;
sd->status.skill[i].id = 0;
sd->status.skill[i].lv = 0;
idx = skill->get_index(i);
if (sd->status.skill[idx].id > 0 && sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) {
sd->status.skill_point += sd->status.skill[idx].lv;
sd->status.skill[idx].id = 0;
sd->status.skill[idx].lv = 0;
}
}
// remove specifical skills of Dancer classes
for(i = 323; i <= 330; i++) {
if (sd->status.skill[i].id > 0 && sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
sd->status.skill_point += sd->status.skill[i].lv;
sd->status.skill[i].id = 0;
sd->status.skill[i].lv = 0;
idx = skill->get_index(i);
if (sd->status.skill[idx].id > 0 && sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) {
sd->status.skill_point += sd->status.skill[idx].lv;
sd->status.skill[idx].id = 0;
sd->status.skill[idx].lv = 0;
}
}
clif->updatestatus(sd, SP_SKILLPOINT);
Expand Down Expand Up @@ -963,20 +966,21 @@ int chrif_divorceack(int char_id, int partner_id) {
*------------------------------------------*/
int chrif_deadopt(int father_id, int mother_id, int child_id) {
struct map_session_data* sd;
int idx = skill->get_index(WE_CALLBABY);

if( father_id && ( sd = map_charid2sd(father_id) ) != NULL && sd->status.child == child_id ) {
sd->status.child = 0;
sd->status.skill[WE_CALLBABY].id = 0;
sd->status.skill[WE_CALLBABY].lv = 0;
sd->status.skill[WE_CALLBABY].flag = 0;
sd->status.skill[idx].id = 0;
sd->status.skill[idx].lv = 0;
sd->status.skill[idx].flag = 0;
clif->deleteskill(sd,WE_CALLBABY);
}

if( mother_id && ( sd = map_charid2sd(mother_id) ) != NULL && sd->status.child == child_id ) {
sd->status.child = 0;
sd->status.skill[WE_CALLBABY].id = 0;
sd->status.skill[WE_CALLBABY].lv = 0;
sd->status.skill[WE_CALLBABY].flag = 0;
sd->status.skill[idx].id = 0;
sd->status.skill[idx].lv = 0;
sd->status.skill[idx].flag = 0;
clif->deleteskill(sd,WE_CALLBABY);
}

Expand Down Expand Up @@ -1370,6 +1374,24 @@ void chrif_keepalive(int fd) {
void chrif_keepalive_ack(int fd) {
session[fd]->flag.ping = 0;/* reset ping state, we received a packet */
}
void chrif_skillid2idx(int fd) {
int i, count = 0;

if( fd == 0 ) fd = char_fd;

WFIFOHEAD(fd,4 + (MAX_SKILL * 4));
WFIFOW(fd,0) = 0x2b0b;
for(i = 0; i < MAX_SKILL; i++) {
if( skill_db[i].nameid ) {
WFIFOW(fd, 4 + (count*4)) = skill_db[i].nameid;
WFIFOW(fd, 6 + (count*4)) = i;
count++;
}
}
WFIFOW(fd,2) = 4 + (count * 4);
WFIFOSET(fd,4 + (count * 4));

}
/*==========================================
*
*------------------------------------------*/
Expand Down
6 changes: 4 additions & 2 deletions src/map/chrif.h
@@ -1,5 +1,6 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams

#ifndef _CHRIF_H_
#define _CHRIF_H_
Expand Down Expand Up @@ -65,5 +66,6 @@ int do_final_chrif(void);
int do_init_chrif(void);

int chrif_flush_fifo(void);
void chrif_skillid2idx(int fd);

#endif /* _CHRIF_H_ */

0 comments on commit 0f4a50d

Please sign in to comment.