diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/atcommand.c | 17 | ||||
-rw-r--r-- | src/map/battle.h | 1 | ||||
-rw-r--r-- | src/map/chrif.c | 6 | ||||
-rw-r--r-- | src/map/clif.c | 70 | ||||
-rw-r--r-- | src/map/clif.h | 1 | ||||
-rw-r--r-- | src/map/elemental.c | 2 | ||||
-rw-r--r-- | src/map/homunculus.h | 2 | ||||
-rw-r--r-- | src/map/mapreg_sql.c | 6 | ||||
-rw-r--r-- | src/map/mercenary.c | 2 | ||||
-rw-r--r-- | src/map/mercenary.h | 2 | ||||
-rw-r--r-- | src/map/mob.c | 2 | ||||
-rw-r--r-- | src/map/npc.c | 23 | ||||
-rw-r--r-- | src/map/npc.h | 3 | ||||
-rw-r--r-- | src/map/packets_struct.h | 13 | ||||
-rw-r--r-- | src/map/pc.c | 50 | ||||
-rw-r--r-- | src/map/pc.h | 2 | ||||
-rw-r--r-- | src/map/script.c | 218 | ||||
-rw-r--r-- | src/map/script.h | 27 | ||||
-rw-r--r-- | src/map/skill.c | 810 | ||||
-rw-r--r-- | src/map/skill.h | 108 | ||||
-rw-r--r-- | src/map/status.c | 16 | ||||
-rw-r--r-- | src/map/status.h | 2 |
22 files changed, 1059 insertions, 324 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c index d9f4810ee..1590c3f0c 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -5296,12 +5296,13 @@ ACMD(skillid) iter = db_iterator(skill->name2id_db); for (data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key)) { - int idx = skill->get_index(DB->data2i(data)); - if (strnicmp(key.str, message, skillen) == 0 || strnicmp(skill->dbs->db[idx].desc, message, skillen) == 0) { - safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1164), DB->data2i(data), skill->dbs->db[idx].desc, key.str); // skill %d: %s (%s) + int skill_id = DB->data2i(data); + const char *skill_desc = skill->get_desc(skill_id); + if (strnicmp(key.str, message, skillen) == 0 || strnicmp(skill_desc, message, skillen) == 0) { + safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 1164), skill_id, skill_desc, key.str); // skill %d: %s (%s) clif->message(fd, atcmd_output); - } else if ( found < MAX_SKILLID_PARTIAL_RESULTS && ( stristr(key.str,message) || stristr(skill->dbs->db[idx].desc,message) ) ) { - snprintf(partials[found], MAX_SKILLID_PARTIAL_RESULTS_LEN, msg_fd(fd,1164), DB->data2i(data), skill->dbs->db[idx].desc, key.str); + } else if (found < MAX_SKILLID_PARTIAL_RESULTS && (stristr(key.str, message) != NULL || stristr(skill_desc, message) != NULL)) { + snprintf(partials[found], MAX_SKILLID_PARTIAL_RESULTS_LEN, msg_fd(fd, 1164), skill_id, skill_desc, key.str); found++; } } @@ -5428,7 +5429,7 @@ ACMD(skilltree) for (j = 0; j < VECTOR_LENGTH(entry->need); j++) { struct skill_tree_requirement *req = &VECTOR_INDEX(entry->need, j); if (pc->checkskill(sd, req->id) < req->lv) { - safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1170), req->lv, skill->dbs->db[req->id].desc); // Player requires level %d of skill %s. + safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1170), req->lv, skill->get_desc(req->id)); // Player requires level %d of skill %s. clif->message(fd, atcmd_output); meets = 0; } @@ -8686,7 +8687,7 @@ ACMD(cart) { int val = atoi(message); bool need_skill = pc->checkskill(sd, MC_PUSHCART) ? false : true; - unsigned int index = skill->get_index(MC_PUSHCART); + int index = skill->get_index(MC_PUSHCART); if (!*message || val < 0 || val > MAX_CARTS) { safesnprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd,1390),command,MAX_CARTS); // Unknown Cart (usage: %s <0-%d>). @@ -9394,7 +9395,7 @@ ACMD(cddebug) { } if (!cd || (*message && !strcmpi(message,"reset"))) { - for(i = 0; i < MAX_SKILL; i++) { + for (i = 0; i < MAX_SKILL_DB; i++) { if( sd->blockskill[i] ) { clif->messages(fd,"Found skill '%s', unblocking...",skill->dbs->db[i].name); sd->blockskill[i] = false; diff --git a/src/map/battle.h b/src/map/battle.h index f6e825e82..429249dca 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -54,6 +54,7 @@ struct status_data; enum { // Flag of the final calculation + BF_NONE = 0x0000, BF_WEAPON = 0x0001, BF_MAGIC = 0x0002, BF_MISC = 0x0004, diff --git a/src/map/chrif.c b/src/map/chrif.c index 39aa046d7..96f144523 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -1360,10 +1360,10 @@ void chrif_skillid2idx(int fd) { if (!sockt->session_is_valid(fd)) return; - WFIFOHEAD(fd,4 + (MAX_SKILL * 4)); + WFIFOHEAD(fd,4 + (MAX_SKILL_DB * 4)); WFIFOW(fd,0) = 0x2b0b; - for(i = 0; i < MAX_SKILL; i++) { - if( skill->dbs->db[i].nameid ) { + for (i = 0; i < MAX_SKILL_DB; i++) { + if (skill->dbs->db[i].nameid != 0) { WFIFOW(fd, 4 + (count*4)) = skill->dbs->db[i].nameid; WFIFOW(fd, 6 + (count*4)) = i; count++; diff --git a/src/map/clif.c b/src/map/clif.c index eb6b46bec..5f7cf3b5d 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -293,7 +293,11 @@ unsigned char clif_bl_type(struct block_list *bl) case BL_NPC: vd = status->get_viewdata(bl); nullpo_retr(CLUT_NPC, vd); +#if PACKETVER >= 20170726 + return CLUT_EVENT; +#else return pc->db_checkid(vd->class) ? CLUT_PC : CLUT_EVENT; +#endif case BL_PET: vd = status->get_viewdata(bl); nullpo_retr(CLUT_NPC, vd); @@ -3341,17 +3345,22 @@ void clif_changelook(struct block_list *bl,int type,int val) #if PACKETVER < 4 clif->sendlook(bl, bl->id, type, val, 0, target); #else - if(type == LOOK_WEAPON || type == LOOK_SHIELD) { - nullpo_retv(vd); - type = LOOK_WEAPON; - val = vd->weapon; - val2 = vd->shield; - } - if (clif->isdisguised(bl)) { - clif->sendlook(bl, bl->id, type, val, val2, AREA_WOS); - clif->sendlook(bl, -bl->id, type, val, val2, SELF); + if (bl->type != BL_NPC) { + if(type == LOOK_WEAPON || type == LOOK_SHIELD) { + nullpo_retv(vd); + type = LOOK_WEAPON; + val = vd->weapon; + val2 = vd->shield; + } + if (clif->isdisguised(bl)) { + clif->sendlook(bl, bl->id, type, val, val2, AREA_WOS); + clif->sendlook(bl, -bl->id, type, val, val2, SELF); + } else { + clif->sendlook(bl, bl->id, type, val, val2, target); + } } else { - clif->sendlook(bl, bl->id, type, val, val2, target); + struct npc_data *nd = BL_UCAST(BL_NPC, bl); + npc->refresh(nd); } #endif } @@ -4857,9 +4866,9 @@ void clif_skillinfoblock(struct map_session_data *sd) fd=sd->fd; if (!fd) return; - WFIFOHEAD(fd, MAX_SKILL * 37 + 4); + WFIFOHEAD(fd, MAX_SKILL_DB * 37 + 4); WFIFOW(fd,0) = 0x10f; - for ( i = 0, len = 4; i < MAX_SKILL; i++) { + for ( i = 0, len = 4; i < MAX_SKILL_DB; i++) { if( (id = sd->status.skill[i].id) != 0 ) { int level; // workaround for bugreport:5348 @@ -4890,7 +4899,7 @@ void clif_skillinfoblock(struct map_session_data *sd) WFIFOSET(fd,len); // workaround for bugreport:5348; send the remaining skills one by one to bypass packet size limit - for ( ; i < MAX_SKILL; i++) { + for ( ; i < MAX_SKILL_DB; i++) { if( (id = sd->status.skill[i].id) != 0 ) { clif->addskill(sd, id); clif->skillinfo(sd, id, 0); @@ -4992,7 +5001,7 @@ void clif_skillinfo(struct map_session_data *sd,int skill_id, int inf) int skill_lv; nullpo_retv(sd); - Assert_retv(idx >= 0 && idx < MAX_SKILL); + Assert_retv(idx >= 0 && idx < MAX_SKILL_DB); skill_lv = sd->status.skill[idx].lv; @@ -5059,6 +5068,10 @@ void clif_useskill(struct block_list* bl, int src_id, int dst_id, int dst_x, int } else { clif->send(buf,packet_len(cmd), bl, AREA); } +#if PACKETVER >= 20151223 + if ((skill->get_inf2(skill_id) & INF2_SHOW_SKILL_SCALE) != 0) + clif->skill_scale(bl, src_id, bl->x, bl->y, skill_id, skill_lv, casttime); +#endif } /// Notifies clients in area, that an object canceled casting (ZC_DISPEL). @@ -17647,7 +17660,7 @@ int clif_autoshadowspell_list(struct map_session_data *sd) { WFIFOHEAD(fd, 2 * 6 + 4); WFIFOW(fd,0) = 0x442; - for( i = 0, c = 0; i < MAX_SKILL; i++ ) + for (i = 0, c = 0; i < MAX_SKILL_DB; i++) if( sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED && sd->status.skill[i].id > 0 && sd->status.skill[i].id < GS_GLITTERING && skill->get_type(sd->status.skill[i].id) == BF_MAGIC ) { // Can't auto cast both Extended class and 3rd class skills. @@ -19865,6 +19878,32 @@ void clif_parse_rodex_cancel_write_mail(int fd, struct map_session_data *sd) rodex->clean(sd, 1); } +void clif_skill_scale(struct block_list *bl, int src_id, int x, int y, uint16 skill_id, uint16 skill_lv, int casttime) +{ +#if PACKETVER >= 20151223 + struct PACKET_ZC_SKILL_SCALE p; + + p.PacketType = skillscale; + p.AID = src_id; + p.skill_id = skill_id; + p.skill_lv = skill_lv; + p.x = x; + p.y = y; + p.casttime = casttime; + + if (clif->isdisguised(bl)) { + clif->send(&p, sizeof(p), bl, AREA_WOS); + p.AID = -src_id; + clif->send(&p, sizeof(p), bl, SELF); + } else { + clif->send(&p, sizeof(p), bl, AREA); + } +#else + ShowWarning("clif_skill_scale: showing skill scale available only for clients >= 20151223."); + return; +#endif +} + /*========================================== * Main client packet processing function *------------------------------------------*/ @@ -20934,4 +20973,5 @@ void clif_defaults(void) { clif->rodex_request_items = clif_rodex_request_items; clif->rodex_icon = clif_rodex_icon; clif->rodex_send_mails_all = clif_rodex_send_mails_all; + clif->skill_scale = clif_skill_scale; } diff --git a/src/map/clif.h b/src/map/clif.h index c321b99d7..e348bbb08 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -1403,6 +1403,7 @@ struct clif_interface { void (*pRodexRequestItems) (int fd, struct map_session_data *sd); void (*rodex_request_items) (struct map_session_data *sd, int8 opentype, int64 mail_id, int8 result); void (*rodex_icon) (int fd, bool show); + void (*skill_scale) (struct block_list *bl, int src_id, int x, int y, uint16 skill_id, uint16 skill_lv, int casttime); }; #ifdef HERCULES_CORE diff --git a/src/map/elemental.c b/src/map/elemental.c index ae1fda0a2..cf1d485e1 100644 --- a/src/map/elemental.c +++ b/src/map/elemental.c @@ -885,7 +885,7 @@ int read_elementaldb(void) { estatus->race = atoi(str[20]); ele = atoi(str[21]); - estatus->def_ele = ele%10; + estatus->def_ele = ele % ELE_MAX; estatus->ele_lv = ele/20; if( estatus->def_ele >= ELE_MAX ) { ShowWarning("Elemental %d has invalid element type %d (max element is %d)\n", db->class_, estatus->def_ele, ELE_MAX - 1); diff --git a/src/map/homunculus.h b/src/map/homunculus.h index a80392cf6..f3b10fc19 100644 --- a/src/map/homunculus.h +++ b/src/map/homunculus.h @@ -124,7 +124,7 @@ struct homun_data { struct map_session_data *master; //pointer back to its master int hungry_timer; //[orn] unsigned int exp_next; - char blockskill[MAX_SKILL]; // [orn] + char blockskill[MAX_SKILL_DB]; // [orn] int64 masterteleport_timer; }; diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c index 4cdb91b21..02015e011 100644 --- a/src/map/mapreg_sql.c +++ b/src/map/mapreg_sql.c @@ -211,9 +211,9 @@ void script_load_mapreg(void) { mapreg->skip_insert = true; - SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &varname[0], sizeof(varname), &length, NULL); - SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &index, 0, NULL, NULL); - SQL->StmtBindColumn(stmt, 2, SQLDT_STRING, &value[0], sizeof(value), NULL, NULL); + SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &varname, sizeof varname, &length, NULL); + SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &index, sizeof index, NULL, NULL); + SQL->StmtBindColumn(stmt, 2, SQLDT_STRING, &value, sizeof value, NULL, NULL); while ( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) { int s = script->add_str(varname); diff --git a/src/map/mercenary.c b/src/map/mercenary.c index f5d3fe11c..c4b692008 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -465,7 +465,7 @@ bool read_mercenarydb_sub(char* str[], int columns, int current) { mstatus->race = atoi(str[20]); ele = atoi(str[21]); - mstatus->def_ele = ele%10; + mstatus->def_ele = ele % ELE_MAX; mstatus->ele_lv = ele/20; if( mstatus->def_ele >= ELE_MAX ) { ShowWarning("Mercenary %d has invalid element type %d (max element is %d)\n", db->class_, mstatus->def_ele, ELE_MAX - 1); diff --git a/src/map/mercenary.h b/src/map/mercenary.h index 0af75e8a2..f3773f191 100644 --- a/src/map/mercenary.h +++ b/src/map/mercenary.h @@ -92,7 +92,7 @@ struct mercenary_data { struct regen_data regen; struct s_mercenary_db *db; struct s_mercenary mercenary; - char blockskill[MAX_SKILL]; + char blockskill[MAX_SKILL_DB]; struct map_session_data *master; int contract_timer; diff --git a/src/map/mob.c b/src/map/mob.c index 208617b5d..f509ecace 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -4846,7 +4846,7 @@ bool mob_parse_row_mobskilldb(char** str, int columns, int current) struct mob_skill *ms, gms; int mob_id; int i =0, j, tmp; - uint16 sidx = 0; + int sidx = 0; nullpo_retr(false, str); mob_id = atoi(str[0]); diff --git a/src/map/npc.c b/src/map/npc.c index de5335302..d3dfb39d2 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -114,6 +114,8 @@ bool npc_db_checkid(int id) return true; if (id >= MAX_NPC_CLASS2_START && id < MAX_NPC_CLASS2_END) // Second range return true; + if (pc->db_checkid(id)) + return true; // Anything else is invalid return false; } @@ -1558,9 +1560,9 @@ void npc_market_fromsql(void) return; } - SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &name[0], sizeof(name), NULL, NULL); - SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &itemid, 0, NULL, NULL); - SQL->StmtBindColumn(stmt, 2, SQLDT_INT, &amount, 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &name, sizeof name, NULL, NULL); + SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &itemid, sizeof itemid, NULL, NULL); + SQL->StmtBindColumn(stmt, 2, SQLDT_INT, &amount, sizeof amount, NULL, NULL); while ( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) { struct npc_data *nd = NULL; @@ -2706,6 +2708,7 @@ struct npc_data *npc_create_npc(enum npc_subtype subtype, int m, int x, int y, u nd->area_size = AREA_SIZE + 1; nd->class_ = class_; nd->speed = 200; + nd->vd = npc_viewdb[0]; // Copy INVISIBLE_CLASS view data. Actual view data is set by npc->add_to_location() later. return nd; } @@ -3656,6 +3659,18 @@ void npc_setclass(struct npc_data* nd, short class_) { clif->spawn(&nd->bl);// fade in } +void npc_refresh(struct npc_data* nd) +{ + nullpo_retv(nd); + + if (map->list[nd->bl.m].users) { + // using here CLR_TRICKDEAD because other flags show effects. + // probably need use other flag or other way to refresh npc. + clif->clearunit_area(&nd->bl, CLR_TRICKDEAD); // fade out + clif->spawn(&nd->bl); // fade in + } +} + // @commands (script based) int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const char* message, const char* eventname) { @@ -4999,7 +5014,6 @@ int do_init_npc(bool minimal) { npc_viewdb[i].class = i; for( i = MAX_NPC_CLASS2_START; i < MAX_NPC_CLASS2_END; i++ ) npc_viewdb2[i - MAX_NPC_CLASS2_START].class = i; - npc->ev_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, EVENT_NAME_LENGTH); npc->ev_label_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, NAME_LENGTH); npc->name_db = strdb_alloc(DB_OPT_BASE, NAME_LENGTH); @@ -5194,4 +5208,5 @@ void npc_defaults(void) { npc->market_delfromsql = npc_market_delfromsql; npc->market_delfromsql_sub = npc_market_delfromsql_sub; npc->db_checkid = npc_db_checkid; + npc->refresh = npc_refresh; } diff --git a/src/map/npc.h b/src/map/npc.h index 3bd11d536..8bb38f252 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -70,7 +70,7 @@ struct npc_parse; struct npc_data { struct block_list bl; struct unit_data *ud; - struct view_data *vd; + struct view_data vd; unsigned int option; struct npc_data *master_nd; short class_; @@ -309,6 +309,7 @@ struct npc_interface { void (*market_delfromsql) (struct npc_data *nd, unsigned short index); void (*market_delfromsql_sub) (const char *npcname, unsigned short index); bool (*db_checkid) (const int id); + void (*refresh) (struct npc_data* nd); /** * For the Secure NPC Timeout option (check config/Secure.h) [RR] **/ diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index 03b555e2b..e1395e949 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -330,6 +330,9 @@ enum packet_headers { #else // PACKETVER >= 20160316 rodexcheckplayer = 0x0A51, #endif +#if PACKETVER >= 20151223 + skillscale = 0xA41, +#endif }; #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute @@ -1478,6 +1481,16 @@ struct PACKET_ZC_ACK_ITEM_FROM_MAIL { int8 result; } __attribute__((packed)); +struct PACKET_ZC_SKILL_SCALE { + int16 PacketType; + uint32 AID; + int16 skill_id; + int16 skill_lv; + int16 x; + int16 y; + uint32 casttime; +} __attribute__((packed)); + #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute #pragma pack(pop) #endif // not NetBSD < 6 / Solaris diff --git a/src/map/pc.c b/src/map/pc.c index 0636ebafa..d5d359557 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1560,7 +1560,7 @@ int pc_calc_skillpoint(struct map_session_data* sd) { nullpo_ret(sd); - for (i = 1; i < MAX_SKILL; i++) { + for (i = 1; i < MAX_SKILL_DB; i++) { int skill_lv = pc->checkskill2(sd,i); if (skill_lv > 0) { inf2 = skill->dbs->db[i].inf2; @@ -1596,7 +1596,7 @@ int pc_calc_skilltree(struct map_session_data *sd) } classidx = pc->class2idx(class); - for( i = 0; i < MAX_SKILL; i++ ) { + for (i = 0; i < MAX_SKILL_DB; i++) { if( sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED ) //Don't touch these sd->status.skill[i].id = 0; //First clear skills. /* permanent skills that must be re-checked */ @@ -1613,7 +1613,7 @@ int pc_calc_skilltree(struct map_session_data *sd) } } - for( i = 0; i < MAX_SKILL; i++ ) { + for (i = 0; i < MAX_SKILL_DB; i++) { if( sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED ) { // Restore original level of skills after deleting earned skills. sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0; @@ -1622,18 +1622,25 @@ int pc_calc_skilltree(struct map_session_data *sd) if( sd->sc.count && sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_BARDDANCER && skill->dbs->db[i].nameid >= DC_HUMMING && skill->dbs->db[i].nameid <= DC_SERVICEFORYOU ) { //Enable Bard/Dancer spirit linked skills. - if( sd->status.sex ) - { //Link dancer skills to bard. - // i can be < 8? - if( sd->status.skill[i-8].lv < 10 ) + if (sd->status.sex) { + // Link dancer skills to bard. + if (i < 8) { + Assert_report(i >= 8); + continue; + } + if (sd->status.skill[i-8].lv < 10) continue; sd->status.skill[i].id = skill->dbs->db[i].nameid; sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill - } else { //Link bard skills to dancer. - if( sd->status.skill[i].lv < 10 ) + } else { + // Link bard skills to dancer. + if (i < 8) { + Assert_report(i >= 8); + continue; + } + if (sd->status.skill[i].lv < 10) continue; - // i can be < 8? sd->status.skill[i-8].id = skill->dbs->db[i-8].nameid; sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill @@ -1642,7 +1649,7 @@ int pc_calc_skilltree(struct map_session_data *sd) } if( pc_has_permission(sd, PC_PERM_ALL_SKILL) ) { - for( i = 0; i < MAX_SKILL; i++ ) { + for (i = 0; i < MAX_SKILL_DB; i++) { switch(skill->dbs->db[i].nameid) { /** * Dummy skills must be added here otherwise they'll be displayed in the, @@ -1836,7 +1843,7 @@ int pc_clean_skilltree(struct map_session_data *sd) { int i; nullpo_ret(sd); - for (i = 0; i < MAX_SKILL; i++){ + for (i = 0; i < MAX_SKILL_DB; i++) { if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED) { sd->status.skill[i].id = 0; sd->status.skill[i].lv = 0; @@ -4143,7 +4150,7 @@ int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4 *------------------------------------------*/ int pc_skill(struct map_session_data *sd, int id, int level, int flag) { - uint16 index = 0; + int index = 0; nullpo_ret(sd); if (!(index = skill->get_index(id))) { @@ -5869,7 +5876,7 @@ int pc_memo(struct map_session_data* sd, int pos) { * Return player sd skill_lv learned for given skill *------------------------------------------*/ int pc_checkskill(struct map_session_data *sd,uint16 skill_id) { - uint16 index = 0; + int index = 0; if(sd == NULL) return 0; if( skill_id >= GD_SKILLBASE && skill_id < GD_MAX ) { struct guild *g; @@ -5888,8 +5895,9 @@ int pc_checkskill(struct map_session_data *sd,uint16 skill_id) { return 0; } int pc_checkskill2(struct map_session_data *sd,uint16 index) { - if(sd == NULL) return 0; - if(index >= ARRAYLENGTH(sd->status.skill) ) { + if (sd == NULL) + return 0; + if (index >= MAX_SKILL_DB) { ShowError("pc_checkskill: Invalid skill index %d (char_id=%d).\n", index, sd->status.char_id); return 0; } @@ -7229,7 +7237,7 @@ int pc_statusup2(struct map_session_data* sd, int type, int val) * Skill point allocation *------------------------------------------*/ int pc_skillup(struct map_session_data *sd,uint16 skill_id) { - uint16 index = 0; + int index = 0; nullpo_ret(sd); if( skill_id >= GD_SKILLBASE && skill_id < GD_SKILLBASE+MAX_GUILDSKILL ) { @@ -7286,7 +7294,7 @@ int pc_allskillup(struct map_session_data *sd) nullpo_ret(sd); - for(i=0;i<MAX_SKILL;i++){ + for (i = 0; i < MAX_SKILL_DB; i++) { if (sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED) { sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0; sd->status.skill[i].flag = SKILL_FLAG_PERMANENT; @@ -7297,7 +7305,7 @@ int pc_allskillup(struct map_session_data *sd) if (pc_has_permission(sd, PC_PERM_ALL_SKILL)) { //Get ALL skills except npc/guild ones. [Skotlex] //and except SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage] - for(i=0;i<MAX_SKILL;i++){ + for (i = 0; i < MAX_SKILL_DB; i++) { switch( skill->dbs->db[i].nameid ) { case SG_DEVIL: case MO_TRIPLEATTACK: @@ -7537,9 +7545,7 @@ int pc_resetskill(struct map_session_data* sd, int flag) status_change_end(&sd->bl, SC_SPRITEMABLE, INVALID_TIMER); } - for( i = 1; i < MAX_SKILL; i++ ) { - // FIXME: We're looping on i = [1..MAX_SKILL-1] (which makes sense as index for sd->status.skill[]) but then we're using the - // same i to access skill->dbs->db[], and especially to check skill_ischangesex(). This is wrong. + for (i = 1; i < MAX_SKILL_DB; i++) { uint16 skill_id = 0; int lv = sd->status.skill[i].lv; if (lv < 1) continue; diff --git a/src/map/pc.h b/src/map/pc.h index 50cb1b68e..df0df979d 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -292,7 +292,7 @@ struct map_session_data { uint16 skill_id_old,skill_lv_old; uint16 skill_id_dance,skill_lv_dance; short cook_mastery; // range: [0,1999] [Inkfish] - bool blockskill[MAX_SKILL]; + bool blockskill[MAX_SKILL_DB]; int cloneskill_id, reproduceskill_id; int menuskill_id, menuskill_val, menuskill_val2; int invincible_timer; diff --git a/src/map/script.c b/src/map/script.c index 2d4f60f37..7f7aba183 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -12190,7 +12190,7 @@ BUILDIN(homunculus_mutate) if (script_hasdata(st,2)) homun_id = script_getnum(st,2); else - homun_id = 6048 + (rnd() % 4); + homun_id = HOMID_EIRA + (rnd() % 4); m_class = homun->class2type(sd->hd->homunculus.class_); m_id = homun->class2type(homun_id); @@ -14081,53 +14081,61 @@ BUILDIN(getiteminfo) } switch (n) { - case 0: + case ITEMINFO_BUYPRICE: script_pushint(st, it->value_buy); break; - case 1: + case ITEMINFO_SELLPRICE: script_pushint(st, it->value_sell); break; - case 2: + case ITEMINFO_TYPE: script_pushint(st, it->type); break; - case 3: + case ITEMINFO_MAXCHANCE: script_pushint(st, it->maxchance); break; - case 4: + case ITEMINFO_SEX: script_pushint(st, it->sex); break; - case 5: + case ITEMINFO_LOC: script_pushint(st, it->equip); break; - case 6: + case ITEMINFO_WEIGHT: script_pushint(st, it->weight); break; - case 7: + case ITEMINFO_ATK: script_pushint(st, it->atk); break; - case 8: + case ITEMINFO_DEF: script_pushint(st, it->def); break; - case 9: + case ITEMINFO_RANGE: script_pushint(st, it->range); break; - case 10: + case ITEMINFO_SLOTS: script_pushint(st, it->slot); break; - case 11: + case ITEMINFO_SUBTYPE: script_pushint(st, it->subtype); break; - case 12: + case ITEMINFO_ELV: script_pushint(st, it->elv); break; - case 13: + case ITEMINFO_WLV: script_pushint(st, it->wlv); break; - case 14: + case ITEMINFO_VIEWID: script_pushint(st, it->view_id); break; + case ITEMINFO_MATK: + script_pushint(st, it->matk); + break; + case ITEMINFO_VIEWSPRITE: + script_pushint(st, it->view_sprite); + break; default: + ShowError("buildin_getiteminfo: Invalid item type %d.\n", n); script_pushint(st,-1); + return false; } return true; } @@ -14339,54 +14347,61 @@ BUILDIN(setiteminfo) } switch (n) { - case 0: + case ITEMINFO_BUYPRICE: it->value_buy = value; break; - case 1: + case ITEMINFO_SELLPRICE: it->value_sell = value; break; - case 2: + case ITEMINFO_TYPE: it->type = value; break; - case 3: + case ITEMINFO_MAXCHANCE: it->maxchance = value; break; - case 4: + case ITEMINFO_SEX: it->sex = value; break; - case 5: + case ITEMINFO_LOC: it->equip = value; break; - case 6: + case ITEMINFO_WEIGHT: it->weight = value; break; - case 7: + case ITEMINFO_ATK: it->atk = value; break; - case 8: + case ITEMINFO_DEF: it->def = value; break; - case 9: + case ITEMINFO_RANGE: it->range = value; break; - case 10: + case ITEMINFO_SLOTS: it->slot = value; break; - case 11: + case ITEMINFO_SUBTYPE: it->subtype = value; break; - case 12: + case ITEMINFO_ELV: it->elv = value; break; - case 13: + case ITEMINFO_WLV: it->wlv = value; break; - case 14: + case ITEMINFO_VIEWID: it->view_id = value; break; + case ITEMINFO_MATK: + it->matk = value; + break; + case ITEMINFO_VIEWSPRITE: + it->view_sprite = value; + break; default: + ShowError("buildin_setiteminfo: invalid type %d.\n", n); script_pushint(st,-1); - return true; + return false; } script_pushint(st,value); return true; @@ -14590,7 +14605,7 @@ BUILDIN(getskilllist) int i,j=0; if (sd == NULL) return true; - for(i=0;i<MAX_SKILL;i++) { + for (i = 0; i < MAX_SKILL_DB; i++) { if(sd->status.skill[i].id > 0 && sd->status.skill[i].lv > 0) { pc->setreg(sd,reference_uid(script->add_str("@skilllist_id"), j),sd->status.skill[i].id); pc->setreg(sd,reference_uid(script->add_str("@skilllist_lv"), j),sd->status.skill[i].lv); @@ -18217,6 +18232,8 @@ BUILDIN(setunitdata) case UDT_INTIMACY: case UDT_LIFETIME: case UDT_MERC_KILLCOUNT: + case UDT_ROBE: + case UDT_BODY2: setunitdata_check_min(4, 0); break; case UDT_MASTERAID: @@ -19155,6 +19172,40 @@ BUILDIN(setunitdata) case UDT_DMOTION: nd->status.dmotion = (unsigned short) val; break; + case UDT_SEX: + nd->vd.sex = (char)val; + npc->refresh(nd); + break; + case UDT_HAIRSTYLE: + clif->changelook(bl, LOOK_HAIR, val); + break; + case UDT_HAIRCOLOR: + clif->changelook(bl, LOOK_HAIR_COLOR, val); + break; + case UDT_HEADBOTTOM: + clif->changelook(bl, LOOK_HEAD_BOTTOM, val); + break; + case UDT_HEADMIDDLE: + clif->changelook(bl, LOOK_HEAD_MID, val); + break; + case UDT_HEADTOP: + clif->changelook(bl, LOOK_HEAD_TOP, val); + break; + case UDT_CLOTHCOLOR: + clif->changelook(bl, LOOK_CLOTHES_COLOR, val); + break; + case UDT_SHIELD: + clif->changelook(bl, LOOK_SHIELD, val); + break; + case UDT_WEAPON: + clif->changelook(bl, LOOK_WEAPON, val); + break; + case UDT_ROBE: + clif->changelook(bl, LOOK_ROBE, val); + break; + case UDT_BODY2: + clif->changelook(bl, LOOK_BODY2, val); + break; default: ShowWarning("buildin_setunitdata: Invalid data type '%s' for NPC unit.\n", udtype); script_pushint(st, 0); @@ -19565,6 +19616,18 @@ BUILDIN(getunitdata) case UDT_AMOTION: script_pushint(st, nd->status.amotion); break; case UDT_ADELAY: script_pushint(st, nd->status.adelay); break; case UDT_DMOTION: script_pushint(st, nd->status.dmotion); break; + case UDT_SEX: script_pushint(st, nd->vd.sex); break; + case UDT_CLASS: script_pushint(st, nd->vd.class); break; + case UDT_HAIRSTYLE: script_pushint(st, nd->vd.hair_style); break; + case UDT_HAIRCOLOR: script_pushint(st, nd->vd.hair_color); break; + case UDT_HEADBOTTOM: script_pushint(st, nd->vd.head_bottom); break; + case UDT_HEADMIDDLE: script_pushint(st, nd->vd.head_mid); break; + case UDT_HEADTOP: script_pushint(st, nd->vd.head_top); break; + case UDT_CLOTHCOLOR: script_pushint(st, nd->vd.cloth_color); break; + case UDT_SHIELD: script_pushint(st, nd->vd.shield); break; + case UDT_WEAPON: script_pushint(st, nd->vd.weapon); break; + case UDT_ROBE: script_pushint(st, nd->vd.robe); break; + case UDT_BODY2: script_pushint(st, nd->vd.body_style); break; default: ShowWarning("buildin_getunitdata: Invalid data type '%s' for NPC unit.\n", udtype); script_pushint(st, 0); @@ -21140,72 +21203,90 @@ BUILDIN(has_instance) const char *str; int16 m; int instance_id = -1; + int i = 0, j = 0; bool type = strcmp(script->getfuncname(st),"has_instance2") == 0 ? true : false; str = script_getstr(st, 2); - if( (m = map->mapname2mapid(str)) < 0 ) { - if( type ) + if ((m = map->mapname2mapid(str)) < 0) { + if (type) { script_pushint(st, -1); - else + } else { script_pushconststr(st, ""); + } return true; } - if( script_hasdata(st, 3) ) + if (script_hasdata(st, 3)) instance_id = script_getnum(st, 3); - else if( st->instance_id >= 0 ) + else if (st->instance_id >= 0) instance_id = st->instance_id; - else if( (sd = script->rid2sd(st)) != NULL ) { + else if ((sd = script->rid2sd(st)) != NULL) { struct party_data *p; - int i = 0, j = 0; - if( sd->instances ) { - for( i = 0; i < sd->instances; i++ ) { - if( sd->instance[i] >= 0 ) { + if (sd->instances) { + for (i = 0; i < sd->instances; i++) { + if (sd->instance[i] >= 0) { ARR_FIND(0, instance->list[sd->instance[i]].num_map, j, map->list[instance->list[sd->instance[i]].map[j]].instance_src_map == m); - if( j != instance->list[sd->instance[i]].num_map ) + if (j != instance->list[sd->instance[i]].num_map) break; } } - if( i != sd->instances ) + if (i != sd->instances) { instance_id = sd->instance[i]; + } } if (instance_id == -1 && sd->status.party_id && (p = party->search(sd->status.party_id)) != NULL && p->instances) { - for( i = 0; i < p->instances; i++ ) { - if( p->instance[i] >= 0 ) { + for (i = 0; i < p->instances; i++) { + if (p->instance[i] >= 0) { ARR_FIND(0, instance->list[p->instance[i]].num_map, j, map->list[instance->list[p->instance[i]].map[j]].instance_src_map == m); - if( j != instance->list[p->instance[i]].num_map ) + if (j != instance->list[p->instance[i]].num_map) break; } } - if( i != p->instances ) + if (i != p->instances) { instance_id = p->instance[i]; + } } - if( instance_id == -1 && sd->guild && sd->guild->instances ) { - for( i = 0; i < sd->guild->instances; i++ ) { - if( sd->guild->instance[i] >= 0 ) { + if (instance_id == -1 && sd->guild && sd->guild->instances) { + for (i = 0; i < sd->guild->instances; i++) { + if (sd->guild->instance[i] >= 0) { ARR_FIND(0, instance->list[sd->guild->instance[i]].num_map, j, map->list[instance->list[sd->guild->instance[i]].map[j]].instance_src_map == m); - if( j != instance->list[sd->guild->instance[i]].num_map ) + if (j != instance->list[sd->guild->instance[i]].num_map) break; } } - if( i != sd->guild->instances ) + if (i != sd->guild->instances) instance_id = sd->guild->instance[i]; } } - if( !instance->valid(instance_id) || (m = instance->map2imap(m, instance_id)) < 0 ) { - if( type ) + if (instance_id == -1) { + for (i = 0; i < instance->instances; i++) { + if (instance->list[i].state != INSTANCE_FREE && instance->list[i].owner_type == IOT_NONE && instance->list[i].num_map > 0) { + ARR_FIND(0, instance->list[i].num_map, j, map->list[instance->list[i].map[j]].instance_src_map == m); + if (j != instance->list[i].num_map) + break; + } + } + if (i != instance->instances) { + instance_id = instance->list[i].id; + } + } + + if (!instance->valid(instance_id) || (m = instance->map2imap(m, instance_id)) < 0) { + if (type) { script_pushint(st, -1); - else + } else { script_pushconststr(st, ""); + } return true; } - if( type ) + if (type) { script_pushint(st, instance_id); - else + } else { script_pushconststr(st, map->list[m].name); + } return true; } @@ -24763,6 +24844,25 @@ void script_hardcoded_constants(void) script->set_constant("MAPINFO_SIZE_Y", MAPINFO_SIZE_Y, false, false); script->set_constant("MAPINFO_ZONE", MAPINFO_ZONE, false, false); + script->constdb_comment("set/getiteminfo options"); + script->set_constant("ITEMINFO_BUYPRICE", ITEMINFO_BUYPRICE, false, false); + script->set_constant("ITEMINFO_SELLPRICE", ITEMINFO_SELLPRICE, false, false); + script->set_constant("ITEMINFO_TYPE", ITEMINFO_TYPE, false, false); + script->set_constant("ITEMINFO_MAXCHANCE", ITEMINFO_MAXCHANCE, false, false); + script->set_constant("ITEMINFO_SEX", ITEMINFO_SEX, false, false); + script->set_constant("ITEMINFO_LOC", ITEMINFO_LOC, false, false); + script->set_constant("ITEMINFO_WEIGHT", ITEMINFO_WEIGHT, false, false); + script->set_constant("ITEMINFO_ATK", ITEMINFO_ATK, false, false); + script->set_constant("ITEMINFO_DEF", ITEMINFO_DEF, false, false); + script->set_constant("ITEMINFO_RANGE", ITEMINFO_RANGE, false, false); + script->set_constant("ITEMINFO_SLOTS", ITEMINFO_SLOTS, false, false); + script->set_constant("ITEMINFO_SUBTYPE", ITEMINFO_SUBTYPE, false, false); + script->set_constant("ITEMINFO_ELV", ITEMINFO_ELV, false, false); + script->set_constant("ITEMINFO_WLV", ITEMINFO_WLV, false, false); + script->set_constant("ITEMINFO_VIEWID", ITEMINFO_VIEWID, false, false); + script->set_constant("ITEMINFO_MATK", ITEMINFO_MATK, false, false); + script->set_constant("ITEMINFO_VIEWSPRITE", ITEMINFO_VIEWSPRITE, false, false); + script->constdb_comment("Renewal"); #ifdef RENEWAL script->set_constant("RENEWAL", 1, false, false); diff --git a/src/map/script.h b/src/map/script.h index 283afa496..14d20838d 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -423,10 +423,37 @@ enum script_unit_data_types { UDT_LIFETIME, UDT_MERC_KILLCOUNT, UDT_STATPOINT, + UDT_ROBE, + UDT_BODY2, UDT_MAX }; /** + * Item Info types. + */ +enum script_iteminfo_types { + ITEMINFO_BUYPRICE = 0, + ITEMINFO_SELLPRICE, + ITEMINFO_TYPE, + ITEMINFO_MAXCHANCE, + ITEMINFO_SEX, + ITEMINFO_LOC, + ITEMINFO_WEIGHT, + ITEMINFO_ATK, + ITEMINFO_DEF, + ITEMINFO_RANGE, + ITEMINFO_SLOTS, + ITEMINFO_SUBTYPE, + ITEMINFO_ELV, + ITEMINFO_WLV, + ITEMINFO_VIEWID, + ITEMINFO_MATK, + ITEMINFO_VIEWSPRITE, + + ITEMINFO_MAX +}; + +/** * Structures **/ diff --git a/src/map/skill.c b/src/map/skill.c index 726deaa9a..88a29b9a8 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -105,7 +105,7 @@ int skill_name2id(const char* name) /// Maps skill ids to skill db offsets. /// Returns the skill's array index, or 0 (Unknown Skill). -int skill_get_index (uint16 skill_id) +int skill_get_index(int skill_id) { // avoid ranges reserved for mapping guild/homun/mercenary skills if( (skill_id >= GD_SKILLRANGEMIN && skill_id <= GD_SKILLRANGEMAX) @@ -138,88 +138,593 @@ int skill_get_index (uint16 skill_id) } // validate result - if( !skill_id || skill_id >= MAX_SKILL_DB ) + if (skill_id <= 0|| skill_id >= MAX_SKILL_DB) return 0; return skill_id; } -const char* skill_get_name( uint16 skill_id ) { +const char *skill_get_name(int skill_id) +{ return skill->dbs->db[skill->get_index(skill_id)].name; } -const char* skill_get_desc( uint16 skill_id ) { +const char *skill_get_desc(int skill_id) +{ return skill->dbs->db[skill->get_index(skill_id)].desc; } -// out of bounds error checking [celest] -void skill_chk(uint16* skill_id) { - *skill_id = skill->get_index(*skill_id); // checks/adjusts id -} +#define skill_get_lvl_idx(lv) (min((lv), MAX_SKILL_LEVEL) - 1) +#define skill_adjust_over_level(val, lv, max_lv) ((val) > 1 ? ((val) + ((lv) - (max_lv)) / 2) : (val)) -#define skill_get(var,id) do { skill->chk(&(id)); if(!(id)) return 0; return (var); } while(0) -#define skill_get2(var,id,lv) do { \ - skill->chk(&(id)); \ - if(!(id)) return 0; \ - if( (lv) > MAX_SKILL_LEVEL && (var) > 1 ) { \ - int lv2__ = (lv); (lv) = skill->dbs->db[(id)].max; \ - return (var) + ((lv2__-(lv))/2);\ - } \ - return (var);\ -} while(0) -#define skill_glv(lv) min((lv),MAX_SKILL_LEVEL-1) // Skill DB -int skill_get_hit( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].hit, skill_id); } -int skill_get_inf( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].inf, skill_id); } -int skill_get_ele( uint16 skill_id , uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get (skill->dbs->db[skill_id].element[skill_glv(skill_lv-1)], skill_id); } -int skill_get_nk( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].nk, skill_id); } -int skill_get_max( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].max, skill_id); } -int skill_get_range( uint16 skill_id , uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].range[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_splash( uint16 skill_id , uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 ( (skill->dbs->db[skill_id].splash[skill_glv(skill_lv-1)]>=0?skill->dbs->db[skill_id].splash[skill_glv(skill_lv-1)]:AREA_SIZE), skill_id, skill_lv); } -int skill_get_hp( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].hp[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_sp( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].sp[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_hp_rate(uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].hp_rate[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_sp_rate(uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].sp_rate[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_state(uint16 skill_id) { skill_get (skill->dbs->db[skill_id].state, skill_id); } -int skill_get_spiritball(uint16 skill_id, uint16 skill_lv) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].spiritball[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_itemid(uint16 skill_id, int idx) { skill_get (skill->dbs->db[skill_id].itemid[idx], skill_id); } -int skill_get_itemqty(uint16 skill_id, int idx) { skill_get (skill->dbs->db[skill_id].amount[idx], skill_id); } -int skill_get_zeny( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].zeny[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_num( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].num[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_cast( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].cast[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_delay( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].delay[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_walkdelay( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].walkdelay[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_time( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].upkeep_time[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_time2( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].upkeep_time2[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_castdef( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].cast_def_rate, skill_id); } -int skill_get_weapontype( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].weapon, skill_id); } -int skill_get_ammotype( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].ammo, skill_id); } -int skill_get_ammo_qty( uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].ammo_qty[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_inf2( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].inf2, skill_id); } -int skill_get_castcancel( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].castcancel, skill_id); } -int skill_get_maxcount( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].maxcount[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_blewcount( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].blewcount[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_mhp( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].mhp[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_castnodex( uint16 skill_id ,uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].castnodex[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_delaynodex( uint16 skill_id ,uint16 skill_lv ){ Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].delaynodex[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_type( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].skill_type, skill_id); } -int skill_get_unit_id ( uint16 skill_id, int flag ){ skill_get (skill->dbs->db[skill_id].unit_id[flag], skill_id); } -int skill_get_unit_interval( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].unit_interval, skill_id); } -int skill_get_unit_range( uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].unit_range[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_unit_target( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].unit_target&BCT_ALL, skill_id); } -int skill_get_unit_bl_target( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].unit_target&BL_ALL, skill_id); } -int skill_get_unit_flag( uint16 skill_id ) { skill_get (skill->dbs->db[skill_id].unit_flag, skill_id); } -int skill_get_unit_layout_type( uint16 skill_id ,uint16 skill_lv ){ Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].unit_layout_type[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_cooldown( uint16 skill_id, uint16 skill_lv ) { Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].cooldown[skill_glv(skill_lv-1)], skill_id, skill_lv); } -int skill_get_fixed_cast( uint16 skill_id ,uint16 skill_lv ) { + +int skill_get_hit(int skill_id) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + return skill->dbs->db[idx].hit; +} + +int skill_get_inf(int skill_id) +{ + int idx; + if (skill_id == 0) + return INF_NONE; + idx = skill->get_index(skill_id); + Assert_retr(INF_NONE, idx != 0); + return skill->dbs->db[idx].inf; +} + +int skill_get_ele(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return ELE_NEUTRAL; + idx = skill->get_index(skill_id); + Assert_retr(ELE_NEUTRAL, idx != 0); + Assert_retr(ELE_NEUTRAL, skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].element[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].element[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_nk(int skill_id) +{ + int idx; + if (skill_id == 0) + return NK_NONE; + idx = skill->get_index(skill_id); + Assert_retr(NK_NONE, idx != 0); + return skill->dbs->db[idx].nk; +} + +int skill_get_max(int skill_id) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + return skill->dbs->db[idx].max; +} + +int skill_get_range(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].range[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].range[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_splash(int skill_id, int skill_lv) +{ + int idx, val; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + val = skill->dbs->db[idx].splash[skill_get_lvl_idx(skill_lv)]; + if (val < 0) { + val = AREA_SIZE; + } + if (skill_lv > MAX_SKILL_LEVEL) { + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return val; +} + +int skill_get_hp(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].hp[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].hp[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_sp(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].sp[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].sp[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_hp_rate(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].hp_rate[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].hp_rate[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_sp_rate(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].sp_rate[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].sp_rate[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_state(int skill_id) +{ + int idx; + if (skill_id == 0) + return ST_NONE; + idx = skill->get_index(skill_id); + Assert_retr(ST_NONE, idx != 0); + return skill->dbs->db[idx].state; +} + +int skill_get_spiritball(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].spiritball[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].spiritball[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_itemid(int skill_id, int item_idx) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(item_idx >= 0 && item_idx < MAX_SKILL_ITEM_REQUIRE); + return skill->dbs->db[idx].itemid[item_idx]; +} + +int skill_get_itemqty(int skill_id, int item_idx) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(item_idx >= 0 && item_idx < MAX_SKILL_ITEM_REQUIRE); + return skill->dbs->db[idx].amount[item_idx]; +} + +int skill_get_zeny(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].zeny[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].zeny[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_num(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].num[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].num[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_cast(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].cast[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].cast[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_delay(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].delay[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].delay[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_walkdelay(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].walkdelay[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].walkdelay[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_time(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].upkeep_time[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].upkeep_time[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_time2(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].upkeep_time2[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].upkeep_time2[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_castdef(int skill_id) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + return skill->dbs->db[idx].cast_def_rate; +} + +int skill_get_weapontype(int skill_id) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + return skill->dbs->db[idx].weapon; +} + +int skill_get_ammotype(int skill_id) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + return skill->dbs->db[idx].ammo; +} + +int skill_get_ammo_qty(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].ammo_qty[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].ammo_qty[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_inf2(int skill_id) +{ + int idx; + if (skill_id == 0) + return INF2_NONE; + idx = skill->get_index(skill_id); + Assert_retr(INF2_NONE, idx != 0); + return skill->dbs->db[idx].inf2; +} + +int skill_get_castcancel(int skill_id) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + return skill->dbs->db[idx].castcancel; +} + +int skill_get_maxcount(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].maxcount[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].maxcount[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_blewcount(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].blewcount[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].blewcount[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_mhp(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].mhp[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].mhp[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_castnodex(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].castnodex[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].castnodex[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_delaynodex(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].delaynodex[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].delaynodex[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_type(int skill_id) +{ + int idx; + if (skill_id == 0) + return BF_NONE; + idx = skill->get_index(skill_id); + Assert_retr(BF_NONE, idx != 0); + return skill->dbs->db[idx].skill_type; +} + +int skill_get_unit_id(int skill_id, int flag) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(flag >= 0 && flag < ARRAYLENGTH(skill->dbs->db[0].unit_id)); + return skill->dbs->db[idx].unit_id[flag]; +} + +int skill_get_unit_interval(int skill_id) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + return skill->dbs->db[idx].unit_interval; +} + +int skill_get_unit_range(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].unit_range[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].unit_range[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_unit_target(int skill_id) +{ + int idx; + if (skill_id == 0) + return BCT_NOONE; + idx = skill->get_index(skill_id); + Assert_retr(BCT_NOONE, idx != 0); + return skill->dbs->db[idx].unit_target & BCT_ALL; +} + +int skill_get_unit_bl_target(int skill_id) +{ + int idx; + if (skill_id == 0) + return BL_NUL; + idx = skill->get_index(skill_id); + Assert_retr(BL_NUL, idx != 0); + return skill->dbs->db[idx].unit_target & BL_ALL; +} + +int skill_get_unit_flag(int skill_id) +{ + int idx; + if (skill_id == 0) + return UF_NONE; + idx = skill->get_index(skill_id); + Assert_retr(UF_NONE, idx != 0); + return skill->dbs->db[idx].unit_flag; +} + +int skill_get_unit_layout_type(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].unit_layout_type[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].unit_layout_type[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_cooldown(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].cooldown[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].cooldown[skill_get_lvl_idx(skill_lv)]; +} + +int skill_get_fixed_cast(int skill_id, int skill_lv) +{ + int idx; + if (skill_id == 0) + return 0; + idx = skill->get_index(skill_id); + Assert_ret(idx != 0); + Assert_ret(skill_lv > 0); #ifdef RENEWAL_CAST - Assert_ret(skill_lv > 0); skill_get2 (skill->dbs->db[skill_id].fixed_cast[skill_glv(skill_lv-1)], skill_id, skill_lv); + if (skill_lv > MAX_SKILL_LEVEL) { + int val = skill->dbs->db[idx].fixed_cast[skill_get_lvl_idx(skill_lv)]; + return skill_adjust_over_level(val, skill_lv, skill->dbs->db[idx].max); + } + return skill->dbs->db[idx].fixed_cast[skill_get_lvl_idx(skill_lv)]; #else return 0; #endif } -int skill_tree_get_max(uint16 skill_id, int class) +int skill_tree_get_max(int skill_id, int class) { int i; int class_idx = pc->class2idx(class); @@ -231,7 +736,7 @@ int skill_tree_get_max(uint16 skill_id, int class) return skill->get_max(skill_id); } -int skill_get_casttype(uint16 skill_id) +int skill_get_casttype(int skill_id) { int inf = skill->get_inf(skill_id); if (inf&(INF_GROUND_SKILL)) @@ -248,7 +753,7 @@ int skill_get_casttype(uint16 skill_id) return CAST_DAMAGE; } -int skill_get_casttype2(uint16 index) +int skill_get_casttype2(int index) { int inf; Assert_retr(CAST_NODAMAGE, index < MAX_SKILL_DB); @@ -268,7 +773,7 @@ int skill_get_casttype2(uint16 index) } //Returns actual skill range taking into account attack range and AC_OWL [Skotlex] -int skill_get_range2(struct block_list *bl, uint16 skill_id, uint16 skill_lv) +int skill_get_range2(struct block_list *bl, int skill_id, int skill_lv) { int range; struct map_session_data *sd = BL_CAST(BL_PC, bl); @@ -3175,8 +3680,8 @@ int skill_check_condition_mercenary(struct block_list *bl, int skill_id, int lv, struct status_data *st; struct map_session_data *sd = NULL; int i, hp, sp, hp_rate, sp_rate, state, mhp; - uint16 idx; - int itemid[MAX_SKILL_ITEM_REQUIRE],amount[ARRAYLENGTH(itemid)],index[ARRAYLENGTH(itemid)]; + int idx; + int itemid[MAX_SKILL_ITEM_REQUIRE], amount[MAX_SKILL_ITEM_REQUIRE], index[MAX_SKILL_ITEM_REQUIRE]; if( lv < 1 || lv > MAX_SKILL_LEVEL ) return 0; @@ -3192,8 +3697,7 @@ int skill_check_condition_mercenary(struct block_list *bl, int skill_id, int lv, return 0; // Requirements - for( i = 0; i < ARRAYLENGTH(itemid); i++ ) - { + for (i = 0; i < MAX_SKILL_ITEM_REQUIRE; i++) { itemid[i] = skill->dbs->db[idx].itemid[i]; amount[i] = skill->dbs->db[idx].amount[i]; } @@ -6666,7 +7170,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin // custom hack to make the mob display the skill, because these skills don't show the skill use text themselves //NOTE: mobs don't have the sprite animation that is used when performing this skill (will cause glitches) char temp[70]; - snprintf(temp, sizeof(temp), "%s : %s !!",md->name,skill->dbs->db[skill_id].desc); + snprintf(temp, sizeof(temp), "%s : %s !!", md->name, skill->get_desc(skill_id)); clif->disp_overhead(&md->bl,temp); } break; @@ -6865,7 +7369,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin return 1; } if( sd->skillitem != skill_id ) - status_zap(src,0,skill->dbs->db[skill->get_index(skill_id)].sp[skill_lv]); // consume sp only if succeeded + status_zap(src, 0, skill->get_sp(skill_id, skill_lv)); // consume sp only if succeeded } break; @@ -7041,21 +7545,22 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin return 1; } if( sd ) { - int x,bonus=100, potion = min(500+skill_lv,505); - x = skill_lv%11 - 1; - i = pc->search_inventory(sd,skill->dbs->db[skill_id].itemid[x]); - if (i == INDEX_NOT_FOUND || skill->dbs->db[skill_id].itemid[x] <= 0) { + int bonus = 100, potion = min(500+skill_lv,505); + int item_idx = (skill_lv - 1) % MAX_SKILL_ITEM_REQUIRE; + int item_id = skill->get_itemid(skill_id, item_idx); + int inventory_idx = pc->search_inventory(sd, item_id); + if (inventory_idx == INDEX_NOT_FOUND || item_id <= 0) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); map->freeblock_unlock(); return 1; } - if(sd->inventory_data[i] == NULL || sd->status.inventory[i].amount < skill->dbs->db[skill_id].amount[x]) { + if (sd->inventory_data[inventory_idx] == NULL || sd->status.inventory[inventory_idx].amount < skill->get_itemqty(skill_id, item_idx)) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); map->freeblock_unlock(); return 1; } if( skill_id == AM_BERSERKPITCHER ) { - if (dstsd && dstsd->status.base_level < sd->inventory_data[i]->elv) { + if (dstsd != NULL && dstsd->status.base_level < sd->inventory_data[inventory_idx]->elv) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); map->freeblock_unlock(); return 1; @@ -7064,7 +7569,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin script->potion_flag = 1; script->potion_hp = script->potion_sp = script->potion_per_hp = script->potion_per_sp = 0; script->potion_target = bl->id; - script->run_use_script(sd, sd->inventory_data[i], 0); + script->run_use_script(sd, sd->inventory_data[inventory_idx], 0); script->potion_flag = script->potion_target = 0; if( sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_ALCHEMIST ) bonus += sd->status.base_level; @@ -7384,7 +7889,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin maxlv = skill_lv - 4; } else if(skill_lv >=2) { - int i = rnd()%3; + int i = rnd() % ARRAYLENGTH(spellarray); spellid = spellarray[i]; maxlv = skill_lv - 1; } @@ -7591,14 +8096,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case WE_MALE: { - int hp_rate = (!skill_lv)? 0:skill->dbs->db[skill_id].hp_rate[skill_lv-1]; + int hp_rate = skill_lv == 0 ? 0 : skill->get_hp_rate(skill_id, skill_lv); int gain_hp = tstatus->max_hp*abs(hp_rate)/100; // The earned is the same % of the target HP than it cost the caster. [Skotlex] clif->skill_nodamage(src,bl,skill_id,status->heal(bl, gain_hp, 0, 0),1); } break; case WE_FEMALE: { - int sp_rate = (!skill_lv)? 0:skill->dbs->db[skill_id].sp_rate[skill_lv-1]; + int sp_rate = skill_lv == 0 ? 0 : skill->get_sp_rate(skill_id, skill_lv); int gain_sp = tstatus->max_sp*abs(sp_rate)/100;// The earned is the same % of the target SP than it cost the caster. [Skotlex] clif->skill_nodamage(src,bl,skill_id,status->heal(bl, 0, gain_sp, 0),1); } @@ -7661,16 +8166,17 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin if( battle_config.skill_removetrap_type ) { int i; // get back all items used to deploy the trap - for( i = 0; i < 10; i++ ) { - if( skill->dbs->db[su->group->skill_id].itemid[i] > 0 ) { + for (i = 0; i < MAX_SKILL_ITEM_REQUIRE; i++) { + int nameid = skill->get_itemid(su->group->skill_id, i); + if (nameid > 0) { int success; - struct item item_tmp; - memset(&item_tmp,0,sizeof(item_tmp)); - item_tmp.nameid = skill->dbs->db[su->group->skill_id].itemid[i]; + struct item item_tmp = { 0 }; + int amount = skill->get_itemqty(su->group->skill_id, i); + item_tmp.nameid = nameid; item_tmp.identify = 1; - if (item_tmp.nameid && (success=pc->additem(sd,&item_tmp,skill->dbs->db[su->group->skill_id].amount[i],LOG_TYPE_SKILL)) != 0) { + if ((success = pc->additem(sd, &item_tmp, amount, LOG_TYPE_SKILL)) != 0) { clif->additem(sd,0,0,success); - map->addflooritem(&sd->bl, &item_tmp, skill->dbs->db[su->group->skill_id].amount[i], sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0); + map->addflooritem(&sd->bl, &item_tmp, amount, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0); } } } @@ -7902,7 +8408,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin map->freeblock_unlock(); return 0; } - status_zap(src,0,skill->dbs->db[skill->get_index(skill_id)].sp[skill_lv]); // consume sp only if succeeded [Inkfish] + status_zap(src, 0, skill->get_sp(skill_id, skill_lv)); // consume sp only if succeeded [Inkfish] do { int eff = rnd() % 14; if( eff == 5 ) @@ -7926,7 +8432,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin clif->damage(src,bl,0,0,1000,0,BDT_NORMAL,0); if( !status->isdead(bl) ) { int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM, EQP_SHOES, EQP_GARMENT }; - skill->break_equip(bl, where[rnd()%5], 10000, BCT_ENEMY); + skill->break_equip(bl, where[rnd() % ARRAYLENGTH(where)], 10000, BCT_ENEMY); } } break; @@ -7947,7 +8453,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case 7: // stop freeze or stoned { enum sc_type sc[] = { SC_STOP, SC_FREEZE, SC_STONE }; - sc_start(src,bl,sc[rnd()%3],100,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,sc[rnd() % ARRAYLENGTH(sc)],100,skill_lv,skill->get_time2(skill_id,skill_lv)); } break; case 8: // curse coma and poison @@ -10837,10 +11343,13 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui // Slim Pitcher [Celest] case CR_SLIMPITCHER: if (sd) { - int i = skill_lv%11 - 1; - int j = pc->search_inventory(sd,skill->dbs->db[skill_id].itemid[i]); - if (j == INDEX_NOT_FOUND || skill->dbs->db[skill_id].itemid[i] <= 0 - || sd->inventory_data[j] == NULL || sd->status.inventory[j].amount < skill->dbs->db[skill_id].amount[i] + int item_idx = (skill_lv - 1) % MAX_SKILL_ITEM_REQUIRE; + int item_id = skill->get_itemid(skill_id, item_idx); + int inventory_idx = pc->search_inventory(sd, item_id); + int bonus; + if (inventory_idx == INDEX_NOT_FOUND || item_id <= 0 + || sd->inventory_data[inventory_idx] == NULL + || sd->status.inventory[inventory_idx].amount < skill->get_itemqty(skill_id, item_idx) ) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 1; @@ -10848,44 +11357,44 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui script->potion_flag = 1; script->potion_hp = 0; script->potion_sp = 0; - script->run_use_script(sd, sd->inventory_data[j], 0); + script->run_use_script(sd, sd->inventory_data[inventory_idx], 0); script->potion_flag = 0; //Apply skill bonuses - i = pc->checkskill(sd,CR_SLIMPITCHER)*10 + bonus = pc->checkskill(sd,CR_SLIMPITCHER)*10 + pc->checkskill(sd,AM_POTIONPITCHER)*10 + pc->checkskill(sd,AM_LEARNINGPOTION)*5 + pc->skillheal_bonus(sd, skill_id); - script->potion_hp = script->potion_hp * (100+i)/100; - script->potion_sp = script->potion_sp * (100+i)/100; + script->potion_hp = script->potion_hp * (100 + bonus) / 100; + script->potion_sp = script->potion_sp * (100 + bonus) / 100; - if(script->potion_hp > 0 || script->potion_sp > 0) { - i = skill->get_splash(skill_id, skill_lv); + if (script->potion_hp > 0 || script->potion_sp > 0) { + r = skill->get_splash(skill_id, skill_lv); map->foreachinarea(skill->area_sub, - src->m,x-i,y-i,x+i,y+i,BL_CHAR, - src,skill_id,skill_lv,tick,flag|BCT_PARTY|BCT_GUILD|1, + src->m, x - r, y - r, x + r, y + r, BL_CHAR, + src, skill_id, skill_lv, tick, flag|BCT_PARTY|BCT_GUILD|1, skill->castend_nodamage_id); } } else { - int i = skill_lv%11 - 1; - struct item_data *item; - i = skill->dbs->db[skill_id].itemid[i]; - item = itemdb->search(i); + int item_idx = (skill_lv - 1) % MAX_SKILL_ITEM_REQUIRE; + int item_id = skill->get_itemid(skill_id, item_idx); + struct item_data *item = itemdb->search(item_id); + int bonus; script->potion_flag = 1; script->potion_hp = 0; script->potion_sp = 0; script->run(item->script,0,src->id,0); script->potion_flag = 0; - i = skill->get_max(CR_SLIMPITCHER)*10; + bonus = skill->get_max(CR_SLIMPITCHER)*10; - script->potion_hp = script->potion_hp * (100+i)/100; - script->potion_sp = script->potion_sp * (100+i)/100; + script->potion_hp = script->potion_hp * (100 + bonus)/100; + script->potion_sp = script->potion_sp * (100 + bonus)/100; - if(script->potion_hp > 0 || script->potion_sp > 0) { - i = skill->get_splash(skill_id, skill_lv); + if (script->potion_hp > 0 || script->potion_sp > 0) { + r = skill->get_splash(skill_id, skill_lv); map->foreachinarea(skill->area_sub, - src->m,x-i,y-i,x+i,y+i,BL_CHAR, - src,skill_id,skill_lv,tick,flag|BCT_PARTY|BCT_GUILD|1, + src->m, x - r, y - r, x + r, y + r, BL_CHAR, + src, skill_id, skill_lv, tick, flag|BCT_PARTY|BCT_GUILD|1, skill->castend_nodamage_id); } } @@ -11636,27 +12145,27 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ int element[5]={ELE_WIND,ELE_DARK,ELE_POISON,ELE_WATER,ELE_FIRE}; val1 = st->rhw.ele; - if (!val1) - val1=element[rnd()%5]; + if (val1 == ELE_NEUTRAL) + val1 = element[rnd() % ARRAYLENGTH(element)]; - switch (val1) - { + switch (val1) { case ELE_FIRE: - subunt++; - FALLTHROUGH + subunt = 4; + break; case ELE_WATER: - subunt++; - FALLTHROUGH + subunt = 3; + break; case ELE_POISON: - subunt++; - FALLTHROUGH + subunt = 2; + break; case ELE_DARK: - subunt++; - FALLTHROUGH + subunt = 1; + break; case ELE_WIND: + subunt = 0; break; default: - subunt=rnd()%5; + subunt = rnd() % 5; break; } @@ -14824,7 +15333,8 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16 } for( i = 0; i < MAX_SKILL_ITEM_REQUIRE; i++ ) { - if( (skill_id == AM_POTIONPITCHER || skill_id == CR_SLIMPITCHER || skill_id == CR_CULTIVATION) && i != skill_lv%11 - 1 ) + int item_idx = (skill_lv - 1) % MAX_SKILL_ITEM_REQUIRE; + if ((skill_id == AM_POTIONPITCHER || skill_id == CR_SLIMPITCHER || skill_id == CR_CULTIVATION) && i != item_idx) continue; switch( skill_id ) { @@ -16618,15 +17128,16 @@ struct skill_unit_group* skill_id2group(int group_id) /// Fatal error if nothing is available. int skill_get_new_group_id(void) { - if( skill->unit_group_newid >= MAX_SKILL_DB && skill->id2group(skill->unit_group_newid) == NULL ) + if (skill->unit_group_newid > MAX_SKILL_ID && skill->id2group(skill->unit_group_newid) == NULL) return skill->unit_group_newid++;// available - {// find next id + + { + // find next id int base_id = skill->unit_group_newid; - while( base_id != ++skill->unit_group_newid ) - { - if( skill->unit_group_newid < MAX_SKILL_DB ) - skill->unit_group_newid = MAX_SKILL_DB; - if( skill->id2group(skill->unit_group_newid) == NULL ) + while (base_id != ++skill->unit_group_newid) { + if (skill->unit_group_newid <= MAX_SKILL_ID) + skill->unit_group_newid = MAX_SKILL_ID + 1; + if (skill->id2group(skill->unit_group_newid) == NULL) return skill->unit_group_newid++;// available } // full loop, nothing available @@ -17719,7 +18230,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, int difficulty = 30 + rnd()%120; // Random number between (30 ~ 150) make_per = sd->status.job_level / 4 + st->luk / 2 + st->dex / 3; // (Caster?s Job Level / 4) + (Caster?s LUK / 2) + (Caster?s DEX / 3) - qty = ~(5 + rnd()%5) + 1; + qty = ~(5 + rnd()%5) + 1; // FIXME[Haru]: This smells, if anyone knows the intent, please rewrite the expression in a more clear form. switch(nameid){// difficulty factor case ITEMID_APPLE_BOMB: @@ -17755,7 +18266,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, qty = 5; if( qty < 0 || (skill_lv == 1 && make_per < difficulty)){ - qty = ~qty + 1; + qty = ~qty + 1; // FIXME[Haru]: This smells. If anyone knows the intent, please rewrite the expression in a more clear form. make_per = 0; }else make_per = 10000; @@ -18012,7 +18523,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, int rate = rnd()%500; memset(&tmp_item,0,sizeof(tmp_item)); if( rate < 50) i = 4; - else if( rate < 100) i = 2+rnd()%1; + else if( rate < 100) i = 2+rnd()%1; // FIXME[Haru]: This '%1' is certainly not intended. If anyone knows the purpose, please rewrite this code. else if( rate < 250 ) i = 1; else if( rate < 500 ) i = 0; tmp_item.nameid = compensation[i]; @@ -18435,7 +18946,7 @@ int skill_blockpc_end(int tid, int64 tick, int id, intptr_t data) struct map_session_data *sd = map->id2sd(id); struct skill_cd * cd = NULL; - if (data <= 0 || data >= MAX_SKILL) + if (data <= 0 || data >= MAX_SKILL_DB) return 0; if (!sd || !sd->blockskill[data]) return 0; @@ -18571,7 +19082,7 @@ int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick) int skill_blockhomun_end(int tid, int64 tick, int id, intptr_t data) { struct homun_data *hd = map->id2hd(id); - if (data <= 0 || data >= MAX_SKILL) + if (data <= 0 || data >= MAX_SKILL_DB) return 0; if (hd != NULL) hd->blockskill[data] = 0; @@ -18600,7 +19111,7 @@ int skill_blockhomun_start(struct homun_data *hd, uint16 skill_id, int tick) int skill_blockmerc_end(int tid, int64 tick, int id, intptr_t data) { struct mercenary_data *md = map->id2mc(id); - if (data <= 0 || data >= MAX_SKILL) + if (data <= 0 || data >= MAX_SKILL_DB) return 0; if (md != NULL) md->blockskill[data] = 0; @@ -19651,6 +20162,12 @@ void skill_validate_skillinfo(struct config_setting_t *conf, struct s_skill_db * } else { sk->inf2 &= ~INF2_FREE_CAST_REDUCED; } + } else if (strcmpi(type, "ShowSkillScale") == 0) { + if (on) { + sk->inf2 |= INF2_SHOW_SKILL_SCALE; + } else { + sk->inf2 &= ~INF2_SHOW_SKILL_SCALE; + } } else if (strcmpi(type, "None") != 0) { skilldb_invalid_error(type, config_setting_name(t), sk->nameid); } @@ -20477,7 +20994,7 @@ bool skill_read_skilldb(const char *filename) struct config_setting_t *sk, *conf; char filepath[256]; int count=0, index=0; - bool duplicate[MAX_SKILL] = {0}; + bool duplicate[MAX_SKILL_DB] = {0}; nullpo_retr(false, filename); @@ -20902,8 +21419,12 @@ void skill_defaults(void) skill->get_hp = skill_get_hp; skill->get_mhp = skill_get_mhp; skill->get_sp = skill_get_sp; + skill->get_hp_rate = skill_get_hp_rate; + skill->get_sp_rate = skill_get_sp_rate; skill->get_state = skill_get_state; skill->get_spiritball = skill_get_spiritball; + skill->get_itemid = skill_get_itemid; + skill->get_itemqty = skill_get_itemqty; skill->get_zeny = skill_get_zeny; skill->get_num = skill_get_num; skill->get_cast = skill_get_cast; @@ -20932,7 +21453,6 @@ void skill_defaults(void) skill->tree_get_max = skill_tree_get_max; skill->get_name = skill_get_name; skill->get_desc = skill_get_desc; - skill->chk = skill_chk; skill->get_casttype = skill_get_casttype; skill->get_casttype2 = skill_get_casttype2; skill->is_combo = skill_is_combo; diff --git a/src/map/skill.h b/src/map/skill.h index bba440107..1e00e488f 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -25,7 +25,7 @@ #include "map/status.h" // enum sc_type #include "common/hercules.h" #include "common/db.h" -#include "common/mmo.h" // MAX_SKILL, struct square +#include "common/mmo.h" // MAX_SKILL_DB, struct square /** * Declarations @@ -43,7 +43,6 @@ struct status_change_entry; /** * Defines **/ -#define MAX_SKILL_DB MAX_SKILL #define MAX_SKILL_PRODUCE_DB 270 #define MAX_PRODUCE_RESOURCE 10 #define MAX_SKILL_ARROW_DB 140 @@ -77,6 +76,7 @@ struct status_change_entry; //Constants to identify the skill's inf value: enum e_skill_inf { + INF_NONE = 0x00, INF_ATTACK_SKILL = 0x01, INF_GROUND_SKILL = 0x02, INF_SELF_SKILL = 0x04, // Skills casted on self where target is automatically chosen @@ -89,6 +89,7 @@ enum e_skill_inf { //The NK value applies only to non INF_GROUND_SKILL skills //when determining skill castend function to invoke. enum e_skill_nk { + NK_NONE = 0x00, NK_NO_DAMAGE = 0x01, NK_SPLASH = 0x02|0x04, // 0x4 = splash & split NK_SPLASH_ONLY = 0x02, @@ -103,6 +104,7 @@ enum e_skill_nk { //A skill with 3 would be no damage + splash: area of effect. //Constants to identify a skill's inf2 value. enum e_skill_inf2 { + INF2_NONE = 0x00000, INF2_QUEST_SKILL = 0x00001, INF2_NPC_SKILL = 0x00002, // NPC skills are those that players can't have in their skill tree. INF2_WEDDING_SKILL = 0x00004, @@ -120,6 +122,7 @@ enum e_skill_inf2 { INF2_CHORUS_SKILL = 0x04000, // Chorus skill INF2_FREE_CAST_NORMAL = 0x08000, INF2_FREE_CAST_REDUCED = 0x10000, + INF2_SHOW_SKILL_SCALE = 0x20000, }; @@ -132,6 +135,7 @@ enum e_skill_display { }; enum { + UF_NONE = 0x0000, UF_DEFNOTENEMY = 0x0001, // If 'defunit_not_enemy' is set, the target is changed to 'friend' UF_NOREITERATION = 0x0002, // Spell cannot be stacked UF_NOFOOTSET = 0x0004, // Spell cannot be cast near/on targets @@ -158,7 +162,7 @@ enum wl_spheres { }; enum { - ST_NONE, + ST_NONE = 0, ST_HIDING, ST_CLOAKING, ST_HIDDEN, @@ -1930,54 +1934,56 @@ struct skill_interface { int unit_temp[20]; // temporary storage for tracking skill unit skill ids as players move in/out of them int unit_group_newid; /* accesssors */ - int (*get_index) ( uint16 skill_id ); - int (*get_type) ( uint16 skill_id ); - int (*get_hit) ( uint16 skill_id ); - int (*get_inf) ( uint16 skill_id ); - int (*get_ele) ( uint16 skill_id, uint16 skill_lv ); - int (*get_nk) ( uint16 skill_id ); - int (*get_max) ( uint16 skill_id ); - int (*get_range) ( uint16 skill_id, uint16 skill_lv ); - int (*get_range2) (struct block_list *bl, uint16 skill_id, uint16 skill_lv); - int (*get_splash) ( uint16 skill_id, uint16 skill_lv ); - int (*get_hp) ( uint16 skill_id, uint16 skill_lv ); - int (*get_mhp) ( uint16 skill_id, uint16 skill_lv ); - int (*get_sp) ( uint16 skill_id, uint16 skill_lv ); - int (*get_state) (uint16 skill_id); - int (*get_spiritball) (uint16 skill_id, uint16 skill_lv); - int (*get_zeny) ( uint16 skill_id, uint16 skill_lv ); - int (*get_num) ( uint16 skill_id, uint16 skill_lv ); - int (*get_cast) ( uint16 skill_id, uint16 skill_lv ); - int (*get_delay) ( uint16 skill_id, uint16 skill_lv ); - int (*get_walkdelay) ( uint16 skill_id, uint16 skill_lv ); - int (*get_time) ( uint16 skill_id, uint16 skill_lv ); - int (*get_time2) ( uint16 skill_id, uint16 skill_lv ); - int (*get_castnodex) ( uint16 skill_id, uint16 skill_lv ); - int (*get_delaynodex) ( uint16 skill_id ,uint16 skill_lv ); - int (*get_castdef) ( uint16 skill_id ); - int (*get_weapontype) ( uint16 skill_id ); - int (*get_ammotype) ( uint16 skill_id ); - int (*get_ammo_qty) ( uint16 skill_id, uint16 skill_lv ); - int (*get_unit_id) (uint16 skill_id,int flag); - int (*get_inf2) ( uint16 skill_id ); - int (*get_castcancel) ( uint16 skill_id ); - int (*get_maxcount) ( uint16 skill_id, uint16 skill_lv ); - int (*get_blewcount) ( uint16 skill_id, uint16 skill_lv ); - int (*get_unit_flag) ( uint16 skill_id ); - int (*get_unit_target) ( uint16 skill_id ); - int (*get_unit_interval) ( uint16 skill_id ); - int (*get_unit_bl_target) ( uint16 skill_id ); - int (*get_unit_layout_type) ( uint16 skill_id ,uint16 skill_lv ); - int (*get_unit_range) ( uint16 skill_id, uint16 skill_lv ); - int (*get_cooldown) ( uint16 skill_id, uint16 skill_lv ); - int (*tree_get_max) (uint16 skill_id, int class); - const char *(*get_name) ( uint16 skill_id ); - const char *(*get_desc) ( uint16 skill_id ); - /* check */ - void (*chk) (uint16* skill_id); + int (*get_index) (int skill_id); + int (*get_type) (int skill_id); + int (*get_hit) (int skill_id); + int (*get_inf) (int skill_id); + int (*get_ele) (int skill_id, int skill_lv); + int (*get_nk) (int skill_id); + int (*get_max) (int skill_id); + int (*get_range) (int skill_id, int skill_lv); + int (*get_range2) (struct block_list *bl, int skill_id, int skill_lv); + int (*get_splash) (int skill_id, int skill_lv); + int (*get_hp) (int skill_id, int skill_lv); + int (*get_mhp) (int skill_id, int skill_lv); + int (*get_sp) (int skill_id, int skill_lv); + int (*get_hp_rate) (int skill_id, int skill_lv); + int (*get_sp_rate) (int skill_id, int skill_lv); + int (*get_state) (int skill_id); + int (*get_spiritball) (int skill_id, int skill_lv); + int (*get_itemid) (int skill_id, int item_idx); + int (*get_itemqty) (int skill_id, int item_idx); + int (*get_zeny) (int skill_id, int skill_lv); + int (*get_num) (int skill_id, int skill_lv); + int (*get_cast) (int skill_id, int skill_lv); + int (*get_delay) (int skill_id, int skill_lv); + int (*get_walkdelay) (int skill_id, int skill_lv); + int (*get_time) (int skill_id, int skill_lv); + int (*get_time2) (int skill_id, int skill_lv); + int (*get_castnodex) (int skill_id, int skill_lv); + int (*get_delaynodex) (int skill_id, int skill_lv); + int (*get_castdef) (int skill_id); + int (*get_weapontype) (int skill_id); + int (*get_ammotype) (int skill_id); + int (*get_ammo_qty) (int skill_id, int skill_lv); + int (*get_unit_id) (int skill_id, int flag); + int (*get_inf2) (int skill_id); + int (*get_castcancel) (int skill_id); + int (*get_maxcount) (int skill_id, int skill_lv); + int (*get_blewcount) (int skill_id, int skill_lv); + int (*get_unit_flag) (int skill_id); + int (*get_unit_target) (int skill_id); + int (*get_unit_interval) (int skill_id); + int (*get_unit_bl_target) (int skill_id); + int (*get_unit_layout_type) (int skill_id, int skill_lv); + int (*get_unit_range) (int skill_id, int skill_lv); + int (*get_cooldown) (int skill_id, int skill_lv); + int (*tree_get_max) (int skill_id, int class); + const char *(*get_name) (int skill_id); + const char *(*get_desc) (int skill_id); /* whether its CAST_GROUND, CAST_DAMAGE or CAST_NODAMAGE */ - int (*get_casttype) (uint16 skill_id); - int (*get_casttype2) (uint16 index); + int (*get_casttype) (int skill_id); + int (*get_casttype2) (int index); bool (*is_combo) (int skill_id); int (*name2id) (const char* name); int (*isammotype) (struct map_session_data *sd, int skill_id); @@ -2071,7 +2077,7 @@ struct skill_interface { int (*check_condition_mob_master_sub) (struct block_list *bl, va_list ap); void (*brandishspear_first) (struct square *tc, uint8 dir, int16 x, int16 y); void (*brandishspear_dir) (struct square* tc, uint8 dir, int are); - int (*get_fixed_cast) ( uint16 skill_id ,uint16 skill_lv ); + int (*get_fixed_cast) (int skill_id, int skill_lv); int (*sit_count) (struct block_list *bl, va_list ap); int (*sit_in) (struct block_list *bl, va_list ap); int (*sit_out) (struct block_list *bl, va_list ap); diff --git a/src/map/status.c b/src/map/status.c index e0893aa36..ddb8c7e6a 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -159,7 +159,7 @@ void initChangeTables(void) for (i = 0; i < SC_MAX; i++) status->dbs->IconChangeTable[i] = SI_BLANK; - for (i = 0; i < MAX_SKILL; i++) + for (i = 0; i < MAX_SKILL_DB; i++) status->dbs->Skill2SCTable[i] = SC_NONE; for (i = 0; i < SI_MAX; i++) @@ -2329,7 +2329,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) static int calculating = 0; //Check for recursive call preemption. [Skotlex] struct status_data *bstatus; // pointer to the player's base status const struct status_change *sc; - struct s_skill b_skill[MAX_SKILL]; // previous skill tree + struct s_skill b_skill[MAX_SKILL_DB]; // previous skill tree int b_weight, b_max_weight, b_cart_weight_max, // previous weight i, k, index, skill_lv,refinedef=0; int64 i64; @@ -6809,7 +6809,7 @@ struct view_data *status_get_viewdata(struct block_list *bl) case BL_PC: return &BL_UCAST(BL_PC, bl)->vd; case BL_MOB: return BL_UCAST(BL_MOB, bl)->vd; case BL_PET: return &BL_UCAST(BL_PET, bl)->vd; - case BL_NPC: return BL_UCAST(BL_NPC, bl)->vd; + case BL_NPC: return &BL_UCAST(BL_NPC, bl)->vd; case BL_HOM: return BL_UCAST(BL_HOM, bl)->vd; case BL_MER: return BL_UCAST(BL_MER, bl)->vd; case BL_ELEM: return BL_UCAST(BL_ELEM, bl)->vd; @@ -6927,10 +6927,14 @@ void status_set_viewdata(struct block_list *bl, int class_) case BL_NPC: { struct npc_data *nd = BL_UCAST(BL_NPC, bl); - if (vd != NULL) - nd->vd = vd; - else + if (vd != NULL) { + memcpy(&nd->vd, vd, sizeof(struct view_data)); + } else if (pc->db_checkid(class_)) { + memset(&nd->vd, 0, sizeof(struct view_data)); + nd->vd.class = class_; + } else { ShowError("status_set_viewdata (NPC): No view data for class %d (name=%s)\n", class_, nd->name); + } } break; case BL_HOM: //[blackhole89] diff --git a/src/map/status.h b/src/map/status.h index a104c66ab..e9c2218e8 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -2257,7 +2257,7 @@ BEGIN_ZEROED_BLOCK; /* Everything within this block will be memset to 0 when sta int HP_table[CLASS_COUNT][MAX_LEVEL + 1]; int SP_table[CLASS_COUNT][MAX_LEVEL + 1]; int aspd_base[CLASS_COUNT][MAX_SINGLE_WEAPON_TYPE+1]; // +1 for RENEWAL_ASPD - sc_type Skill2SCTable[MAX_SKILL]; // skill -> status + sc_type Skill2SCTable[MAX_SKILL_DB]; // skill -> status int IconChangeTable[SC_MAX]; // status -> "icon" (icon is a bit of a misnomer, since there exist values with no icon associated) unsigned int ChangeFlagTable[SC_MAX]; // status -> flags int SkillChangeTable[SC_MAX]; // status -> skill |