diff options
Diffstat (limited to 'src/map')
38 files changed, 1362 insertions, 988 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c index a1666b44e..f3ee84197 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -209,9 +209,10 @@ ACMD(send) long num; // read message type as hex number (without the 0x) - if(!message || !*message || - !((sscanf(message, "len %x", &type)==1 && (len=1)) - || sscanf(message, "%x", &type)==1) ) { + if (!message || !*message + || !((sscanf(message, "len %x", &type)==1 && (len=1)) + || sscanf(message, "%x", &type)==1) + ) { clif->message(fd, msg_fd(fd,900)); // Usage: clif->message(fd, msg_fd(fd,901)); // @send len <packet hex number> clif->message(fd, msg_fd(fd,902)); // @send <packet hex number> {<value>}* @@ -663,7 +664,7 @@ ACMD(who) { break; } } - clif->colormes(fd, COLOR_DEFAULT, StrBuf->Value(&buf));/** for whatever reason clif->message crashes with some patterns, see bugreport:8186 **/ + clif->messagecolor_self(fd, COLOR_DEFAULT, StrBuf->Value(&buf));/** for whatever reason clif->message crashes with some patterns, see bugreport:8186 **/ StrBuf->Clear(&buf); count++; } @@ -875,12 +876,12 @@ ACMD(guildstorage) if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading) return false; - if (sd->state.storage_flag == 1) { + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) { clif->message(fd, msg_fd(fd,250)); return false; } - if (sd->state.storage_flag == 2) { + if (sd->state.storage_flag == STORAGE_FLAG_GUILD) { clif->message(fd, msg_fd(fd,251)); return false; } @@ -1124,7 +1125,7 @@ ACMD(heal) if ( hp < 0 && sp <= 0 ) { status->damage(NULL, &sd->bl, -hp, -sp, 0, 0); - clif->damage(&sd->bl,&sd->bl, 0, 0, -hp, 0, 4, 0); + clif->damage(&sd->bl,&sd->bl, 0, 0, -hp, 0, BDT_ENDURE, 0); clif->message(fd, msg_fd(fd,156)); // HP or/and SP modified. return true; } @@ -1135,7 +1136,7 @@ ACMD(heal) status->heal(&sd->bl, hp, 0, 0); else { status->damage(NULL, &sd->bl, -hp, 0, 0, 0); - clif->damage(&sd->bl,&sd->bl, 0, 0, -hp, 0, 4, 0); + clif->damage(&sd->bl,&sd->bl, 0, 0, -hp, 0, BDT_ENDURE, 0); } } @@ -1344,7 +1345,7 @@ ACMD(itemreset) for (i = 0; i < MAX_INVENTORY; i++) { if (sd->status.inventory[i].amount && sd->status.inventory[i].equip == 0) { - pc->delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_COMMAND); + pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_COMMAND); } } clif->message(fd, msg_fd(fd,20)); // All of your items have been removed. @@ -1443,7 +1444,7 @@ ACMD(joblevelup) level = sd->status.job_level-1; sd->status.job_level -= (unsigned int)level; if (sd->status.skill_point < level) - pc->resetskill(sd,0); //Reset skills since we need to subtract more points. + pc->resetskill(sd, PCRESETSKILL_NONE); //Reset skills since we need to subtract more points. if (sd->status.skill_point < level) sd->status.skill_point = 0; else @@ -2086,9 +2087,9 @@ ACMD(refine) if (sd->status.inventory[idx].refine != final_refine) { sd->status.inventory[idx].refine = final_refine; current_position = sd->status.inventory[idx].equip; - pc->unequipitem(sd, idx, 3); + pc->unequipitem(sd, idx, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); clif->refine(fd, 0, idx, sd->status.inventory[idx].refine); - clif->delitem(sd, idx, 1, 3); + clif->delitem(sd, idx, 1, DELITEM_MATERIALCHANGE); clif->additem(sd, idx, 1, 0); pc->equipitem(sd, idx, current_position); clif->misceffect(&sd->bl, 3); @@ -2730,7 +2731,7 @@ ACMD(char_block) return false; } - chrif->char_ask_name(sd->status.account_id, atcmd_player_name, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block + chrif->char_ask_name(sd->status.account_id, atcmd_player_name, CHAR_ASK_NAME_BLOCK, 0, 0, 0, 0, 0, 0); clif->message(fd, msg_fd(fd,88)); // Character name sent to char-server to ask it. return true; @@ -2826,7 +2827,8 @@ ACMD(char_ban) return false; } - chrif->char_ask_name(sd->status.account_id, atcmd_player_name, !strcmpi(info->command,"charban") ? 6 : 2, year, month, day, hour, minute, second); // type: 2 - ban; 6 - charban + chrif->char_ask_name(sd->status.account_id, atcmd_player_name, + !strcmpi(info->command,"charban") ? CHAR_ASK_NAME_CHARBAN : CHAR_ASK_NAME_BAN, year, month, day, hour, minute, second); clif->message(fd, msg_fd(fd,88)); // Character name sent to char-server to ask it. return true; @@ -2845,7 +2847,7 @@ ACMD(char_unblock) } // send answer to login server via char-server - chrif->char_ask_name(sd->status.account_id, atcmd_player_name, 3, 0, 0, 0, 0, 0, 0); // type: 3 - unblock + chrif->char_ask_name(sd->status.account_id, atcmd_player_name, CHAR_ASK_NAME_UNBLOCK, 0, 0, 0, 0, 0, 0); clif->message(fd, msg_fd(fd,88)); // Character name sent to char-server to ask it. return true; @@ -2864,7 +2866,8 @@ ACMD(char_unban) } // send answer to login server via char-server - chrif->char_ask_name(sd->status.account_id, atcmd_player_name, !strcmpi(info->command,"charunban") ? 7 : 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban account; type 7 - unban character + chrif->char_ask_name(sd->status.account_id, atcmd_player_name, + !strcmpi(info->command,"charunban") ? CHAR_ASK_NAME_CHARUNBAN : CHAR_ASK_NAME_UNBAN, 0, 0, 0, 0, 0, 0); clif->message(fd, msg_fd(fd,88)); // Character name sent to char-server to ask it. return true; @@ -3101,7 +3104,7 @@ ACMD(questskill) return false; } - pc->skill(sd, skill_id, 1, 0); + pc->skill(sd, skill_id, 1, SKILL_GRANT_PERMANENT); clif->message(fd, msg_fd(fd,70)); // You have learned the skill. return true; @@ -5096,7 +5099,7 @@ ACMD(dropall) for (i = 0; i < MAX_INVENTORY; i++) { if (sd->status.inventory[i].amount) { if(sd->status.inventory[i].equip != 0) - pc->unequipitem(sd, i, 3); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); pc->dropitem(sd, i, sd->status.inventory[i].amount); } } @@ -5111,7 +5114,7 @@ ACMD(storeall) { int i; - if (sd->state.storage_flag != 1) { + if (sd->state.storage_flag != STORAGE_FLAG_NORMAL) { //Open storage. if( storage->open(sd) == 1 ) { clif->message(fd, msg_fd(fd,1161)); // You currently cannot open your storage. @@ -5122,7 +5125,7 @@ ACMD(storeall) for (i = 0; i < MAX_INVENTORY; i++) { if (sd->status.inventory[i].amount) { if(sd->status.inventory[i].equip != 0) - pc->unequipitem(sd, i, 3); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); storage->add(sd, i, sd->status.inventory[i].amount); } } @@ -5136,7 +5139,7 @@ ACMD(clearstorage) { int i, j; - if (sd->state.storage_flag == 1) { + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) { clif->message(fd, msg_fd(fd,250)); return false; } @@ -5164,12 +5167,12 @@ ACMD(cleargstorage) return false; } - if (sd->state.storage_flag == 1) { + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) { clif->message(fd, msg_fd(fd,250)); return false; } - if (sd->state.storage_flag == 2) { + if (sd->state.storage_flag == STORAGE_FLAG_GUILD) { clif->message(fd, msg_fd(fd,251)); return false; } @@ -5200,7 +5203,7 @@ ACMD(clearcart) return false; } - if( sd->state.vending == 1 ) { + if (sd->state.vending) { clif->message(fd, msg_fd(fd,548)); // You can't clean a cart while vending! return false; } @@ -5326,7 +5329,7 @@ ACMD(displayskill) { } st = status->get_status_data(&sd->bl); tick = timer->gettick(); - clif->skill_damage(&sd->bl,&sd->bl, tick, st->amotion, st->dmotion, 1, 1, skill_id, skill_lv, 5); + clif->skill_damage(&sd->bl,&sd->bl, tick, st->amotion, st->dmotion, 1, 1, skill_id, skill_lv, BDT_SPLASH); clif->skill_nodamage(&sd->bl, &sd->bl, skill_id, skill_lv, 1); clif->skill_poseffect(&sd->bl, skill_id, skill_lv, sd->bl.x, sd->bl.y, tick); return true; @@ -5603,7 +5606,7 @@ ACMD(partyoption) return false; } - option = (config_switch(w1)?1:0)|(config_switch(w2)?2:0); + option = (config_switch(w1)?1:0)|(config_switch(w2)?2:0); // TODO: Add documentation for these values //Change item share type. if (option != p->party.item) @@ -6075,14 +6078,14 @@ ACMD(cleanmap) { } ACMD(cleanarea) { - int x0 = 0, y0 = 0, x1 = 0, y1 = 0; + int x0 = 0, y0 = 0, x1 = 0, y1 = 0, n = 0; - if (!message || !*message || sscanf(message, "%d %d %d %d", &x0, &y0, &x1, &y1) < 1) { + if (!message || !*message || (n=sscanf(message, "%d %d %d %d", &x0, &y0, &x1, &y1)) < 1) { map->foreachinrange(atcommand->cleanfloor_sub, &sd->bl, AREA_SIZE * 2, BL_ITEM); - } else if (sscanf(message, "%d %d %d %d", &x0, &y0, &x1, &y1) == 1) { - map->foreachinrange(atcommand->cleanfloor_sub, &sd->bl, x0, BL_ITEM); - } else if (sscanf(message, "%d %d %d %d", &x0, &y0, &x1, &y1) == 4) { + } else if (n == 4) { map->foreachinarea(atcommand->cleanfloor_sub, sd->bl.m, x0, y0, x1, y1, BL_ITEM); + } else { + map->foreachinrange(atcommand->cleanfloor_sub, &sd->bl, x0, BL_ITEM); } clif->message(fd, msg_fd(fd,1221)); // All dropped items have been cleaned up. @@ -6244,10 +6247,9 @@ ACMD(users) /*========================================== * *------------------------------------------*/ -ACMD(reset) -{ +ACMD(reset) { pc->resetstate(sd); - pc->resetskill(sd,1); + pc->resetskill(sd, PCRESETSKILL_RESYNC); sprintf(atcmd_output, msg_fd(fd,208), sd->status.name); // '%s' skill and stats points reseted! clif->message(fd, atcmd_output); return true; @@ -6288,9 +6290,9 @@ ACMD(summon) if(!md) return false; - md->master_id=sd->bl.id; - md->special_state.ai=1; - md->deletetimer=timer->add(tick+(duration*60000),mob->timer_delete,md->bl.id,0); + md->master_id = sd->bl.id; + md->special_state.ai = AI_ATTACK; + md->deletetimer = timer->add(tick+(duration*60000),mob->timer_delete,md->bl.id,0); clif->specialeffect(&md->bl,344,AREA); mob->spawn(md); sc_start4(NULL,&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000); @@ -6423,14 +6425,13 @@ ACMD(uptime) * @changesex <sex> * => Changes one's sex. Argument sex can be 0 or 1, m or f, male or female. *------------------------------------------*/ -ACMD(changesex) -{ +ACMD(changesex) { int i; - pc->resetskill(sd,4); + pc->resetskill(sd, PCRESETSKILL_CHSEX); // to avoid any problem with equipment and invalid sex, equipment is unequipped. for( i=0; i<EQI_MAX; i++ ) - if( sd->equip_index[i] >= 0 ) pc->unequipitem(sd, sd->equip_index[i], 3); + if( sd->equip_index[i] >= 0 ) pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); chrif->changesex(sd, true); return true; } @@ -6745,7 +6746,7 @@ ACMD(showmobs) continue; if( mob_id != -1 && md->class_ != mob_id ) continue; - if( md->special_state.ai || md->master_id ) + if (md->special_state.ai != AI_NONE || md->master_id) continue; // hide slaves and player summoned mobs if( md->spawn_timer != INVALID_TIMER ) continue; // hide mobs waiting for respawn @@ -7940,10 +7941,10 @@ ACMD(feelreset) /*========================================== * AUCTION SYSTEM *------------------------------------------*/ -ACMD(auction) { - - if( !battle_config.feature_auction ) { - clif->colormes(sd->fd,COLOR_RED,msg_fd(fd,1484)); +ACMD(auction) +{ + if (!battle_config.feature_auction) { + clif->messagecolor_self(sd->fd, COLOR_RED, msg_fd(fd,1484)); return false; } @@ -7955,31 +7956,22 @@ ACMD(auction) { /*========================================== * Kill Steal Protection *------------------------------------------*/ -ACMD(ksprotection) -{ +ACMD(ksprotection) { if( sd->state.noks ) { - sd->state.noks = 0; + sd->state.noks = KSPROTECT_NONE; clif->message(fd, msg_fd(fd,1325)); // [ K.S Protection Inactive ] - } - else - { - if( !message || !*message || !strcmpi(message, "party") ) - { // Default is Party - sd->state.noks = 2; - clif->message(fd, msg_fd(fd,1326)); // [ K.S Protection Active - Option: Party ] - } - else if( !strcmpi(message, "self") ) - { - sd->state.noks = 1; - clif->message(fd, msg_fd(fd,1327)); // [ K.S Protection Active - Option: Self ] - } - else if( !strcmpi(message, "guild") ) - { - sd->state.noks = 3; - clif->message(fd, msg_fd(fd,1328)); // [ K.S Protection Active - Option: Guild ] - } - else - clif->message(fd, msg_fd(fd,1329)); // Usage: @noks <self|party|guild> + } else if( !message || !*message || strcmpi(message, "party") == 0 ) { + // Default is Party + sd->state.noks = KSPROTECT_PARTY; + clif->message(fd, msg_fd(fd,1326)); // [ K.S Protection Active - Option: Party ] + } else if( strcmpi(message, "self") == 0 ) { + sd->state.noks = KSPROTECT_SELF; + clif->message(fd, msg_fd(fd,1327)); // [ K.S Protection Active - Option: Self ] + } else if( strcmpi(message, "guild") == 0 ) { + sd->state.noks = KSPROTECT_GUILD; + clif->message(fd, msg_fd(fd,1328)); // [ K.S Protection Active - Option: Guild ] + } else { + clif->message(fd, msg_fd(fd,1329)); // Usage: @noks <self|party|guild> } return true; } @@ -8008,7 +8000,7 @@ ACMD(resetstat) ACMD(resetskill) { - pc->resetskill(sd,1); + pc->resetskill(sd, PCRESETSKILL_RESYNC); sprintf(atcmd_output, msg_fd(fd,206), sd->status.name); clif->message(fd, atcmd_output); return true; @@ -8255,7 +8247,7 @@ ACMD(delitem) { {// delete pet intif->delete_petdata(MakeDWord(sd->status.inventory[idx].card[1], sd->status.inventory[idx].card[2])); } - pc->delitem(sd, idx, delamount, 0, 0, LOG_TYPE_COMMAND); + pc->delitem(sd, idx, delamount, 0, DELITEM_NORMAL, LOG_TYPE_COMMAND); amount-= delamount; } @@ -8793,13 +8785,7 @@ ACMD(channel) { unsigned short msg_len = 1; msg_len += sprintf(mout, "[ %s list colors ] : %s", command, channel->config->colors_name[k]); - WFIFOHEAD(fd,msg_len + 12); - WFIFOW(fd,0) = 0x2C1; - WFIFOW(fd,2) = msg_len + 12; - WFIFOL(fd,4) = 0; - WFIFOL(fd,8) = channel->config->colors[k]; - safestrncpy((char*)WFIFOP(fd,12), mout, msg_len); - WFIFOSET(fd, msg_len + 12); + clif->messagecolor_self(fd, channel->config->colors[k], mout); } } else { DBIterator *iter = db_iterator(channel->db); @@ -9185,13 +9171,7 @@ ACMD(fontcolor) { for( k = 0; k < channel->config->colors_count; k++ ) { msg_len += sprintf(mout, "[ %s ] : %s", command, channel->config->colors_name[k]); - WFIFOHEAD(fd,msg_len + 12); - WFIFOW(fd,0) = 0x2C1; - WFIFOW(fd,2) = msg_len + 12; - WFIFOL(fd,4) = 0; - WFIFOL(fd,8) = channel->config->colors[k]; - safestrncpy((char*)WFIFOP(fd,12), mout, msg_len); - WFIFOSET(fd, msg_len + 12); + clif->messagecolor_self(fd, channel->config->colors[k], mout); } return false; } @@ -9214,13 +9194,8 @@ ACMD(fontcolor) { sd->fontcolor = k + 1; msg_len += sprintf(mout, "Color changed to '%s'", channel->config->colors_name[k]); - WFIFOHEAD(fd,msg_len + 12); - WFIFOW(fd,0) = 0x2C1; - WFIFOW(fd,2) = msg_len + 12; - WFIFOL(fd,4) = 0; - WFIFOL(fd,8) = channel->config->colors[k]; - safestrncpy((char*)WFIFOP(fd,12), mout, msg_len); - WFIFOSET(fd, msg_len + 12); + clif->messagecolor_self(fd, channel->config->colors[k], mout); + return true; } ACMD(searchstore){ @@ -9959,11 +9934,12 @@ bool atcommand_exec(const int fd, struct map_session_data *sd, const char *messa } for(i = 0; i < map->list[sd->bl.m].zone->disabled_commands_count; i++) { if( info->func == map->list[sd->bl.m].zone->disabled_commands[i]->cmd ) { - if( pc_get_group_level(sd) < map->list[sd->bl.m].zone->disabled_commands[i]->group_lv ) { - clif->colormes(sd->fd,COLOR_RED,"This command is disabled in this area"); + if (pc_get_group_level(sd) < map->list[sd->bl.m].zone->disabled_commands[i]->group_lv) { + clif->messagecolor_self(sd->fd, COLOR_RED, "This command is disabled in this area"); return true; - } else + } else { break;/* already found the matching command, no need to keep checking -- just go on */ + } } } } diff --git a/src/map/battle.c b/src/map/battle.c index 603db4738..b7ee23d09 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -300,10 +300,10 @@ int battle_delay_damage(int64 tick, int amotion, struct block_list *src, struct int battle_attr_ratio(int atk_elem,int def_type, int def_lv) { - if (atk_elem < 0 || atk_elem >= ELE_MAX) + if (atk_elem < ELE_NEUTRAL || atk_elem >= ELE_MAX) return 100; - if (def_type < 0 || def_type >= ELE_MAX || def_lv < 1 || def_lv > 4) + if (def_type < ELE_NEUTRAL || def_type >= ELE_MAX || def_lv < 1 || def_lv > 4) return 100; return battle->attr_fix_table[def_lv-1][atk_elem][def_type]; @@ -322,10 +322,10 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d if (src) sc = status->get_sc(src); if (target) tsc = status->get_sc(target); - if (atk_elem < 0 || atk_elem >= ELE_MAX) + if (atk_elem < ELE_NEUTRAL || atk_elem >= ELE_MAX) atk_elem = rnd()%ELE_MAX; - if (def_type < 0 || def_type >= ELE_MAX || + if (def_type < ELE_NEUTRAL || def_type >= ELE_MAX || def_lv < 1 || def_lv > 4) { ShowError("battle_attr_fix: unknown attr type: atk=%d def_type=%d def_lv=%d\n",atk_elem,def_type,def_lv); return damage; @@ -407,6 +407,8 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d else return damage + (damage * (ratio - 100) / 100); } + +//FIXME: Missing documentation for flag, flag2 int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, struct weapon_atk *watk, int nk, bool n_ele, short s_ele, short s_ele_, int size, int type, int flag, int flag2){ // [malufett] #ifdef RENEWAL int64 damage, eatk = 0; @@ -485,7 +487,7 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u * it calculates nothing extra fancy, is needed for magnum breaks WATK_ELEMENT bonus. [Skotlex] *------------------------------------------ * Pass damage2 as NULL to not calc it. - * Flag values: + * Flag values: // TODO: Check whether these values are correct (the flag parameter seems to be passed through to other functions), and replace them with an enum. * &1: Critical hit * &2: Arrow attack * &4: Skill is Magic Crasher @@ -493,6 +495,7 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u *&16: Arrow attack but BOW, REVOLVER, RIFLE, SHOTGUN, GATLING or GRENADE type weapon not equipped (i.e. shuriken, kunai and venom knives not affected by DEX) */ /* 'battle_calc_base_damage' is used on renewal, 'battle_calc_base_damage2' otherwise. */ +// FIXME: Missing documentation for flag2 int64 battle_calc_base_damage(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int nk, bool n_ele, short s_ele, short s_ele_, int type, int flag, int flag2) { int64 damage; struct status_data *st = status->get_status_data(src); @@ -616,6 +619,7 @@ int64 battle_calc_sizefix(struct map_session_data *sd, int64 damage, int type, i /*========================================== * Passive skill damages increases *------------------------------------------*/ +// FIXME: type is undocumented int64 battle_addmastery(struct map_session_data *sd,struct block_list *target,int64 dmg,int type) { int64 damage; struct status_data *st = status->get_status_data(target); @@ -866,6 +870,7 @@ void battle_calc_masteryfix_unknown(struct block_list *src, struct block_list *t /*========================================== * Elemental attribute fix. *------------------------------------------*/ +// FIXME: flag is undocumented int64 battle_calc_elefix(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 damage, int nk, int n_ele, int s_ele, int s_ele_, bool left, int flag){ struct status_data *tstatus; @@ -930,8 +935,6 @@ int64 battle_calc_cardfix2(struct block_list *src, struct block_list *bl, int64 // RaceAddTolerance damage -= damage * tsd->race_tolerance[sstatus->race] / 100; damage -= damage * tsd->race_tolerance[is_boss(src) ? RC_BOSS : RC_NONBOSS] / 100; - if ( sstatus->race != RC_DEMIHUMAN ) - damage -= damage *tsd->race_tolerance[RC_NONDEMIHUMAN] / 100; if ( flag&BF_SHORT ) damage -= damage * tsd->bonus.near_attack_def_rate / 100; else // SubRangeAttackDamage or bLongAtkDef @@ -950,6 +953,7 @@ int64 battle_calc_cardfix2(struct block_list *src, struct block_list *bl, int64 * &1 - calc for left hand. * &2 - atker side cardfix(BF_WEAPON) otherwise target side(BF_WEAPON). *------------------------------------------*/ +// FIXME: wflag is undocumented int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int64 damage, int cflag, int wflag){ struct map_session_data *sd, *tsd; short cardfix = @@ -1013,8 +1017,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ cardfix = cardfix * (100 - tsd->subrace2[s_race2]) / 100; cardfix = cardfix * (100 - tsd->subrace[sstatus->race]) / 100; cardfix = cardfix * (100 - tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS]) / 100; - if( sstatus->race != RC_DEMIHUMAN ) - cardfix = cardfix * (100-tsd->subrace[RC_NONDEMIHUMAN]) / 100; for(i=0; i < ARRAYLENGTH(tsd->add_mdef) && tsd->add_mdef[i].rate;i++) { if(tsd->add_mdef[i].class_ == s_class) { @@ -1070,8 +1072,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ cardfix = cardfix * (100 + sd->right_weapon.addsize[tstatus->size]+sd->arrow_addsize[tstatus->size]) / 100; cardfix = cardfix * (100 + sd->right_weapon.addrace2[t_race2]) / 100; cardfix = cardfix * (100 + sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS] + sd->arrow_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]) / 100; - if( tstatus->race != RC_DEMIHUMAN ) - cardfix = cardfix * (100 + sd->right_weapon.addrace[RC_NONDEMIHUMAN]+sd->arrow_addrace[RC_NONDEMIHUMAN]) / 100; }else{ // Melee attack if( !battle_config.left_cardfix_to_right ){ cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race])/100; @@ -1090,8 +1090,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ cardfix = cardfix * (100+sd->right_weapon.addsize[tstatus->size]) / 100; cardfix = cardfix * (100+sd->right_weapon.addrace2[t_race2]) / 100; cardfix = cardfix * (100+sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]) / 100; - if( tstatus->race != RC_DEMIHUMAN ) - cardfix = cardfix * (100 + sd->right_weapon.addrace[RC_NONDEMIHUMAN]) / 100; if( cflag&1 ){ cardfix_ = cardfix_*(100+sd->left_weapon.addrace[tstatus->race])/100; @@ -1110,8 +1108,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ cardfix_ = cardfix_ * (100+sd->left_weapon.addsize[tstatus->size]) / 100; cardfix_ = cardfix_ * (100+sd->left_weapon.addrace2[t_race2]) / 100; cardfix_ = cardfix_ * (100+sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]) / 100; - if( tstatus->race != RC_DEMIHUMAN ) - cardfix_ = cardfix_*(100+sd->left_weapon.addrace[RC_NONDEMIHUMAN])/100; } }else{ int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[tstatus->def_ele]; @@ -1137,8 +1133,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ cardfix = cardfix * (100 + sd->right_weapon.addsize[tstatus->size] + sd->left_weapon.addsize[tstatus->size])/100; cardfix = cardfix * (100 + sd->right_weapon.addrace2[t_race2] + sd->left_weapon.addrace2[t_race2])/100; cardfix = cardfix * (100 + sd->right_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS] + sd->left_weapon.addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]) / 100; - if( tstatus->race != RC_DEMIHUMAN ) - cardfix = cardfix * (100+sd->right_weapon.addrace[RC_NONDEMIHUMAN] + sd->left_weapon.addrace[RC_NONDEMIHUMAN]) / 100; } } @@ -1203,8 +1197,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ cardfix = cardfix * (100-tsd->subrace2[s_race2]) / 100; cardfix = cardfix * (100-tsd->subrace[sstatus->race]) / 100; cardfix = cardfix * (100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS]) / 100; - if( sstatus->race != RC_DEMIHUMAN ) - cardfix = cardfix * (100 - tsd->subrace[RC_NONDEMIHUMAN]) / 100; for( i = 0; i < ARRAYLENGTH(tsd->add_def) && tsd->add_def[i].rate;i++ ){ if( tsd->add_def[i].class_ == s_class ) @@ -1251,8 +1243,6 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ } cardfix = cardfix*(100-tsd->subrace[sstatus->race]) / 100; cardfix = cardfix*(100-tsd->subrace[is_boss(src)?RC_BOSS:RC_NONBOSS]) / 100; - if( sstatus->race != RC_DEMIHUMAN ) - cardfix = cardfix * (100 - tsd->subrace[RC_NONDEMIHUMAN]) / 100; if( wflag&BF_SHORT ) cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100; else // BF_LONG (there's no other choice) @@ -1282,6 +1272,7 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ * &2 - pdef(Pierce defense) * &4 - tdef(Total defense reduction) *------------------------------------------*/ +// TODO: Add an enum for flag int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 damage, int flag, int pdef){ struct status_data *sstatus, *tstatus; struct map_session_data *sd, *tsd; @@ -1485,6 +1476,7 @@ int battle_calc_chorusbonus(struct map_session_data *sd) { return members - 2; // Effect bonus from additional Minstrel's/Wanderer's if not above the max possible } +// FIXME: flag is undocumented int battle_calc_skillratio(int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int skillratio, int flag){ int i; struct status_change *sc, *tsc; @@ -2788,6 +2780,8 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam group->val2 -= (int)cap_value(damage,INT_MIN,INT_MAX); } else skill->del_unitgroup(group,ALC_MARK); + if (--group->val3<=0) + skill->del_unitgroup(group,ALC_MARK); #else if (--group->val2<=0) skill->del_unitgroup(group,ALC_MARK); @@ -3159,28 +3153,31 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam if( sc->data[SC__DEADLYINFECT] && flag&BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * sc->data[SC__DEADLYINFECT]->val1 && !is_boss(src) ) status->change_spread(bl, src); // Deadly infect attacked side + + if ( sd && damage > 0 && (sce = sc->data[SC_GENTLETOUCH_ENERGYGAIN]) ) { + if ( rnd() % 100 < sce->val2 ) + pc->addspiritball(sd, skill->get_time(MO_CALLSPIRITS, 1), pc->getmaxspiritball(sd, 0)); + } } //SC effects from caster side. - sc = status->get_sc(src); - - if (sc && sc->count) { - if( sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] ) + if (tsc && tsc->count) { + if( tsc->data[SC_INVINCIBLE] && !tsc->data[SC_INVINCIBLEOFF] ) damage += damage * 75 / 100; // [Epoque] if (bl->type == BL_MOB) { int i; - if ( ((sce=sc->data[SC_MANU_ATK]) && (flag&BF_WEAPON)) || - ((sce=sc->data[SC_MANU_MATK]) && (flag&BF_MAGIC)) + if ( ((sce=tsc->data[SC_MANU_ATK]) && (flag&BF_WEAPON)) || + ((sce=tsc->data[SC_MANU_MATK]) && (flag&BF_MAGIC)) ) for (i=0;ARRAYLENGTH(mob->manuk)>i;i++) if (((TBL_MOB*)bl)->class_==mob->manuk[i]) { damage += damage * sce->val1 / 100; break; } - if ( ((sce=sc->data[SC_SPL_ATK]) && (flag&BF_WEAPON)) || - ((sce=sc->data[SC_SPL_MATK]) && (flag&BF_MAGIC)) + if ( ((sce=tsc->data[SC_SPL_ATK]) && (flag&BF_WEAPON)) || + ((sce=tsc->data[SC_SPL_MATK]) && (flag&BF_MAGIC)) ) for (i=0;ARRAYLENGTH(mob->splendide)>i;i++) if (((TBL_MOB*)bl)->class_==mob->splendide[i]) { @@ -3197,14 +3194,19 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam sc_start(src,bl,tsc->data[SC_POISONINGWEAPON]->val2,rate,tsc->data[SC_POISONINGWEAPON]->val1,skill->get_time2(GC_POISONINGWEAPON,1) - (tstatus->vit + tstatus->luk) / 2 * 1000); } } - if( sc->data[SC__DEADLYINFECT] && flag&BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * sc->data[SC__DEADLYINFECT]->val1 && !is_boss(src) ) + if( tsc->data[SC__DEADLYINFECT] && flag&BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * tsc->data[SC__DEADLYINFECT]->val1 && !is_boss(src) ) status->change_spread(src, bl); - if (sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 && damage > 0) + if (tsc->data[SC_SHIELDSPELL_REF] && tsc->data[SC_SHIELDSPELL_REF]->val1 == 1 && damage > 0) skill->break_equip(bl,EQP_ARMOR,10000,BCT_ENEMY ); - if (sc->data[SC_STYLE_CHANGE] && rnd()%2) { + if (tsc->data[SC_STYLE_CHANGE] && rnd()%2) { TBL_HOM *hd = BL_CAST(BL_HOM,bl); if (hd) homun->addspiritball(hd, 10); } + if ( src->type == BL_PC && damage > 0 && (sce = tsc->data[SC_GENTLETOUCH_ENERGYGAIN]) ) { + struct map_session_data *tsd = (struct map_session_data *)src; + if ( tsd && rnd() % 100 < sce->val2 ) + pc->addspiritball(tsd, skill->get_time(MO_CALLSPIRITS, 1), pc->getmaxspiritball(tsd, 0)); + } } /* no data claims these settings affect anything other than players */ if( damage && sd && bl->type == BL_PC ) { @@ -3274,6 +3276,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam /*========================================== * Calculates BG related damage adjustments. *------------------------------------------*/ +// FIXME: flag is undocumented int64 battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int64 damage, int div_, uint16 skill_id, uint16 skill_lv, int flag) { if( !damage ) @@ -3292,6 +3295,7 @@ int64 battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int64 /*========================================== * Calculates GVG related damage adjustments. *------------------------------------------*/ +// FIXME: flag is undocumented int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64 damage,int div_,uint16 skill_id,uint16 skill_lv,int flag) { struct mob_data* md = BL_CAST(BL_MOB, bl); int class_ = status->get_class(bl); @@ -3368,13 +3372,13 @@ void battle_consume_ammo(TBL_PC*sd, int skill_id, int lv) { if (!battle_config.arrow_decrement) return; - if (skill_id) { + if (skill_id && lv) { qty = skill->get_ammo_qty(skill_id, lv); if (!qty) qty = 1; } if(sd->equip_index[EQI_AMMO]>=0) //Qty check should have been done in skill_check_condition - pc->delitem(sd,sd->equip_index[EQI_AMMO],qty,0,1,LOG_TYPE_CONSUME); + pc->delitem(sd, sd->equip_index[EQI_AMMO], qty, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME); sd->state.arrow_atk = 0; } @@ -3428,6 +3432,7 @@ int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id) { /*========================================== * battle_calc_magic_attack [DracoRPG] *------------------------------------------*/ +// FIXME: mflag is undocumented struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag) { int nk; short s_ele = 0; @@ -3606,7 +3611,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list skillratio = sc->data[SC_SPELLFIST]->val2 * 50 + sc->data[SC_SPELLFIST]->val4 * 100;// val4 = used bolt level, val2 = used spellfist level. [Rytech] ad.div_ = 1;// ad mods, to make it work similar to regular hits [Xazax] ad.flag = BF_WEAPON|BF_SHORT; - ad.type = 0; + ad.type = BDT_NORMAL; } /* Fall through */ default: @@ -3754,6 +3759,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list /*========================================== * Calculate Misc damage for skill_id *------------------------------------------*/ +// FIXME: mflag is undocumented struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag) { int temp; short i, nk; @@ -4185,6 +4191,7 @@ void battle_calc_misc_attack_unknown(struct block_list *src, struct block_list * /*========================================== * battle_calc_weapon_attack (by Skotlex) *------------------------------------------*/ +// FIXME: wflag is undocumented struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int wflag) { unsigned int skillratio = 100; //Skill dmg modifiers. @@ -4235,7 +4242,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list flag.infdef = 1; // Reverberation takes 1 damage //Initial Values - wd.type=0; //Normal attack + wd.type = BDT_NORMAL; wd.div_ = skill_id ? skill->get_num(skill_id,skill_lv) : 1; wd.amotion=(skill_id && skill->get_inf(skill_id)&INF_GROUND_SKILL)?0:sstatus->amotion; //Amotion should be 0 for ground skills. if(skill_id == KN_AUTOCOUNTER) @@ -4302,7 +4309,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list case TF_DOUBLE: //For NPC used skill. case GS_CHAINACTION: - wd.type = 0x08; + wd.type = BDT_MULTIHIT; break; case GS_GROUNDDRIFT: @@ -4341,6 +4348,10 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if( tsc && (tsc->data[SC_WUGBITE] || tsc->data[SC_ANKLESNARE] || tsc->data[SC_ELECTRICSHOCKER]) ) wd.div_ = tstatus->size + 2 + ( (rnd()%100 < 50-tstatus->size*10) ? 1 : 0 ); break; + + case NPC_EARTHQUAKE: + wd.flag = (wd.flag&~(BF_WEAPON)) | BF_MAGIC; + break; #ifdef RENEWAL case MO_EXTREMITYFIST: case GS_PIERCINGSHOT: @@ -4367,7 +4378,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list wd.flag |= flag.arrow?BF_LONG:BF_SHORT; if ((!skill_id || skill_id == PA_SACRIFICE) && tstatus->flee2 && rnd()%1000 < tstatus->flee2) { //Check for Lucky Dodge - wd.type=0x0b; + wd.type = BDT_PDODGE; wd.dmg_lv=ATK_LUCKY; if (wd.div_ < 0) wd.div_*=-1; return wd; @@ -4435,13 +4446,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if( rnd()%100 < ( 5*skill_lv > sd->bonus.double_rate ? 5*skill_lv : sc && sc->data[SC_KAGEMUSYA]?sc->data[SC_KAGEMUSYA]->val1*3:sd->bonus.double_rate ) ) { wd.div_ = skill->get_num(TF_DOUBLE,skill_lv?skill_lv:1); - wd.type = 0x08; + wd.type = BDT_MULTIHIT; } } else if( sd->weapontype1 == W_REVOLVER && (skill_lv = pc->checkskill(sd,GS_CHAINACTION)) > 0 && rnd()%100 < 5*skill_lv ) { wd.div_ = skill->get_num(GS_CHAINACTION,skill_lv); - wd.type = 0x08; + wd.type = BDT_MULTIHIT; } else if(sc && sc->data[SC_FEARBREEZE] && sd->weapontype1==W_BOW && (i = sd->equip_index[EQI_AMMO]) >= 0 && sd->inventory_data[i] && sd->status.inventory[i].amount > 1){ @@ -4472,13 +4483,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if ( wd.div_ > 1 ) { wd.div_ = min(wd.div_, sd->status.inventory[i].amount); sc->data[SC_FEARBREEZE]->val4 = wd.div_ - 1; - wd.type = 0x08; + wd.type = BDT_MULTIHIT; } } } //Check for critical - if( !flag.cri && !(wd.type&0x08) && sstatus->cri && + if( !flag.cri && wd.type != BDT_MULTIHIT && sstatus->cri && (!skill_id || skill_id == KN_AUTOCOUNTER || skill_id == SN_SHARPSHOOTING || skill_id == MA_SHARPSHOOTING || @@ -4530,7 +4541,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list flag.cri = 1; } if (flag.cri) { - wd.type = 0x0a; + wd.type = BDT_CRIT; #ifndef RENEWAL flag.idef = flag.idef2 = #endif @@ -5528,7 +5539,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list rnd()%100 < tsc->data[SC_SWORDREJECT]->val2 ) { ATK_RATER(50); - status_fix_damage(target,src,wd.damage,clif->damage(target,src,0,0,wd.damage,0,0,0)); + status_fix_damage(target,src,wd.damage,clif->damage(target,src,0,0,wd.damage,0,BDT_NORMAL,0)); clif->skill_nodamage(target,target,ST_REJECTSWORD,tsc->data[SC_SWORDREJECT]->val1,1); if( --(tsc->data[SC_SWORDREJECT]->val3) <= 0 ) status_change_end(target, SC_SWORDREJECT, INVALID_TIMER); @@ -5634,8 +5645,8 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st rdamage = ratio + (damage)* (10 + sc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10; skill->blown(target, src, skill->get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit->getdir(src), 0); clif->skill_damage(target, src, tick, status_get_amotion(src), 0, rdamage, - 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does - clif->delay_damage(tick + delay, src, target,status_get_amotion(src)+1000,0, rdamage/10, 1, 0); + 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, BDT_SKILL); // This is how official does + clif->delay_damage(tick + delay, src, target,status_get_amotion(src)+1000,0, rdamage/10, 1, BDT_NORMAL); status->damage(src, target, status->damage(target, src, rdamage, 0, 0, 1)/10, 0, 0, 1); status_change_end(target, SC_CRESCENTELBOW, INVALID_TIMER); /* shouldn't this trigger skill->additional_effect? */ @@ -5653,7 +5664,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st int64 rd1 = damage * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage. trdamage += rdamage = rd1 - (damage = rd1 * 30 / 100); // not normalized as intended. - rdelay = clif->skill_damage(src, target, tick, status_get_amotion(src), status_get_dmotion(src), -3000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, 6); + rdelay = clif->skill_damage(src, target, tick, status_get_amotion(src), status_get_dmotion(src), -3000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, BDT_SKILL); skill->blown(target, src, skill->get_blewcount(RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1), unit->getdir(src), 0); if( tsd ) /* is this right? rdamage as both left and right? */ @@ -5680,7 +5691,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st if ( tsd && tsd->bonus.short_weapon_damage_return ) { NORMALIZE_RDAMAGE(damage * tsd->bonus.short_weapon_damage_return / 100); - rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4); + rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, BDT_ENDURE); /* is this right? rdamage as both left and right? */ battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0); @@ -5705,9 +5716,9 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st NORMALIZE_RDAMAGE(damage * sc->data[SC_REFLECTSHIELD]->val2 / 100); #ifndef RENEWAL - rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4); + rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, BDT_ENDURE); #else - rdelay = clif->skill_damage(src, src, tick, delay, status_get_dmotion(src), rdamage, 1, CR_REFLECTSHIELD, 1, 4); + rdelay = clif->skill_damage(src, src, tick, delay, status_get_dmotion(src), rdamage, 1, CR_REFLECTSHIELD, 1, BDT_ENDURE); #endif /* is this right? rdamage as both left and right? */ if( tsd ) @@ -5741,7 +5752,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 ){ NORMALIZE_RDAMAGE(damage * sc->data[SC_SHIELDSPELL_DEF]->val2 / 100); - rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4); + rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, BDT_ENDURE); /* is this right? rdamage as both left and right? */ if( tsd ) @@ -5755,7 +5766,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st if( ssc->data[SC_INSPIRATION] ) { NORMALIZE_RDAMAGE(damage / 100); - rdelay = clif->delay_damage(tick+delay,target, target, status_get_amotion(target), status_get_dmotion(target), rdamage, 1, 4); + rdelay = clif->delay_damage(tick+delay,target, target, status_get_amotion(target), status_get_dmotion(target), rdamage, 1, BDT_ENDURE); /* is this right? rdamage as both left and right? */ if( sd ) @@ -5770,7 +5781,7 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st if ( tsd && tsd->bonus.long_weapon_damage_return ) { NORMALIZE_RDAMAGE(damage * tsd->bonus.long_weapon_damage_return / 100); - rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4); + rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, BDT_ENDURE); /* is this right? rdamage as both left and right? */ battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0); @@ -5865,7 +5876,7 @@ int battle_damage_area(struct block_list *bl, va_list ap) { battle->delay_damage(tick, amotion,src,bl,0,CR_REFLECTSHIELD,0,damage,ATK_DEF,0,true); else status_fix_damage(src,bl,damage,0); - clif->damage(bl,bl,amotion,dmotion,damage,1,ATK_BLOCK,0); + clif->damage(bl,bl,amotion,dmotion,damage,1,BDT_ENDURE,0); if( !(src->type == BL_PC && ((TBL_PC*)src)->state.autocast) ) skill->additional_effect(src, bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick); map->freeblock_unlock(); @@ -5876,6 +5887,7 @@ int battle_damage_area(struct block_list *bl, va_list ap) { /*========================================== * Do a basic physical attack (call trough unit_attack_timer) *------------------------------------------*/ +// FIXME: flag is undocumented enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* target, int64 tick, int flag) { struct map_session_data *sd = NULL, *tsd = NULL; struct status_data *sstatus, *tstatus; @@ -5957,7 +5969,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t if(dist <= 0 || (!map->check_dir(dir,t_dir) && dist <= tstatus->rhw.range+1)) { uint16 skill_lv = tsc->data[SC_AUTOCOUNTER]->val1; clif->skillcastcancel(target); //Remove the casting bar. [Skotlex] - clif->damage(src, target, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS. + clif->damage(src, target, sstatus->amotion, 1, 0, 1, BDT_NORMAL, 0); //Display MISS. status_change_end(target, SC_AUTOCOUNTER, INVALID_TIMER); skill->attack(BF_WEAPON,target,target,src,KN_AUTOCOUNTER,skill_lv,tick,0); return ATK_BLOCK; @@ -5970,7 +5982,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t status_change_end(target, SC_BLADESTOP_WAIT, INVALID_TIMER); if(sc_start4(target, src, SC_BLADESTOP, 100, sd?pc->checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration)) { //Target locked. - clif->damage(src, target, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS. + clif->damage(src, target, sstatus->amotion, 1, 0, 1, BDT_NORMAL, 0); //Display MISS. clif->bladestop(target, src->id, 1); sc_start4(target, target, SC_BLADESTOP, 100, skill_lv, 0, 0, src->id, duration); return ATK_BLOCK; @@ -6014,18 +6026,6 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t return ATK_DEF; return ATK_MISS; } - if( sc->data[SC_GENTLETOUCH_ENERGYGAIN] ) { - if( sd && rnd()%100 < 10 + 5 * sc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1) - pc->addspiritball(sd, - skill->get_time(MO_CALLSPIRITS, sc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1), - sc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1); - } - if( tsc && tsc->data[SC_GENTLETOUCH_ENERGYGAIN] ) { - if( tsd && rnd()%100 < 10 + 5 * tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1) - pc->addspiritball(tsd, - skill->get_time(MO_CALLSPIRITS, tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1), - tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1); - } if( tsc && tsc->data[SC_MTF_MLEATKED] && rnd()%100 < 20 ) clif->skill_nodamage(target, target, SM_ENDURE, 5, @@ -6048,7 +6048,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t } if( sd && sc->data[SC_FEARBREEZE] && sc->data[SC_FEARBREEZE]->val4 > 0 && sd->status.inventory[sd->equip_index[EQI_AMMO]].amount >= sc->data[SC_FEARBREEZE]->val4 && battle_config.arrow_decrement){ - pc->delitem(sd,sd->equip_index[EQI_AMMO],sc->data[SC_FEARBREEZE]->val4,0,1,LOG_TYPE_CONSUME); + pc->delitem(sd, sd->equip_index[EQI_AMMO], sc->data[SC_FEARBREEZE]->val4, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME); sc->data[SC_FEARBREEZE]->val4 = 0; } } @@ -6096,7 +6096,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t (d_bl->type == BL_PC && ((TBL_PC*)d_bl)->devotion[sce->val2] == target->id) ) && check_distance_bl(target, d_bl, sce->val3) ) { - clif->damage(d_bl, d_bl, 0, 0, damage, 0, 0, 0); + clif->damage(d_bl, d_bl, 0, 0, damage, 0, BDT_NORMAL, 0); status_fix_damage(NULL, d_bl, damage, 0); } else @@ -6104,7 +6104,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t } else if( tsc->data[SC_CIRCLE_OF_FIRE_OPTION] && (wd.flag&BF_SHORT) && target->type == BL_PC ) { struct elemental_data *ed = ((TBL_PC*)target)->ed; if( ed ) { - clif->skill_damage(&ed->bl, target, tick, status_get_amotion(src), 0, -30000, 1, EL_CIRCLE_OF_FIRE, tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1, 6); + clif->skill_damage(&ed->bl, target, tick, status_get_amotion(src), 0, -30000, 1, EL_CIRCLE_OF_FIRE, tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1, BDT_SKILL); skill->attack(BF_MAGIC,&ed->bl,&ed->bl,src,EL_CIRCLE_OF_FIRE,tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1,tick,wd.flag); } } else if( tsc->data[SC_WATER_SCREEN_OPTION] && tsc->data[SC_WATER_SCREEN_OPTION]->val1 ) { @@ -6373,15 +6373,20 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f } break; case BL_MOB: - if(((((TBL_MOB*)target)->special_state.ai == 2 || //Marine Spheres - (((TBL_MOB*)target)->special_state.ai == 3 && battle_config.summon_flora&1)) && //Floras - s_bl->type == BL_PC && src->type != BL_MOB) || (((TBL_MOB*)target)->special_state.ai == 4 && t_bl->id != s_bl->id)) //Zanzoe - { + { + TBL_MOB *md = BL_CAST(BL_MOB, target); + if(( + (md->special_state.ai == AI_SPHERE || (md->special_state.ai == AI_FLORA && battle_config.summon_flora&1)) + && s_bl->type == BL_PC && src->type != BL_MOB + ) + || (md->special_state.ai == AI_ZANZOU && t_bl->id != s_bl->id) + ) { //Targetable by players state |= BCT_ENEMY; strip_enemy = 0; } break; + } case BL_SKILL: { TBL_SKILL *su = (TBL_SKILL*)target; @@ -6544,19 +6549,16 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f && md->guardian_data && (md->guardian_data->g || md->guardian_data->castle->guild_id) ) return 0; // Disable guardians/emperium owned by Guilds on non-woe times. - if( !md->special_state.ai ) - { //Normal mobs - if( - ( target->type == BL_MOB && t_bl->type == BL_PC && ( ((TBL_MOB*)target)->special_state.ai != 4 && ((TBL_MOB*)target)->special_state.ai != 1 ) ) || - ( t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai ) - ) + if (md->special_state.ai == AI_NONE) { + //Normal mobs + struct mob_data *target_md = BL_CAST(BL_MOB, target); + if( (target_md && t_bl->type == BL_PC && target_md->special_state.ai != AI_ZANZOU && target_md->special_state.ai != AI_ATTACK) + || (t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai) ) state |= BCT_PARTY; //Normal mobs with no ai are friends. else state |= BCT_ENEMY; //However, all else are enemies. - } - else - { - if( t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai ) + } else { + if (t_bl->type == BL_MOB && ((TBL_MOB*)t_bl)->special_state.ai == AI_NONE) state |= BCT_ENEMY; //Natural enemy for AI mobs are normal mobs. } break; diff --git a/src/map/battle.h b/src/map/battle.h index b3437dbc3..58490e869 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -77,6 +77,27 @@ enum e_battle_check_target { //New definitions [Skotlex] }; /** + * Values used by (struct Damage).type, as well as clif->damage(type) and clif->skill_damage(type) + * + * Note: some values may not apply in some contexts. + */ +enum battle_dmg_type { + BDT_NORMAL = 0, // Normal attack + //BDT_PICKUP = 1, // Pick up item + //BDT_SITDOWN = 2, // Sit down + //BDT_STANDUP = 3, // Stand up + BDT_ENDURE = 4, // Damage (endure) + BDT_SPLASH = 5, // Splash + BDT_SKILL = 6, // Skill + //BDT_REPEAT = 7, // (repeat damage?) + BDT_MULTIHIT = 8, // Multi-hit damage + BDT_MULTIENDURE = 9, // Multi-hit damage (endure) + BDT_CRIT = 10, // Critical hit + BDT_PDODGE = 11, // Lucky dodge + //BDT_TOUCH = 12, // (touch skill?) +}; + +/** * Structures **/ diff --git a/src/map/battleground.c b/src/map/battleground.c index f0bad2b3d..3c7c1db43 100644 --- a/src/map/battleground.c +++ b/src/map/battleground.c @@ -211,7 +211,7 @@ int bg_team_get_id(struct block_list *bl) { { struct map_session_data *msd; struct mob_data *md = (TBL_MOB*)bl; - if( md->special_state.ai && (msd = map->id2sd(md->master_id)) != NULL ) + if (md->special_state.ai != AI_NONE && (msd = map->id2sd(md->master_id)) != NULL) return msd->bg_id; return md->bg_id; } @@ -538,11 +538,10 @@ void bg_match_over(struct bg_arena *arena, bool canceled) { bg->team_leave(sd, 0); bg->queue_pc_cleanup(sd); } - if( canceled ) - clif->colormes(sd->fd,COLOR_RED,"BG Match Canceled: not enough players"); - else { + if (canceled) + clif->messagecolor_self(sd->fd, COLOR_RED, "BG Match Canceled: not enough players"); + else pc_setglobalreg(sd, script->add_str(arena->delay_var), (unsigned int)time(NULL)); - } } } @@ -766,7 +765,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_ sprintf(response, "You are a deserter! Wait %d minute(s) before you can apply again",(tick-tsec)/60); else sprintf(response, "You are a deserter! Wait %d seconds before you can apply again",(tick-tsec)); - clif->colormes(sd->fd,COLOR_RED,response); + clif->messagecolor_self(sd->fd, COLOR_RED, response); return BGQA_FAIL_DESERTER; } @@ -776,7 +775,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_ sprintf(response, "You can't reapply to this arena so fast. Apply to the different arena or wait %d minute(s)",(tick-tsec)/60); else sprintf(response, "You can't reapply to this arena so fast. Apply to the different arena or wait %d seconds",(tick-tsec)); - clif->colormes(sd->fd,COLOR_RED,response); + clif->messagecolor_self(sd->fd, COLOR_RED, response); return BGQA_FAIL_COOLDOWN; } @@ -800,7 +799,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_ sprintf(response, "Can't apply: not enough members in your team/guild that have not entered the queue in individual mode, minimum is %d",arena->min_team_players); else sprintf(response, "Can't apply: not enough members in your team/guild, minimum is %d",arena->min_team_players); - clif->colormes(sd->fd,COLOR_RED,response); + clif->messagecolor_self(sd->fd, COLOR_RED, response); return BGQA_FAIL_TEAM_COUNT; } } @@ -832,7 +831,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_ sprintf(response, "Can't apply: not enough members in your team/party that have not entered the queue in individual mode, minimum is %d",arena->min_team_players); else sprintf(response, "Can't apply: not enough members in your team/party, minimum is %d",arena->min_team_players); - clif->colormes(sd->fd,COLOR_RED,response); + clif->messagecolor_self(sd->fd, COLOR_RED, response); return BGQA_FAIL_TEAM_COUNT; } } else diff --git a/src/map/buyingstore.c b/src/map/buyingstore.c index 85fef98aa..531a55e71 100644 --- a/src/map/buyingstore.c +++ b/src/map/buyingstore.c @@ -353,7 +353,7 @@ void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int // move item pc->additem(pl_sd, &sd->status.inventory[index], amount, LOG_TYPE_BUYING_STORE); - pc->delitem(sd, index, amount, 1, 0, LOG_TYPE_BUYING_STORE); + pc->delitem(sd, index, amount, 1, DELITEM_NORMAL, LOG_TYPE_BUYING_STORE); pl_sd->buyingstore.items[listidx].amount-= amount; // pay up diff --git a/src/map/channel.c b/src/map/channel.c index 58ff98c2b..f7ab978a6 100644 --- a/src/map/channel.c +++ b/src/map/channel.c @@ -258,7 +258,7 @@ void channel_send(struct channel_data *chan, struct map_session_data *sd, const if (sd && chan->msg_delay != 0 && DIFF_TICK(sd->hchsysch_tick + chan->msg_delay*1000, timer->gettick()) > 0 && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { - clif->colormes(sd->fd,COLOR_RED,msg_sd(sd,1455)); + clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd,1455)); return; } else if (sd) { snprintf(message, 150, "[ #%s ] %s : %s",chan->name,sd->status.name, msg); @@ -352,7 +352,7 @@ enum channel_operation_status channel_join(struct channel_data *chan, struct map } else { sprintf(output, msg_sd(sd,1403), chan->name); // You're now in the '%s' channel } - clif->colormes(sd->fd, COLOR_DEFAULT, output); + clif->messagecolor_self(sd->fd, COLOR_DEFAULT, output); } if (chan->type == HCS_TYPE_ALLY) { @@ -693,7 +693,6 @@ void read_channels_config(void) safestrncpy(channel->config->colors_name[i], config_setting_name(color), HCS_NAME_LENGTH); channel->config->colors[i] = (unsigned int)strtoul(libconfig->setting_get_string_elem(colors,i),NULL,0); - channel->config->colors[i] = (channel->config->colors[i] & 0x0000FF) << 16 | (channel->config->colors[i] & 0x00FF00) | (channel->config->colors[i] & 0xFF0000) >> 16;//RGB to BGR } channel->config->colors_count = color_count; } diff --git a/src/map/chat.c b/src/map/chat.c index a232781ca..e296fddec 100644 --- a/src/map/chat.c +++ b/src/map/chat.c @@ -93,7 +93,7 @@ bool chat_createpcchat(struct map_session_data* sd, const char* title, const cha return false; } - pc_stop_walking(sd,1); + pc_stop_walking(sd, STOPWALKING_FLAG_FIXPOS); cd = chat->create(&sd->bl, title, pass, limit, pub, 0, "", 0, 1, MAX_LEVEL); if( cd ) { @@ -101,7 +101,7 @@ bool chat_createpcchat(struct map_session_data* sd, const char* title, const cha cd->usersd[0] = sd; pc_setchatid(sd,cd->bl.id); pc_stop_attack(sd); - clif->createchat(sd,0); + clif->createchat(sd,0); // 0 = success clif->dispchat(cd,0); return true; } @@ -150,7 +150,7 @@ bool chat_joinchat(struct map_session_data* sd, int chatid, const char* pass) { return false; } - pc_stop_walking(sd,1); + pc_stop_walking(sd, STOPWALKING_FLAG_FIXPOS); cd->usersd[cd->users] = sd; cd->users++; @@ -339,7 +339,7 @@ bool chat_kickchat(struct map_session_data* sd, const char* kickusername) { idb_iput(cd->kick_list,cd->usersd[i]->status.char_id,1); - chat->leave(cd->usersd[i],1); + chat->leave(cd->usersd[i], true); return true; } @@ -440,7 +440,7 @@ bool chat_npckickall(struct chat_data* cd) nullpo_ret(cd); while( cd->users > 0 ) - chat->leave(cd->usersd[cd->users-1],0); + chat->leave(cd->usersd[cd->users-1], false); return true; } diff --git a/src/map/chrif.c b/src/map/chrif.c index 6ac7d5695..d3d0aa10c 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -247,6 +247,7 @@ int chrif_isconnected(void) { * Flag = 1: Character is quitting * Flag = 2: Character is changing map-servers *------------------------------------------*/ +// TODO: Flag enum bool chrif_save(struct map_session_data *sd, int flag) { nullpo_ret(sd); @@ -263,11 +264,11 @@ bool chrif_save(struct map_session_data *sd, int flag) { chrif_check(false); //Character is saved on reconnect. //For data sync - if (sd->state.storage_flag == 2) + if (sd->state.storage_flag == STORAGE_FLAG_GUILD) gstorage->save(sd->status.account_id, sd->status.guild_id, flag); if (flag) - sd->state.storage_flag = 0; //Force close it. + sd->state.storage_flag = STORAGE_FLAG_CLOSED; //Force close it. //Saving of registry values. if (sd->vars_dirty) @@ -401,7 +402,7 @@ bool chrif_changemapserverack(int account_id, int login_id1, int login_id2, int if ( !login_id1 ) { ShowError("chrif_changemapserverack: map server change failed.\n"); - clif->authfail_fd(node->fd, 0); + clif->authfail_fd(node->fd, 0); // Disconnected from server } else clif->changemapserver(node->sd, map_index, x, y, ntohl(ip), ntohs(port)); @@ -465,7 +466,7 @@ int chrif_reconnect(DBKey key, DBData *data, va_list ap) { if( map->mapname2ipport(sd->mapindex,&ip,&port) == 0 ) chrif->changemapserver(sd, ip, port); else //too much lag/timeout is the closest explanation for this error. - clif->authfail_fd(sd->fd, 3); + clif->authfail_fd(sd->fd, 3); // timeout break; } } @@ -643,7 +644,7 @@ void chrif_authfail(int fd) {/* HELLO WORLD. ip in RFIFOL 15 is not being used ( node->sex == sex && node->state == ST_LOGIN ) {// found a match - clif->authfail_fd(node->fd, 0); + clif->authfail_fd(node->fd, 0); // Disconnected from server chrif->auth_delete(account_id, char_id, ST_LOGIN); } } @@ -747,15 +748,15 @@ bool chrif_changeemail(int id, const char *actual_email, const char *new_email) * S 2b0e <accid>.l <name>.24B <type>.w { <additional fields>.12B } * { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w } * Send an account modification request to the login server (via char server). - * type of operation {additional fields}: - * 1: block { n/a } - * 2: ban { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w } - * 3: unblock { n/a } - * 4: unban { n/a } - * 5: changesex { n/a } -- use chrif_changesex - * 6: charban { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w } - * 7: charunban { n/a } - * 8: changecharsex { <sex>.b } -- use chrif_changesex + * type of operation: @see enum zh_char_ask_name + * block { n/a } + * ban { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w } + * unblock { n/a } + * unban { n/a } + * changesex { n/a } -- use chrif_changesex + * charban { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w } + * charunban { n/a } + * changecharsex { <sex>.b } -- use chrif_changesex *------------------------------------------*/ bool chrif_char_ask_name(int acc, const char* character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second) { @@ -767,7 +768,7 @@ bool chrif_char_ask_name(int acc, const char* character_name, unsigned short ope safestrncpy((char*)WFIFOP(chrif->fd,6), character_name, NAME_LENGTH); WFIFOW(chrif->fd,30) = operation_type; - if ( operation_type == 2 || operation_type == 6 ) { + if (operation_type == CHAR_ASK_NAME_BAN || operation_type == CHAR_ASK_NAME_CHARBAN) { WFIFOW(chrif->fd,32) = year; WFIFOW(chrif->fd,34) = month; WFIFOW(chrif->fd,36) = day; @@ -795,7 +796,7 @@ bool chrif_changesex(struct map_session_data *sd, bool change_account) WFIFOW(chrif->fd,0) = 0x2b0e; WFIFOL(chrif->fd,2) = sd->status.account_id; safestrncpy((char*)WFIFOP(chrif->fd,6), sd->status.name, NAME_LENGTH); - WFIFOW(chrif->fd,30) = change_account ? 5 : 8; + WFIFOW(chrif->fd,30) = change_account ? CHAR_ASK_NAME_CHANGESEX : CHAR_ASK_NAME_CHANGECHARSEX; if (!change_account) WFIFOB(chrif->fd,32) = sd->status.sex == SEX_MALE ? SEX_FEMALE : SEX_MALE; WFIFOSET(chrif->fd,44); @@ -812,19 +813,14 @@ bool chrif_changesex(struct map_session_data *sd, bool change_account) /*========================================== * R 2b0f <accid>.l <name>.24B <type>.w <answer>.w * Processing a reply to chrif->char_ask_name() (request to modify an account). - * type of operation: - * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex, 6: charban, 7: charunban, 8: changecharsex - * type of answer: - * 0: login-server request done - * 1: player not found - * 2: gm level too low - * 3: login-server offline + * type of operation: @see chrif_char_ask_name + * type of answer: @see hz_char_ask_name_answer *------------------------------------------*/ bool chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, uint16 answer) { struct map_session_data* sd; char action[25]; char output[256]; - bool charsrv = ( type == 6 || type == 7 ) ? true : false; + bool charsrv = ( type == CHAR_ASK_NAME_CHARBAN || type == CHAR_ASK_NAME_CHARUNBAN ) ? true : false; sd = map->id2sd(acc); @@ -834,19 +830,19 @@ bool chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, u } /* re-use previous msg_number */ - if( type == 6 ) type = 2; - if( type == 7 ) type = 4; + if( type == CHAR_ASK_NAME_CHARBAN ) type = CHAR_ASK_NAME_BAN; + if( type == CHAR_ASK_NAME_CHARUNBAN ) type = CHAR_ASK_NAME_UNBAN; - if( type > 0 && type <= 5 ) + if( type >= CHAR_ASK_NAME_BLOCK && type <= CHAR_ASK_NAME_CHANGESEX ) snprintf(action,25,"%s",msg_sd(sd,427+type)); //block|ban|unblock|unban|change the sex of else snprintf(action,25,"???"); switch( answer ) { - case 0 : sprintf(output, msg_sd(sd,charsrv?434:424), action, NAME_LENGTH, player_name); break; - case 1 : sprintf(output, msg_sd(sd,425), NAME_LENGTH, player_name); break; - case 2 : sprintf(output, msg_sd(sd,426), action, NAME_LENGTH, player_name); break; - case 3 : sprintf(output, msg_sd(sd,427), action, NAME_LENGTH, player_name); break; + case CHAR_ASK_NAME_ANS_DONE: sprintf(output, msg_sd(sd,charsrv?434:424), action, NAME_LENGTH, player_name); break; + case CHAR_ASK_NAME_ANS_NOTFOUND: sprintf(output, msg_sd(sd,425), NAME_LENGTH, player_name); break; + case CHAR_ASK_NAME_ANS_GMLOW: sprintf(output, msg_sd(sd,426), action, NAME_LENGTH, player_name); break; + case CHAR_ASK_NAME_ANS_OFFLINE: sprintf(output, msg_sd(sd,427), action, NAME_LENGTH, player_name); break; default: output[0] = '\0'; break; } @@ -904,14 +900,14 @@ bool chrif_divorceack(int char_id, int partner_id) { sd->status.partner_id = 0; for(i = 0; i < MAX_INVENTORY; i++) if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F) - pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER); + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); } if( ( sd = map->charid2sd(partner_id) ) != NULL && sd->status.partner_id == char_id ) { sd->status.partner_id = 0; for(i = 0; i < MAX_INVENTORY; i++) if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F) - pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER); + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); } return true; diff --git a/src/map/clif.c b/src/map/clif.c index 0dc04a3b8..a8fa2e6e7 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -688,6 +688,7 @@ void clif_authrefuse(int fd, uint8 error_code) /// 109 = BAN_INVALID_PWD_CNT /// 110 = BAN_NOT_ALLOWED_JOBCLASS /// ? = disconnected -> MsgStringTable[3] +// TODO: type enum void clif_authfail_fd(int fd, int type) { if (!fd || !session[fd] || session[fd]->func_parse != clif->parse) //clif_authfail should only be invoked on players! @@ -1520,21 +1521,24 @@ void clif_homskillinfoblock(struct map_session_data *sd) { WFIFOHEAD(fd, 4+37*MAX_HOMUNSKILL); WFIFOW(fd,0)=0x235; - for ( i = 0; i < MAX_HOMUNSKILL; i++){ + for ( i = 0; i < MAX_HOMUNSKILL; i++ ) { int id = hd->homunculus.hskill[i].id; - if (id != 0) { + if ( id != 0 ) { j = id - HM_SKILLBASE; + WFIFOW(fd, len) = id; + WFIFOW(fd, len + 2) = skill->get_inf(id); + WFIFOW(fd, len + 4) = 0; + WFIFOW(fd, len + 6) = hd->homunculus.hskill[j].lv; if ( hd->homunculus.hskill[j].lv ) { - WFIFOW(fd, len) = id; - WFIFOW(fd, len + 2) = skill->get_inf(id); - WFIFOW(fd, len + 4) = 0; - WFIFOW(fd, len + 6) = hd->homunculus.hskill[j].lv; WFIFOW(fd, len + 8) = skill->get_sp(id, hd->homunculus.hskill[j].lv); WFIFOW(fd, len + 10) = skill->get_range2(&sd->hd->bl, id, hd->homunculus.hskill[j].lv); - safestrncpy((char*)WFIFOP(fd, len + 12), skill->get_name(id), NAME_LENGTH); - WFIFOB(fd, len + 36) = (hd->homunculus.hskill[j].lv < homun->skill_tree_get_max(id, hd->homunculus.class_)) ? 1 : 0; - len += 37; + } else { + WFIFOW(fd, len + 8) = 0; + WFIFOW(fd, len + 10) = 0; } + safestrncpy((char*)WFIFOP(fd, len + 12), skill->get_name(id), NAME_LENGTH); + WFIFOB(fd, len + 36) = (hd->homunculus.hskill[j].lv < homun->skill_tree_get_max(id, hd->homunculus.class_)) ? 1 : 0; + len += 37; } } WFIFOW(fd,2)=len; @@ -2294,15 +2298,7 @@ void clif_dropitem(struct map_session_data *sd,int n,int amount) /// Notifies the client, that an inventory item was deleted (ZC_DELETE_ITEM_FROM_BODY). /// 07fa <delete type>.W <index>.W <amount>.W -/// delete type: -/// 0 = Normal -/// 1 = Item used for a skill -/// 2 = Refine failed -/// 3 = Material changed -/// 4 = Moved to storage -/// 5 = Moved to cart -/// 6 = Item sold -/// 7 = Consumed by Four Spirit Analysis (SO_EL_ANALYSIS) skill +/// delete type: @see enum delitem_reason void clif_delitem(struct map_session_data *sd,int n,int amount, short reason) { #if PACKETVER < 20091117 @@ -3464,6 +3460,7 @@ void clif_useitemack(struct map_session_data *sd,int index,int amount,bool ok) /// 0 = Room has been successfully created (opens chat room) /// 1 = Room limit exceeded /// 2 = Same room already exists +// TODO: Flag enum void clif_createchat(struct map_session_data* sd, int flag) { int fd; @@ -4017,11 +4014,11 @@ void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* ds clif->hpmeter_single(sd->fd, dstsd->bl.id, dstsd->battle_status.hp, dstsd->battle_status.max_hp); // display link (sd - dstsd) to sd - ARR_FIND( 0, 5, i, sd->devotion[i] == dstsd->bl.id ); - if( i < 5 ) clif->devotion(&sd->bl, sd); + ARR_FIND( 0, MAX_PC_DEVOTION, i, sd->devotion[i] == dstsd->bl.id ); + if( i < MAX_PC_DEVOTION ) clif->devotion(&sd->bl, sd); // display links (dstsd - devotees) to sd - ARR_FIND( 0, 5, i, dstsd->devotion[i] > 0 ); - if( i < 5 ) clif->devotion(&dstsd->bl, sd); + ARR_FIND( 0, MAX_PC_DEVOTION, i, dstsd->devotion[i] > 0 ); + if( i < MAX_PC_DEVOTION ) clif->devotion(&dstsd->bl, sd); // display link (dstsd - crusader) to sd if( dstsd->sc.data[SC_DEVOTION] && (d_bl = map->id2bl(dstsd->sc.data[SC_DEVOTION]->val1)) != NULL ) clif->devotion(d_bl, sd); @@ -4136,20 +4133,8 @@ int clif_calc_walkdelay(struct block_list *bl,int delay, int type, int damage, i /// Sends a 'damage' packet (src performs action on dst) /// 008a <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.W <div>.W <type>.B <damage2>.W (ZC_NOTIFY_ACT) /// 02e1 <src ID>.L <dst ID>.L <server tick>.L <src speed>.L <dst speed>.L <damage>.L <div>.W <type>.B <damage2>.L (ZC_NOTIFY_ACT2) -/// type: -/// 0 = damage [ damage: total damage, div: amount of hits, damage2: assassin dual-wield damage ] -/// 1 = pick up item -/// 2 = sit down -/// 3 = stand up -/// 4 = damage (endure) -/// 5 = (splash?) -/// 6 = (skill?) -/// 7 = (repeat damage?) -/// 8 = multi-hit damage -/// 9 = multi-hit damage (endure) -/// 10 = critical hit -/// 11 = lucky dodge -/// 12 = (touch skill?) +/// type: @see enum battle_dmg_type +/// for BDT_NORMAL: [ damage: total damage, div: amount of hits, damage2: assassin dual-wield damage ] int clif_damage(struct block_list* src, struct block_list* dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type, int64 in_damage2) { struct packet_damage p; struct status_change *sc; @@ -4227,7 +4212,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, int sdelay, int *------------------------------------------*/ void clif_takeitem(struct block_list* src, struct block_list* dst) { - //clif->damage(src,dst,0,0,0,0,1,0); + //clif->damage(src,dst,0,0,0,0,BDT_PICKUP,0); unsigned char buf[32]; nullpo_retv(src); @@ -4625,26 +4610,33 @@ void clif_skillinfoblock(struct map_session_data *sd) /// 0111 <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <skill name>.24B <upgradable>.B void clif_addskill(struct map_session_data *sd, int id) { - int fd, idx = skill->get_index(id); + int fd, skill_lv, idx = skill->get_index(id); nullpo_retv(sd); fd = sd->fd; if (!fd) return; - if( sd->status.skill[idx].id <= 0 ) + if (sd->status.skill[idx].id <= 0) return; + skill_lv = sd->status.skill[idx].lv; + WFIFOHEAD(fd, packet_len(0x111)); WFIFOW(fd,0) = 0x111; WFIFOW(fd,2) = id; WFIFOL(fd,4) = skill->get_inf(id); - WFIFOW(fd,8) = sd->status.skill[idx].lv; - WFIFOW(fd,10) = skill->get_sp(id,sd->status.skill[idx].lv); - WFIFOW(fd,12)= skill->get_range2(&sd->bl, id,sd->status.skill[idx].lv); + WFIFOW(fd,8) = skill_lv; + if (skill_lv > 0) { + WFIFOW(fd,10) = skill->get_sp(id, skill_lv); + WFIFOW(fd,12) = skill->get_range2(&sd->bl, id, skill_lv); + } else { + WFIFOW(fd,10) = 0; + WFIFOW(fd,12) = 0; + } safestrncpy((char*)WFIFOP(fd,14), skill->get_name(id), NAME_LENGTH); - if( sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT ) - WFIFOB(fd,38) = (sd->status.skill[idx].lv < skill->tree_get_max(id, sd->status.class_))? 1:0; + if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) + WFIFOB(fd,38) = (skill_lv < skill->tree_get_max(id, sd->status.class_))? 1:0; else WFIFOB(fd,38) = 0; WFIFOSET(fd,packet_len(0x111)); @@ -4704,16 +4696,22 @@ void clif_skillinfo(struct map_session_data *sd,int skill_id, int inf) { const int fd = sd->fd; int idx = skill->get_index(skill_id); + int skill_lv = sd->status.skill[idx].lv; WFIFOHEAD(fd,packet_len(0x7e1)); WFIFOW(fd,0) = 0x7e1; WFIFOW(fd,2) = skill_id; WFIFOL(fd,4) = inf?inf:skill->get_inf(skill_id); - WFIFOW(fd,8) = sd->status.skill[idx].lv; - WFIFOW(fd,10) = skill->get_sp(skill_id,sd->status.skill[idx].lv); - WFIFOW(fd,12) = skill->get_range2(&sd->bl,skill_id,sd->status.skill[idx].lv); - if( sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT ) - WFIFOB(fd,14) = (sd->status.skill[idx].lv < skill->tree_get_max(skill_id, sd->status.class_))? 1:0; + WFIFOW(fd,8) = skill_lv; + if (skill_lv > 0) { + WFIFOW(fd,10) = skill->get_sp(skill_id, skill_lv); + WFIFOW(fd,12) = skill->get_range2(&sd->bl, skill_id, skill_lv); + } else { + WFIFOW(fd,10) = 0; + WFIFOW(fd,12) = 0; + } + if (sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) + WFIFOB(fd,14) = (skill_lv < skill->tree_get_max(skill_id, sd->status.class_))? 1:0; else WFIFOB(fd,14) = 0; WFIFOSET(fd,packet_len(0x7e1)); @@ -5351,7 +5349,7 @@ void clif_displaymessage(const int fd, const char* mes) { #if PACKETVER == 20141022 /** for some reason game client crashes depending on message pattern (only for this packet) **/ /** so we redirect to ZC_NPC_CHAT **/ - clif->colormes(fd,COLOR_DEFAULT,mes); + clif->messagecolor_self(fd, COLOR_DEFAULT, mes); #else size_t len; @@ -5571,6 +5569,7 @@ void clif_map_type(struct map_session_data* sd, enum map_type type) { /// Updates PvP ranking (ZC_NOTIFY_RANKING). /// 019a <id>.L <ranking>.L <total>.L +// FIXME: missing documentation for the 'type' parameter void clif_pvpset(struct map_session_data *sd,int pvprank,int pvpnum,int type) { if(type == 2) { @@ -6898,7 +6897,7 @@ void clif_devotion(struct block_list *src, struct map_session_data *tsd) if( sd == NULL ) return; - for( i = 0; i < 5; i++ ) + for( i = 0; i < MAX_PC_DEVOTION; i++ ) WBUFL(buf,6+4*i) = sd->devotion[i]; WBUFW(buf,26) = skill->get_range2(src, CR_DEVOTION, pc->checkskill(sd, CR_DEVOTION)); } @@ -7055,9 +7054,7 @@ void clif_guild_created(struct map_session_data *sd,int flag) /// Notifies the client that it is belonging to a guild (ZC_UPDATE_GDID). /// 016c <guild id>.L <emblem id>.L <mode>.L <ismaster>.B <inter sid>.L <guild name>.24B -/// mode: -/// &0x01 = allow invite -/// &0x10 = allow expel +/// mode: @see enum guild_permission void clif_guild_belonginfo(struct map_session_data *sd, struct guild *g) { int ps,fd; @@ -7307,9 +7304,7 @@ void clif_guild_positionnamelist(struct map_session_data *sd) { /// Guild position information (ZC_POSITION_INFO). /// 0160 <packet len>.W { <position id>.L <mode>.L <ranking>.L <pay rate>.L }* -/// mode: -/// &0x01 = allow invite -/// &0x10 = allow expel +/// mode: @see enum guild_permission /// ranking: /// TODO void clif_guild_positioninfolist(struct map_session_data *sd) { @@ -7337,9 +7332,7 @@ void clif_guild_positioninfolist(struct map_session_data *sd) { /// Notifies clients in a guild about updated position information (ZC_ACK_CHANGE_GUILD_POSITIONINFO). /// 0174 <packet len>.W { <position id>.L <mode>.L <ranking>.L <pay rate>.L <position name>.24B }* -/// mode: -/// &0x01 = allow invite -/// &0x10 = allow expel +/// mode: @see enum guild_permission /// ranking: /// TODO void clif_guild_positionchanged(struct guild *g,int idx) @@ -7453,8 +7446,13 @@ void clif_guild_skillinfo(struct map_session_data* sd) WFIFOW(fd,p+0) = id; WFIFOL(fd,p+2) = skill->get_inf(id); WFIFOW(fd,p+6) = g->skill[i].lv; - WFIFOW(fd,p+8) = skill->get_sp(id, g->skill[i].lv); - WFIFOW(fd,p+10) = skill->get_range(id, g->skill[i].lv); + if ( g->skill[i].lv ) { + WFIFOW(fd, p + 8) = skill->get_sp(id, g->skill[i].lv); + WFIFOW(fd, p + 10) = skill->get_range(id, g->skill[i].lv); + } else { + WFIFOW(fd, p + 8) = 0; + WFIFOW(fd, p + 10) = 0; + } safestrncpy((char*)WFIFOP(fd,p+12), skill->get_name(id), NAME_LENGTH); WFIFOB(fd,p+36)= (g->skill[i].lv < guild->skill_get_max(id) && sd == g->member[0].sd) ? 1 : 0; c++; @@ -8128,28 +8126,41 @@ void clif_specialeffect_value(struct block_list* bl, int effect_id, int num, sen clif->send(buf, packet_len(0x284), bl, SELF); } } -// Modification of clif_messagecolor to send colored messages to players to chat log only (doesn't display overhead) -/// 02c1 <packet len>.W <id>.L <color>.L <message>.?B -int clif_colormes(int fd, enum clif_colors color, const char* msg) { +/** + * Modification of clif_messagecolor to send colored messages to players to chat log only (doesn't display overhead). + * + * 02c1 <packet len>.W <id>.L <color>.L <message>.?B + * + * @param fd Target fd to send the message to + * @param color Message color (RGB format: 0xRRGGBB) + * @param msg Message text + */ +void clif_messagecolor_self(int fd, uint32 color, const char *msg) +{ size_t msg_len = strlen(msg) + 1; WFIFOHEAD(fd,msg_len + 12); WFIFOW(fd,0) = 0x2C1; WFIFOW(fd,2) = msg_len + 12; WFIFOL(fd,4) = 0; - WFIFOL(fd,8) = color_table[color]; + WFIFOL(fd,8) = RGB2BGR(color); safestrncpy((char*)WFIFOP(fd,12), msg, msg_len); WFIFOSET(fd, msg_len + 12); - - return 0; } -/// Monster/NPC color chat [SnakeDrak] (ZC_NPC_CHAT). -/// 02c1 <packet len>.W <id>.L <color>.L <message>.?B -void clif_messagecolor(struct block_list* bl, unsigned int color, const char* msg) { +/** + * Monster/NPC color chat [SnakeDrak] (ZC_NPC_CHAT). + * + * 02c1 <packet len>.W <id>.L <color>.L <message>.?B + * + * @param bl Source block list. + * @param color Message color (RGB format: 0xRRGGBB) + * @param msg Message text + */ +void clif_messagecolor(struct block_list* bl, uint32 color, const char *msg) +{ size_t msg_len = strlen(msg) + 1; uint8 buf[256]; - color = (color & 0x0000FF) << 16 | (color & 0x00FF00) | (color & 0xFF0000) >> 16; // RGB to BGR nullpo_retv(bl); @@ -8161,48 +8172,29 @@ void clif_messagecolor(struct block_list* bl, unsigned int color, const char* ms WBUFW(buf,0) = 0x2C1; WBUFW(buf,2) = msg_len + 12; WBUFL(buf,4) = bl->id; - WBUFL(buf,8) = color; + WBUFL(buf,8) = RGB2BGR(color); memcpy(WBUFP(buf,12), msg, msg_len); clif->send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC); } -/// Public chat message [Valaris] (ZC_NOTIFY_CHAT). -/// 008d <packet len>.W <id>.L <message>.?B -void clif_message(struct block_list* bl, const char* msg) { - unsigned short msg_len = strlen(msg) + 1; - uint8 buf[256]; - nullpo_retv(bl); - - if( msg_len > sizeof(buf)-8 ) { - ShowWarning("clif_message: Truncating too long message '%s' (len=%u).\n", msg, msg_len); - msg_len = sizeof(buf)-8; - } - - WBUFW(buf,0) = 0x8d; - WBUFW(buf,2) = msg_len + 8; - WBUFL(buf,4) = bl->id; - safestrncpy((char*)WBUFP(buf,8), msg, msg_len); - - clif->send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC); -} - /** * Notifies the client that the storage window is still open * * Should only be used in cases where the client closed the * storage window without server's consent **/ -void clif_refresh_storagewindow( struct map_session_data *sd ) { +void clif_refresh_storagewindow(struct map_session_data *sd) +{ // Notify the client that the storage is open - if( sd->state.storage_flag == 1 ) { + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) { storage->sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items)); clif->storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items)); clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE); } // Notify the client that the gstorage is open otherwise it will // remain locked forever and nobody will be able to access it - if( sd->state.storage_flag == 2 ) { + if (sd->state.storage_flag == STORAGE_FLAG_GUILD) { struct guild_storage *gstor; if( (gstor = idb_get(gstorage->db,sd->status.guild_id)) == NULL) { // Shouldn't happen... The information should already be at the map-server @@ -8252,7 +8244,7 @@ void clif_refresh(struct map_session_data *sd) map->foreachinrange(clif->getareachar,&sd->bl,AREA_SIZE,BL_ALL,sd); clif->weather_check(sd); if( sd->chatID ) - chat->leave(sd,0); + chat->leave(sd, false); if( sd->state.vending ) clif->openvending(sd, sd->bl.id, sd->vending); if( pc_issit(sd) ) @@ -8900,12 +8892,13 @@ void clif_channel_msg(struct channel_data *chan, struct map_session_data *sd, ch DBIterator *iter = db_iterator(chan->users); struct map_session_data *user; unsigned short msg_len = strlen(msg) + 1; + uint32 color = channel->config->colors[chan->color]; WFIFOHEAD(sd->fd,msg_len + 12); WFIFOW(sd->fd,0) = 0x2C1; WFIFOW(sd->fd,2) = msg_len + 12; WFIFOL(sd->fd,4) = 0; - WFIFOL(sd->fd,8) = channel->config->colors[chan->color]; + WFIFOL(sd->fd,8) = RGB2BGR(color); safestrncpy((char*)WFIFOP(sd->fd,12), msg, msg_len); for (user = dbi_first(iter); dbi_exists(iter); user = dbi_next(iter)) { @@ -8927,11 +8920,12 @@ void clif_channel_msg2(struct channel_data *chan, char *msg) struct map_session_data *user; unsigned char buf[210]; unsigned short msg_len = strlen(msg) + 1; + uint32 color = channel->config->colors[chan->color]; WBUFW(buf,0) = 0x2C1; WBUFW(buf,2) = msg_len + 12; WBUFL(buf,4) = 0; - WBUFL(buf,8) = channel->config->colors[chan->color]; + WBUFL(buf,8) = RGB2BGR(color); safestrncpy((char*)WBUFP(buf,12), msg, msg_len); for (user = dbi_first(iter); dbi_exists(iter); user = dbi_next(iter)) { @@ -9027,9 +9021,6 @@ void clif_parse_WantToConnection(int fd, struct map_session_data* sd) { /// Notification from the client, that it has finished map loading and is about to display player's character (CZ_NOTIFY_ACTORINIT). /// 007d void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { -#if PACKETVER >= 20090218 - int i; -#endif bool first_time = false; if(sd->bl.prev != NULL) @@ -9214,10 +9205,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { //Auron reported that This skill only triggers when you logon on the map o.O [Skotlex] if ((lv = pc->checkskill(sd,SG_KNOWLEDGE)) > 0) { - if(sd->bl.m == sd->feel_map[0].m - || sd->bl.m == sd->feel_map[1].m - || sd->bl.m == sd->feel_map[2].m) - sc_start(NULL,&sd->bl, SC_KNOWLEDGE, 100, lv, skill->get_time(SG_KNOWLEDGE, lv)); + int i; + for (i = 0; i < MAX_PC_FEELHATE; i++) { + if (sd->bl.m == sd->feel_map[i].m) { + sc_start(NULL,&sd->bl, SC_KNOWLEDGE, 100, lv, skill->get_time(SG_KNOWLEDGE, lv)); + break; + } + } } if(sd->pd && sd->pd->pet.intimate > 900) @@ -9363,14 +9357,17 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { // NPC Quest / Event Icon Check [Kisuka] #if PACKETVER >= 20090218 - for(i = 0; i < map->list[sd->bl.m].qi_count; i++) { - struct questinfo *qi = &map->list[sd->bl.m].qi_data[i]; - if( quest->check(sd, qi->quest_id, HAVEQUEST) == -1 ) {// Check if quest is not started - if( qi->hasJob ) { // Check if quest is job-specific, check is user is said job class. - if( sd->class_ == qi->job ) + { + int i; + for(i = 0; i < map->list[sd->bl.m].qi_count; i++) { + struct questinfo *qi = &map->list[sd->bl.m].qi_data[i]; + if( quest->check(sd, qi->quest_id, HAVEQUEST) == -1 ) {// Check if quest is not started + if( qi->hasJob ) { // Check if quest is job-specific, check is user is said job class. + if( sd->class_ == qi->job ) + clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color); + } else { clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color); - } else { - clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color); + } } } } @@ -9679,6 +9676,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) } else if ( sd->fontcolor && !sd->chatID ) { char mout[200]; unsigned char mylen = 1; + uint32 color = 0; if( sd->disguise == -1 ) { sd->fontcolor_tid = timer->add(timer->gettick()+5000, clif->undisguise_timer, sd->bl.id, 0); @@ -9696,11 +9694,12 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) mylen += snprintf(mout, 200, "%s : %s",sd->fakename[0]?sd->fakename:sd->status.name,message); + color = channel->config->colors[sd->fontcolor - 1]; WFIFOHEAD(fd,mylen + 12); WFIFOW(fd,0) = 0x2C1; WFIFOW(fd,2) = mylen + 12; WFIFOL(fd,4) = sd->bl.id; - WFIFOL(fd,8) = channel->config->colors[sd->fontcolor - 1]; + WFIFOL(fd,8) = RGB2BGR(color); safestrncpy((char*)WFIFOP(fd,12), mout, mylen); clif->send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, AREA_WOS); WFIFOL(fd,4) = -sd->bl.id; @@ -9887,7 +9886,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, return; if(action_type != 0x00 && action_type != 0x07) - pc_stop_walking(sd, 1); + pc_stop_walking(sd, STOPWALKING_FLAG_FIXPOS); pc_stop_attack(sd); if(target_id<0 && -target_id == sd->bl.id) // for disguises [Valaris] @@ -10291,7 +10290,7 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd) { if( sd->npc_id ) { if ( !sd->npc_item_flag ) return; - } else if ( sd->state.storage_flag || sd->sc.opt1 ) + } else if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->sc.opt1) ; //You can equip/unequip stuff while storage is open/under status changes else if ( pc_cant_act2(sd) || sd->state.prerefining ) return; @@ -10333,7 +10332,7 @@ void clif_parse_UnequipItem(int fd,struct map_session_data *sd) if( sd->npc_id ) { if ( !sd->npc_item_flag ) return; - } else if ( sd->state.storage_flag || sd->sc.opt1 ) + } else if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->sc.opt1) ; //You can equip/unequip stuff while storage is open/under status changes else if ( pc_cant_act2(sd) || sd->state.prerefining ) return; @@ -10343,7 +10342,7 @@ void clif_parse_UnequipItem(int fd,struct map_session_data *sd) if( battle_config.idletime_criteria & BCIDLE_USEITEM ) sd->idletime = sockt->last_tick; - pc->unequipitem(sd,index,1); + pc->unequipitem(sd,index, PCUNEQUIPITEM_RECALC); } @@ -10571,7 +10570,7 @@ void clif_parse_KickFromChat(int fd,struct map_session_data *sd) /// 00e3 void clif_parse_ChatLeave(int fd, struct map_session_data* sd) { - chat->leave(sd,0); + chat->leave(sd, false); } @@ -10926,7 +10925,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) if( pc_cant_act(sd) && skill_id != RK_REFRESH && !(skill_id == SR_GENTLETOUCH_CURE && (sd->sc.opt1 == OPT1_STONE || sd->sc.opt1 == OPT1_FREEZE || sd->sc.opt1 == OPT1_STUN)) - && ( sd->state.storage_flag && !(tmp&INF_SELF_SKILL) ) // SELF skills can be used with the storage open, issue: 8027 + && (sd->state.storage_flag != STORAGE_FLAG_CLOSED && !(tmp&INF_SELF_SKILL)) // SELF skills can be used with the storage open, issue: 8027 ) return; @@ -11131,7 +11130,7 @@ void clif_parse_UseSkillMap(int fd, struct map_session_data* sd) return; // It is possible to use teleport with the storage window open issue:8027 - if( pc_cant_act(sd) && (!sd->state.storage_flag && skill_id != AL_TELEPORT) ) { + if (pc_cant_act(sd) && (sd->state.storage_flag == STORAGE_FLAG_CLOSED && skill_id != AL_TELEPORT)) { clif_menuskill_clear(sd); return; } @@ -11474,9 +11473,9 @@ void clif_parse_MoveToKafra(int fd, struct map_session_data *sd) if (item_index < 0 || item_index >= MAX_INVENTORY || item_amount < 1) return; - if (sd->state.storage_flag == 1) + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) storage->add(sd, item_index, item_amount); - else if (sd->state.storage_flag == 2) + else if (sd->state.storage_flag == STORAGE_FLAG_GUILD) gstorage->add(sd, item_index, item_amount); } @@ -11492,9 +11491,9 @@ void clif_parse_MoveFromKafra(int fd,struct map_session_data *sd) item_index = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[0])-1; item_amount = RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[1]); - if (sd->state.storage_flag == 1) + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) storage->get(sd, item_index, item_amount); - else if(sd->state.storage_flag == 2) + else if(sd->state.storage_flag == STORAGE_FLAG_GUILD) gstorage->get(sd, item_index, item_amount); } @@ -11508,9 +11507,9 @@ void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd) if (!pc_iscarton(sd)) return; - if (sd->state.storage_flag == 1) + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) storage->addfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4)); - else if (sd->state.storage_flag == 2) + else if (sd->state.storage_flag == STORAGE_FLAG_GUILD) gstorage->addfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4)); } @@ -11524,9 +11523,9 @@ void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd) if (!pc_iscarton(sd)) return; - if (sd->state.storage_flag == 1) + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) storage->gettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4)); - else if (sd->state.storage_flag == 2) + else if (sd->state.storage_flag == STORAGE_FLAG_GUILD) gstorage->gettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4)); } @@ -11535,9 +11534,9 @@ void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd) /// 00f7 void clif_parse_CloseKafra(int fd, struct map_session_data *sd) { - if( sd->state.storage_flag == 1 ) + if( sd->state.storage_flag == STORAGE_FLAG_NORMAL ) storage->close(sd); - else if( sd->state.storage_flag == 2 ) + else if( sd->state.storage_flag == STORAGE_FLAG_GUILD ) gstorage->close(sd); } @@ -14188,7 +14187,7 @@ void clif_parse_AutoRevive(int fd, struct map_session_data *sd) { if (item_position == INDEX_NOT_FOUND) status_change_end(&sd->bl,SC_LIGHT_OF_REGENE,INVALID_TIMER); else - pc->delitem(sd, item_position, 1, 0, 1, LOG_TYPE_CONSUME); + pc->delitem(sd, item_position, 1, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME); clif->skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,4,1); } @@ -14718,7 +14717,7 @@ void clif_Auction_openwindow(struct map_session_data *sd) { int fd = sd->fd; - if( sd->state.storage_flag || sd->state.vending || sd->state.buyingstore || sd->state.trading ) + if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->state.vending || sd->state.buyingstore || sd->state.trading) return; if( !battle_config.feature_auction ) @@ -14964,7 +14963,7 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd) { int zeny = auction.hours*battle_config.auction_feeperhour; - pc->delitem(sd, sd->auction.index, sd->auction.amount, 1, 6, LOG_TYPE_AUCTION); + pc->delitem(sd, sd->auction.index, sd->auction.amount, 1, DELITEM_SOLD, LOG_TYPE_AUCTION); sd->auction.amount = 0; pc->payzeny(sd, zeny, LOG_TYPE_AUCTION, NULL); @@ -15678,8 +15677,13 @@ void clif_mercenary_skillblock(struct map_session_data *sd) WFIFOW(fd,len) = id; WFIFOL(fd,len+2) = skill->get_inf(id); WFIFOW(fd,len+6) = md->db->skill[j].lv; - WFIFOW(fd,len+8) = skill->get_sp(id, md->db->skill[j].lv); - WFIFOW(fd,len+10) = skill->get_range2(&md->bl, id, md->db->skill[j].lv); + if ( md->db->skill[j].lv ) { + WFIFOW(fd, len + 8) = skill->get_sp(id, md->db->skill[j].lv); + WFIFOW(fd, len + 10) = skill->get_range2(&md->bl, id, md->db->skill[j].lv); + } else { + WFIFOW(fd, len + 8) = 0; + WFIFOW(fd, len + 10) = 0; + } safestrncpy((char*)WFIFOP(fd,len+12), skill->get_name(id), NAME_LENGTH); WFIFOB(fd,len+36) = 0; // Skillable for Mercenary? len += 37; @@ -17119,8 +17123,8 @@ void __attribute__ ((unused)) clif_parse_dull(int fd,struct map_session_data *sd } void clif_parse_CashShopOpen(int fd, struct map_session_data *sd) { - if( map->list[sd->bl.m].flag.nocashshop ) { - clif->colormes(fd,COLOR_RED,msg_fd(fd,1489)); //Cash Shop is disabled in this map + if (map->list[sd->bl.m].flag.nocashshop) { + clif->messagecolor_self(fd, COLOR_RED, msg_fd(fd,1489)); //Cash Shop is disabled in this map return; } @@ -17160,8 +17164,8 @@ void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) { unsigned short limit = RFIFOW(fd, 4), i, j; unsigned int kafra_pay = RFIFOL(fd, 6);// [Ryuuzaki] - These are free cash points (strangely #CASH = main cash currently for us, confusing) - if( map->list[sd->bl.m].flag.nocashshop ) { - clif->colormes(fd,COLOR_RED,msg_fd(fd,1489)); //Cash Shop is disabled in this map + if (map->list[sd->bl.m].flag.nocashshop) { + clif->messagecolor_self(fd, COLOR_RED, msg_fd(fd,1489)); //Cash Shop is disabled in this map return; } @@ -17562,8 +17566,8 @@ void clif_parse_BankDeposit(int fd, struct map_session_data* sd) { struct packet_banking_deposit_req *p = P2PTR(fd); int money; - if( !battle_config.feature_banking ) { - clif->colormes(fd,COLOR_RED,msg_fd(fd,1483)); + if (!battle_config.feature_banking) { + clif->messagecolor_self(fd, COLOR_RED, msg_fd(fd,1483)); return; } @@ -17576,8 +17580,8 @@ void clif_parse_BankWithdraw(int fd, struct map_session_data* sd) { struct packet_banking_withdraw_req *p = P2PTR(fd); int money; - if( !battle_config.feature_banking ) { - clif->colormes(fd,COLOR_RED,msg_fd(fd,1483)); + if (!battle_config.feature_banking) { + clif->messagecolor_self(fd, COLOR_RED, msg_fd(fd,1483)); return; } @@ -17589,8 +17593,8 @@ void clif_parse_BankWithdraw(int fd, struct map_session_data* sd) { void clif_parse_BankCheck(int fd, struct map_session_data* sd) { struct packet_banking_check p; - if( !battle_config.feature_banking ) { - clif->colormes(fd,COLOR_RED,msg_fd(fd,1483)); + if (!battle_config.feature_banking) { + clif->messagecolor_self(fd, COLOR_RED, msg_fd(fd,1483)); return; } @@ -17665,7 +17669,7 @@ void clif_parse_GMFullStrip(int fd, struct map_session_data *sd) { for( i = 0; i < EQI_MAX; i++ ) { if( tsd->equip_index[ i ] >= 0 ) - pc->unequipitem( tsd , tsd->equip_index[ i ] , 2 ); + pc->unequipitem(tsd, tsd->equip_index[i], PCUNEQUIPITEM_FORCE); } } /** @@ -18370,21 +18374,11 @@ void clif_bc_ready(void) { /*========================================== * *------------------------------------------*/ -int do_init_clif(bool minimal) { - const char* colors[COLOR_MAX] = { "0xFF0000", "0x00ff00", "0xffffff" }; - int i; - +int do_init_clif(bool minimal) +{ if (minimal) return 0; - /** - * Setup Color Table (saves unnecessary load of strtoul on every call) - **/ - for(i = 0; i < COLOR_MAX; i++) { - color_table[i] = (unsigned int)strtoul(colors[i],NULL,0); - color_table[i] = (color_table[i] & 0x0000FF) << 16 | (color_table[i] & 0x00FF00) | (color_table[i] & 0xFF0000) >> 16;//RGB to BGR - } - packetdb_loaddb(); set_defaultparse(clif->parse); @@ -18679,6 +18673,7 @@ void clif_defaults(void) { clif->disp_message = clif_disp_message; clif->broadcast = clif_broadcast; clif->broadcast2 = clif_broadcast2; + clif->messagecolor_self = clif_messagecolor_self; clif->messagecolor = clif_messagecolor; clif->disp_overhead = clif_disp_overhead; clif->msgtable_skill = clif_msgtable_skill; @@ -18687,7 +18682,6 @@ void clif_defaults(void) { clif->message = clif_displaymessage; clif->messageln = clif_displaymessage2; clif->messages = clif_displaymessage_sprintf; - clif->colormes = clif_colormes; clif->process_message = clif_process_message; clif->wisexin = clif_wisexin; clif->wisall = clif_wisall; diff --git a/src/map/clif.h b/src/map/clif.h index 4426be974..f4402bdf7 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -49,6 +49,12 @@ struct channel_data; #define clif_disp_onlyself(sd,mes,len) clif->disp_message( &(sd)->bl, (mes), (len), SELF ) #define MAX_ROULETTE_LEVEL 7 /** client-defined value **/ #define MAX_ROULETTE_COLUMNS 9 /** client-defined value **/ +#define RGB2BGR(c) ((c & 0x0000FF) << 16 | (c & 0x00FF00) | (c & 0xFF0000) >> 16) + +#define COLOR_RED 0xff0000U +#define COLOR_GREEN 0x00ff00U +#define COLOR_WHITE 0xffffffU +#define COLOR_DEFAULT COLOR_GREEN /** * Enumerations @@ -385,16 +391,6 @@ enum cashshop_error { ERROR_TYPE_NOT_ALL = 8, ///< Some items could not be purchased. (ERROR_TYPE_NOT_ALL) }; -/** - * Color Table - **/ -enum clif_colors { - COLOR_RED, - COLOR_DEFAULT, - COLOR_WHITE, - COLOR_MAX -}; - enum CASH_SHOP_TABS { CASHSHOP_TAB_NEW = 0, CASHSHOP_TAB_POPULAR = 1, @@ -515,6 +511,20 @@ enum CLOSE_ROULETTE_ACK { }; /** + * Reason for item deletion (clif->delitem) + */ +enum delitem_reason { + DELITEM_NORMAL = 0, /// Normal + DELITEM_SKILLUSE = 1, /// Item used for a skill + DELITEM_FAILREFINE = 2, /// Refine failed + DELITEM_MATERIALCHANGE = 3, /// Material changed + DELITEM_TOSTORAGE = 4, /// Moved to storage + DELITEM_TOCART = 5, /// Moved to cart + DELITEM_SOLD = 6, /// Item sold + DELITEM_ANALYSIS = 7, /// Consumed by Four Spirit Analysis (SO_EL_ANALYSIS) skill +}; + +/** * Structures **/ typedef void (*pFunc)(int, struct map_session_data *); //cant help but put it first @@ -538,7 +548,6 @@ struct cdelayed_damage { * Vars **/ struct s_packet_db packet_db[MAX_PACKET_DB + 1]; -unsigned int color_table[COLOR_MAX]; /** * Clif.c Interface @@ -816,7 +825,8 @@ struct clif_interface { void (*disp_message) (struct block_list* src, const char* mes, size_t len, enum send_target target); void (*broadcast) (struct block_list* bl, const char* mes, size_t len, int type, enum send_target target); void (*broadcast2) (struct block_list* bl, const char* mes, size_t len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target); - void (*messagecolor) (struct block_list* bl, unsigned int color, const char* msg); + void (*messagecolor_self) (int fd, uint32 color, const char *msg); + void (*messagecolor) (struct block_list* bl, uint32 color, const char* msg); void (*disp_overhead) (struct block_list *bl, const char* mes); void (*msgtable) (struct map_session_data* sd, unsigned short msg_id); void (*msgtable_num) (struct map_session_data *sd, unsigned short msg_id, int value); @@ -825,7 +835,6 @@ struct clif_interface { void (*messageln) (const int fd, const char* mes); /* message+s(printf) */ void (*messages) (const int fd, const char *mes, ...) __attribute__((format(printf, 2, 3))); - int (*colormes) (int fd, enum clif_colors color, const char* msg); bool (*process_message) (struct map_session_data *sd, int format, char **name_, size_t *namelen_, char **message_, size_t *messagelen_); void (*wisexin) (struct map_session_data *sd,int type,int flag); void (*wisall) (struct map_session_data *sd,int type,int flag); diff --git a/src/map/elemental.c b/src/map/elemental.c index dd97e1970..92915d168 100644 --- a/src/map/elemental.c +++ b/src/map/elemental.c @@ -560,7 +560,7 @@ int elemental_unlocktarget(struct elemental_data *ed) { ed->target_id = 0; elemental_stop_attack(ed); - elemental_stop_walking(ed,1); + elemental_stop_walking(ed, STOPWALKING_FLAG_FIXPOS); return 0; } diff --git a/src/map/guild.c b/src/map/guild.c index 936b4c900..b9c0c8267 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -343,14 +343,12 @@ int guild_create(struct map_session_data *sd, const char *name) if( !tname[0] ) return 0; // empty name - if( sd->status.guild_id ) - {// already in a guild - clif->guild_created(sd,1); + if( sd->status.guild_id ) { + clif->guild_created(sd,1); // You're already in a guild return 0; } if (battle_config.guild_emperium_check && pc->search_inventory(sd, ITEMID_EMPERIUM) == INDEX_NOT_FOUND) { - // item required - clif->guild_created(sd,3); + clif->guild_created(sd,3); // You need the necessary item to create a guild return 0; } @@ -367,14 +365,14 @@ int guild_created(int account_id,int guild_id) { if(sd==NULL) return 0; if(!guild_id) { - clif->guild_created(sd, 2); // Creation failure (presence of the same name Guild) + clif->guild_created(sd, 2); // Creation failure (The guild name already exists) return 0; } //struct guild *g; sd->status.guild_id=guild_id; - clif->guild_created(sd,0); + clif->guild_created(sd,0); // Success if(battle_config.guild_emperium_check) - pc->delitem(sd,pc->search_inventory(sd,ITEMID_EMPERIUM),1,0,0,LOG_TYPE_CONSUME); //emperium consumption + pc->delitem(sd, pc->search_inventory(sd, ITEMID_EMPERIUM), 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); //emperium consumption return 0; } @@ -615,7 +613,7 @@ int guild_invite(struct map_session_data *sd, struct map_session_data *tsd) { if(tsd==NULL || g==NULL) return 0; - if( (i=guild->getposition(g,sd))<0 || !(g->position[i].mode&0x0001) ) + if( (i=guild->getposition(g,sd)) < 0 || !(g->position[i].mode&GPERM_INVITE) ) return 0; //Invite permission. if(!battle_config.invite_request_check) { @@ -840,7 +838,7 @@ int guild_expulsion(struct map_session_data* sd, int guild_id, int account_id, i if(sd->status.guild_id!=guild_id) return 0; - if( (ps=guild->getposition(g,sd))<0 || !(g->position[ps].mode&0x0010) ) + if ((ps=guild->getposition(g,sd))<0 || !(g->position[ps].mode&GPERM_EXPEL)) return 0; //Expulsion permission //Can't leave inside guild castles. @@ -895,7 +893,7 @@ int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, c // update char, if online if(sd != NULL && sd->status.guild_id == guild_id) { // do stuff that needs the guild_id first, BEFORE we wipe it - if (sd->state.storage_flag == 2) //Close the guild storage. + if (sd->state.storage_flag == STORAGE_FLAG_GUILD) //Close the guild storage. gstorage->close(sd); guild->send_dot_remove(sd); if (channel->config->ally) { @@ -926,7 +924,7 @@ void guild_retrieveitembound(int char_id,int aid,int guild_id) { if(gstor && gstor->storage_status == 1) { //Someone is in guild storage, close them struct s_mapiterator* iter = mapit_getallusers(); for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) ) { - if(sd->status.guild_id == guild_id && sd->state.storage_flag == 2) { + if(sd->status.guild_id == guild_id && sd->state.storage_flag == STORAGE_FLAG_GUILD) { gstorage->close(sd); break; } @@ -1095,9 +1093,7 @@ int guild_change_position(int guild_id,int idx,int mode,int exp_mode,const char struct guild_position p; exp_mode = cap_value(exp_mode, 0, battle_config.guild_exp_limit); - //Mode 0x01 <- Invite - //Mode 0x10 <- Expel. - p.mode=mode&0x11; + p.mode=mode&GPERM_BOTH; // Invite and Expel p.exp_mode=exp_mode; safestrncpy(p.name,name,NAME_LENGTH); return intif->guild_position(guild_id,idx,&p); @@ -1750,7 +1746,7 @@ int guild_broken(int guild_id,int flag) for(i=0;i<g->max_member;i++){ // Destroy all relationships if((sd=g->member[i].sd)!=NULL){ - if(sd->state.storage_flag == 2) + if(sd->state.storage_flag == STORAGE_FLAG_GUILD) gstorage->pc_quit(sd,1); sd->status.guild_id=0; sd->guild = NULL; @@ -1910,7 +1906,7 @@ int guild_break(struct map_session_data *sd,char *name) { } } - for(i = 0; i < count; i++) { + for(i = 0; i < count; i++) { // FIXME: Why is this not done in the above loop? skill->del_unitgroup(groups[i],ALC_MARK); } } diff --git a/src/map/homunculus.c b/src/map/homunculus.c index 6bbe1eb20..ee88bf3dc 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -584,7 +584,7 @@ bool homunculus_feed(struct map_session_data *sd, struct homun_data *hd) { clif->hom_food(sd,foodID,0); return false; } - pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME); + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); if ( hd->homunculus.hunger >= 91 ) { homun->consume_intimacy(hd, 50); diff --git a/src/map/irc-bot.c b/src/map/irc-bot.c index d492ad9ca..f7e693191 100644 --- a/src/map/irc-bot.c +++ b/src/map/irc-bot.c @@ -1,6 +1,6 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file -// Base Author: shennetsind @ http://hercules.ws +// Base Author: shennetsind @ http://herc.ws #define HERCULES_CORE diff --git a/src/map/irc-bot.h b/src/map/irc-bot.h index 8dcfea5bd..acd014e71 100644 --- a/src/map/irc-bot.h +++ b/src/map/irc-bot.h @@ -1,6 +1,6 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file -// Base Author: shennetsind @ http://hercules.ws +// Base Author: shennetsind @ http://herc.ws #ifndef MAP_IRC_BOT_H diff --git a/src/map/mail.c b/src/map/mail.c index 7ba7d7470..d7ce9c830 100644 --- a/src/map/mail.c +++ b/src/map/mail.c @@ -14,6 +14,7 @@ #include "itemdb.h" #include "log.h" #include "pc.h" +#include "storage.h" #include "../common/nullpo.h" #include "../common/showmsg.h" @@ -36,7 +37,7 @@ int mail_removeitem(struct map_session_data *sd, short flag) if( sd->mail.amount ) { if (flag) // Item send - pc->delitem(sd, sd->mail.index, sd->mail.amount, 1, 0, LOG_TYPE_MAIL); + pc->delitem(sd, sd->mail.index, sd->mail.amount, 1, DELITEM_NORMAL, LOG_TYPE_MAIL); else clif->additem(sd, sd->mail.index, sd->mail.amount, 0); } @@ -151,7 +152,7 @@ int mail_openmail(struct map_session_data *sd) { nullpo_ret(sd); - if( sd->state.storage_flag || sd->state.vending || sd->state.buyingstore || sd->state.trading ) + if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->state.vending || sd->state.buyingstore || sd->state.trading) return 0; clif->mail_window(sd->fd, 0); diff --git a/src/map/map.c b/src/map/map.c index a407722bb..f8c9e7c01 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1844,13 +1844,13 @@ int map_quit(struct map_session_data *sd) { for( i = 0; i < EQI_MAX; i++ ) { if( sd->equip_index[ i ] >= 0 ) if( !pc->isequip( sd , sd->equip_index[ i ] ) ) - pc->unequipitem( sd , sd->equip_index[ i ] , 2 ); + pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_FORCE); } // Return loot to owner if( sd->pd ) pet->lootitem_drop(sd->pd, sd); - if( sd->state.storage_flag == 1 ) sd->state.storage_flag = 0; // No need to Double Save Storage on Quit. + if( sd->state.storage_flag == STORAGE_FLAG_NORMAL ) sd->state.storage_flag = STORAGE_FLAG_CLOSED; // No need to Double Save Storage on Quit. if( sd->ed ) { elemental->clean_effect(sd->ed); diff --git a/src/map/map.h b/src/map/map.h index 63d2d381f..ab2274d78 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -65,16 +65,6 @@ enum MOBID { MOBID_MAGICDECOY_WIND = 2046, }; -// The following system marks a different job ID system used by the map server, -// which makes a lot more sense than the normal one. [Skotlex] -// These marks the "level" of the job. -#define JOBL_2_1 0x100 //256 -#define JOBL_2_2 0x200 //512 -#define JOBL_2 0x300 -#define JOBL_UPPER 0x1000 //4096 -#define JOBL_BABY 0x2000 //8192 -#define JOBL_THIRD 0x4000 //16384 - // For filtering and quick checking. #define MAPID_BASEMASK 0x00ff #define MAPID_UPPERMASK 0x0fff @@ -266,10 +256,15 @@ enum { RC_DEMIHUMAN, RC_ANGEL, RC_DRAGON, + RC_PLAYER, RC_BOSS, RC_NONBOSS, + RC_MAX, RC_NONDEMIHUMAN, - RC_MAX + RC_NONPLAYER, + RC_DEMIPLAYER, + RC_NONDEMIPLAYER, + RC_ALL = 0xFF }; enum { @@ -296,7 +291,8 @@ enum elements { ELE_DARK, ELE_GHOST, ELE_UNDEAD, - ELE_MAX + ELE_MAX, + ELE_ALL = 0xFF }; /** diff --git a/src/map/mob.c b/src/map/mob.c index 8a8e96508..d3aec6e46 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -378,14 +378,14 @@ bool mob_ksprotected(struct block_list *src, struct block_list *target) { break; // No KS Protected if( sd->bl.id == sce->val1 || // Same Owner - (sce->val2 == 2 && sd->status.party_id && sd->status.party_id == sce->val3) || // Party KS allowed - (sce->val2 == 3 && sd->status.guild_id && sd->status.guild_id == sce->val4) ) // Guild KS allowed + (sce->val2 == KSPROTECT_PARTY && sd->status.party_id && sd->status.party_id == sce->val3) || // Party KS allowed + (sce->val2 == KSPROTECT_GUILD && sd->status.guild_id && sd->status.guild_id == sce->val4) ) // Guild KS allowed break; if( t_sd && ( - (sce->val2 == 1 && sce->val1 != t_sd->bl.id) || - (sce->val2 == 2 && sce->val3 && sce->val3 != t_sd->status.party_id) || - (sce->val2 == 3 && sce->val4 && sce->val4 != t_sd->status.guild_id)) ) + (sce->val2 == KSPROTECT_SELF && sce->val1 != t_sd->bl.id) || + (sce->val2 == KSPROTECT_PARTY && sce->val3 && sce->val3 != t_sd->status.party_id) || + (sce->val2 == KSPROTECT_GUILD && sce->val4 && sce->val4 != t_sd->status.guild_id)) ) break; if( (pl_sd = map->id2sd(sce->val1)) == NULL || pl_sd->bl.m != md->bl.m ) @@ -1298,7 +1298,7 @@ int mob_unlocktarget(struct mob_data *md, int64 tick) { break; default: mob_stop_attack(md); - mob_stop_walking(md,1); //Stop chasing. + mob_stop_walking(md, STOPWALKING_FLAG_FIXPOS); //Stop chasing. md->state.skillstate = MSS_IDLE; if(battle_config.mob_ai&0x8) //Walk instantly after dropping target md->next_walktime = tick+rnd()%1000; @@ -1975,7 +1975,7 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage) case BL_MOB: { struct mob_data* md2 = (TBL_MOB*)src; - if( md2->special_state.ai && md2->master_id ) { + if (md2->special_state.ai != AI_NONE && md2->master_id) { struct map_session_data* msd = map->id2sd(md2->master_id); if( msd ) char_id = msd->status.char_id; @@ -2170,7 +2170,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { if( !(type&2) //No exp && (!map->list[m].flag.pvp || battle_config.pvp_exp) //Pvp no exp rule [MouseJstr] - && (!md->master_id || !md->special_state.ai) //Only player-summoned mobs do not give exp. [Skotlex] + && (!md->master_id || md->special_state.ai == AI_NONE) //Only player-summoned mobs do not give exp. [Skotlex] && (!map->list[m].flag.nobaseexp || !map->list[m].flag.nojobexp) //Gives Exp ) { //Experience calculation. int bonus = 100; //Bonus on top of your share (common to all attackers). @@ -2298,9 +2298,9 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { } //End EXP giving. if( !(type&1) && !map->list[m].flag.nomobloot && !md->state.rebirth && ( - !md->special_state.ai || //Non special mob + md->special_state.ai == AI_NONE || //Non special mob battle_config.alchemist_summon_reward == 2 || //All summoned give drops - (md->special_state.ai==2 && battle_config.alchemist_summon_reward == 1) //Marine Sphere Drops items. + (md->special_state.ai == AI_SPHERE && battle_config.alchemist_summon_reward == 1) //Marine Sphere Drops items. ) ) { // Item Drop struct item_drop_list *dlist = ers_alloc(item_drop_list_ers, struct item_drop_list); @@ -2473,7 +2473,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { timer->add(tick + (!battle_config.delay_battle_damage?500:0), mob->delay_item_drop, 0, (intptr_t)dlist); } - if(mvp_sd && md->db->mexp > 0 && !md->special_state.ai) { + if(mvp_sd && md->db->mexp > 0 && md->special_state.ai == AI_NONE) { int log_mvp[2] = {0}; unsigned int mexp; double exp; @@ -2746,7 +2746,7 @@ int mob_class_change (struct mob_data *md, int class_) if( mob_is_treasure(md) ) return 0; //Treasure Boxes - if( md->special_state.ai > 1 ) + if( md->special_state.ai > AI_ATTACK ) return 0; //Marine Spheres and Floras. if( mob->is_clone(md->class_) ) @@ -2764,7 +2764,7 @@ int mob_class_change (struct mob_data *md, int class_) memcpy(md->name,md->db->jname,NAME_LENGTH); mob_stop_attack(md); - mob_stop_walking(md, 0); + mob_stop_walking(md, STOPWALKING_FLAG_NONE); unit->skillcastcancel(&md->bl, 0); status->set_viewdata(&md->bl, class_); clif->class_change(&md->bl, md->vd->class_, 1); @@ -3016,7 +3016,7 @@ struct block_list *mob_getfriendhprate(struct mob_data *md,int min_rate,int max_ nullpo_retr(NULL, md); - if (md->special_state.ai) //Summoned creatures. [Skotlex] + if (md->special_state.ai != AI_NONE) //Summoned creatures. [Skotlex] type = BL_PC; map->foreachinrange(mob->getfriendhprate_sub, &md->bl, 8, type,md,min_rate,max_rate,&fr); @@ -3302,7 +3302,7 @@ int mobskill_event(struct mob_data *md, struct block_list *src, int64 tick, int if(md->bl.prev == NULL || md->status.hp <= 0) return 0; - if( md->special_state.ai == 2 ) {//LOne WOlf explained that ANYONE can trigger the marine countdown skill. [Skotlex] + if (md->special_state.ai == AI_SPHERE) {//LOne WOlf explained that ANYONE can trigger the marine countdown skill. [Skotlex] md->state.alchemist = 1; return mob->skill_use(md, timer->gettick(), MSC_ALCHEMIST); } diff --git a/src/map/mob.h b/src/map/mob.h index 02ae1630a..0a5844f39 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -38,7 +38,7 @@ #define MOB_CLONE_END MAX_MOB_DB //Used to determine default enemy type of mobs (for use in each in range calls) -#define DEFAULT_ENEMY_TYPE(md) ((md)->special_state.ai?BL_CHAR:BL_MOB|BL_PC|BL_HOM|BL_MER) +#define DEFAULT_ENEMY_TYPE(md) ((md)->special_state.ai != AI_NONE ?BL_CHAR:BL_MOB|BL_PC|BL_HOM|BL_MER) #define MAX_MOB_CHAT 250 //Max Skill's messages @@ -79,11 +79,23 @@ enum size { }; enum ai { - AI_NONE = 0, - AI_ATTACK, - AI_SPHERE, - AI_FLORA, - AI_ZANZOU, + AI_NONE = 0, //0: Normal mob. + AI_ATTACK, //1: Standard summon, attacks mobs. + AI_SPHERE, //2: Alchemist Marine Sphere + AI_FLORA, //3: Alchemist Summon Flora + AI_ZANZOU, //4: Summon Zanzou + + AI_MAX +}; + +/** + * Acceptable values for map_session_data.state.noks + */ +enum ksprotection_mode { + KSPROTECT_NONE = 0, + KSPROTECT_SELF = 1, + KSPROTECT_PARTY = 2, + KSPROTECT_GUILD = 3, }; struct mob_skill { @@ -141,13 +153,8 @@ struct mob_data { struct mob_db *db; //For quick data access (saves doing mob_db(md->class_) all the time) [Skotlex] char name[NAME_LENGTH]; struct { - unsigned int size : 2; //Small/Big monsters. - unsigned int ai : 4; //Special AI for summoned monsters. - //0: Normal mob. - //1: Standard summon, attacks mobs. - //2: Alchemist Marine Sphere - //3: Alchemist Summon Flora - //4: Summon Zanzou + unsigned int size : 2; //Small/Big monsters. @see enum size + unsigned int ai : 4; //Special AI for summoned monsters. @see enum ai unsigned int clone : 1;/* is clone? 1:0 */ } special_state; //Special mob information that does not needs to be zero'ed on mob respawn. struct { diff --git a/src/map/npc.c b/src/map/npc.c index e60a655f0..ef56c7872 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -203,7 +203,7 @@ int npc_enable_sub(struct block_list *bl, va_list ap) if (sd->npc_id != 0) return 0; - pc_stop_walking(sd,1); + pc_stop_walking(sd, STOPWALKING_FLAG_FIXPOS); npc->click(sd,nd); } } @@ -1583,8 +1583,8 @@ bool npc_trader_open(struct map_session_data *sd, struct npc_data *nd) { } /* nothing to display, no items available */ - if( i == nd->u.scr.shop->items ) { - clif->colormes(sd->fd,COLOR_RED, msg_sd(sd,881)); + if (i == nd->u.scr.shop->items) { + clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd,881)); return false; } @@ -2145,7 +2145,7 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list) } } - pc->delitem(sd, idx, amount, 0, 6, LOG_TYPE_NPC); + pc->delitem(sd, idx, amount, 0, DELITEM_SOLD, LOG_TYPE_NPC); } if( z > MAX_ZENY ) @@ -3555,7 +3555,7 @@ const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* st return strchr(start, '\n'); } - if (mobspawn.state.ai > 4 && ai != -1) { + if (mobspawn.state.ai >= AI_MAX && ai != -1) { ShowError("npc_parse_mob: Invalid ai %d for mob ID %d in file '%s', line '%d'.\n", mobspawn.state.ai, class_, filepath, strline(buffer, start - buffer)); if (retval) *retval = EXIT_FAILURE; return strchr(start, '\n'); @@ -3578,7 +3578,7 @@ const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* st mobspawn.level = mob_lv; if (size > 0 && size <= 2) mobspawn.state.size = size; - if (ai > 0 && ai <= 4) + if (ai > AI_NONE && ai < AI_MAX) mobspawn.state.ai = ai; if (mobspawn.num > 1 && battle_config.mob_count_rate != 100) { diff --git a/src/map/packets.h b/src/map/packets.h index db332c033..53278f66e 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -2885,7 +2885,7 @@ packet(0x020d,-1); packet(0x0a2e,6,clif->pDull); //TITLE #endif -/* PacketKeys: http://hercules.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */ +/* PacketKeys: http://herc.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */ #if PACKETVER >= 20110817 packetKeys(0x053D5CED,0x3DED6DED,0x6DED6DED); /* Thanks to Shakto */ #endif diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index 71471e5c6..47e566662 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -1,7 +1,7 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file -/* Hercules Renewal: Phase Two http://hercules.ws/board/topic/383-hercules-renewal-phase-two/ */ +/* Hercules Renewal: Phase Two http://herc.ws/board/topic/383-hercules-renewal-phase-two/ */ #ifndef MAP_PACKETS_STRUCT_H #define MAP_PACKETS_STRUCT_H diff --git a/src/map/party.c b/src/map/party.c index fb738a12b..ccb522809 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -640,7 +640,7 @@ int party_optionchanged(int party_id,int account_id,int exp,int item,int flag) { if( (p=party->search(party_id))==NULL) return 0; - //Flag&1: Exp change denied. Flag&2: Item change denied. + //Flag&0x1: Exp change denied. Flag&0x10: Item change denied. if(!(flag&0x01) && p->party.exp != exp) p->party.exp=exp; if(!(flag&0x10) && p->party.item != item) { diff --git a/src/map/pc.c b/src/map/pc.c index 5fc6469f3..ce4f31f25 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -174,6 +174,28 @@ int pc_spiritball_timer(int tid, int64 tick, int id, intptr_t data) { return 0; } +/** +* Get the possible number of spiritball that a player can call. +* @param sd the affected player structure +* @param min the minimum number of spiritball regardless the level of MO_CALLSPIRITS +* @retval total number of spiritball +**/ +int pc_getmaxspiritball(struct map_session_data *sd, int min) { + int result; + + nullpo_ret(sd); + + result = pc->checkskill(sd, MO_CALLSPIRITS); + + if ( min && result < min ) + result = min; + else if ( sd->sc.data[SC_RAISINGDRAGON] ) + result += sd->sc.data[SC_RAISINGDRAGON]->val1; + if ( result > MAX_SPIRITBALL ) + result = MAX_SPIRITBALL; + return result; +} + int pc_addspiritball(struct map_session_data *sd,int interval,int max) { int tid, i; @@ -495,7 +517,7 @@ void pc_rental_expire(struct map_session_data *sd, int i) { } clif->rental_expired(sd->fd, i, sd->status.inventory[i].nameid); - pc->delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER); + pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); } void pc_inventory_rentals(struct map_session_data *sd) { @@ -861,12 +883,12 @@ bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd, clif->updatestatus(b_sd, SP_JOBEXP); // Baby Skills - pc->skill(b_sd, WE_BABY, 1, 0); - pc->skill(b_sd, WE_CALLPARENT, 1, 0); + pc->skill(b_sd, WE_BABY, 1, SKILL_GRANT_PERMANENT); + pc->skill(b_sd, WE_CALLPARENT, 1, SKILL_GRANT_PERMANENT); // Parents Skills - pc->skill(p1_sd, WE_CALLBABY, 1, 0); - pc->skill(p2_sd, WE_CALLBABY, 1, 0); + pc->skill(p1_sd, WE_CALLBABY, 1, SKILL_GRANT_PERMANENT); + pc->skill(p2_sd, WE_CALLBABY, 1, SKILL_GRANT_PERMANENT); return true; } @@ -1119,7 +1141,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim // Rental Timer sd->rental_timer = INVALID_TIMER; - for( i = 0; i < 3; i++ ) + for( i = 0; i < MAX_PC_FEELHATE; i++ ) sd->hate_mob[i] = -1; sd->quest_log = NULL; @@ -1217,7 +1239,7 @@ void pc_authfail(struct map_session_data *sd) int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl) { int class_; - if (!sd || !bl || pos < 0 || pos > 2) + if (!sd || !bl || pos < 0 || pos >= MAX_PC_FEELHATE) return 0; if (sd->hate_mob[pos] != -1) { //Can't change hate targets. @@ -1777,7 +1799,7 @@ int pc_disguise(struct map_session_data *sd, int class_) { if( class_ == -1 && sd->disguise == sd->status.class_ ) { clif->clearunit_single(-sd->bl.id,CLR_OUTSIGHT,sd->fd); } else if ( class_ != sd->status.class_ ) { - pc_stop_walking(sd, 0); + pc_stop_walking(sd, STOPWALKING_FLAG_NONE); clif->clearunit_area(&sd->bl, CLR_OUTSIGHT); } } @@ -2783,24 +2805,56 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) switch(type){ case SP_ADDELE: - if(type2 >= ELE_MAX) { + if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) { ShowError("pc_bonus2: SP_ADDELE: Invalid element %d\n", type2); break; } - if(!sd->state.lr_flag) - sd->right_weapon.addele[type2]+=val; - else if(sd->state.lr_flag == 1) - sd->left_weapon.addele[type2]+=val; - else if(sd->state.lr_flag == 2) - sd->arrow_addele[type2]+=val; + if ( type2 == ELE_ALL ) { + for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ ) { + if ( !sd->state.lr_flag ) + sd->right_weapon.addele[i] += val; + else if ( sd->state.lr_flag == 1 ) + sd->left_weapon.addele[i] += val; + else if ( sd->state.lr_flag == 2 ) + sd->arrow_addele[i] += val; + } + } else { + if(!sd->state.lr_flag) + sd->right_weapon.addele[type2] += val; + else if(sd->state.lr_flag == 1) + sd->left_weapon.addele[type2] += val; + else if(sd->state.lr_flag == 2) + sd->arrow_addele[type2] += val; + } break; case SP_ADDRACE: - if(!sd->state.lr_flag) - sd->right_weapon.addrace[type2]+=val; - else if(sd->state.lr_flag == 1) - sd->left_weapon.addrace[type2]+=val; - else if(sd->state.lr_flag == 2) - sd->arrow_addrace[type2]+=val; + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus2: SP_ADDRACE: Invalid Race(%d)\n",type2); + break; + } + if ( type2 >= RC_MAX ) { + for ( i = RC_FORMLESS; i < RC_MAX; i++ ) { + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + if ( !sd->state.lr_flag ) + sd->right_weapon.addrace[i] += val; + else if ( sd->state.lr_flag == 1 ) + sd->left_weapon.addrace[i] += val; + else if ( sd->state.lr_flag == 2 ) + sd->arrow_addrace[i] += val; + } + } else { + if(!sd->state.lr_flag) + sd->right_weapon.addrace[type2] += val; + else if(sd->state.lr_flag == 1) + sd->left_weapon.addrace[type2] += val; + else if(sd->state.lr_flag == 2) + sd->arrow_addrace[type2] += val; + } break; case SP_ADDSIZE: if(!sd->state.lr_flag) @@ -2811,16 +2865,40 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) sd->arrow_addsize[type2]+=val; break; case SP_SUBELE: - if(type2 >= ELE_MAX) { + if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) { ShowError("pc_bonus2: SP_SUBELE: Invalid element %d\n", type2); break; } - if(sd->state.lr_flag != 2) - sd->subele[type2]+=val; + if(sd->state.lr_flag != 2) { + if ( type2 == ELE_ALL ) { + for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ ){ + sd->subele[i] += val; + } + } else { + sd->subele[type2] += val; + } + } break; case SP_SUBRACE: - if(sd->state.lr_flag != 2) - sd->subrace[type2]+=val; + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus2: SP_SUBRACE: Invalid Race(%d)\n",type2); + break; + } + if(sd->state.lr_flag != 2) { + if (type2 >= RC_MAX ) { + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + sd->subrace[i] += val; + } + } else { + sd->subrace[type2]+=val; + } + } break; case SP_ADDEFF: if (type2 > SC_MAX) { @@ -2849,24 +2927,57 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) sd->reseff[type2-SC_COMMON_MIN]= cap_value(i, 0, 10000); break; case SP_MAGIC_ADDELE: - if(type2 >= ELE_MAX) { + if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) { ShowError("pc_bonus2: SP_MAGIC_ADDELE: Invalid element %d\n", type2); break; } - if(sd->state.lr_flag != 2) - sd->magic_addele[type2]+=val; + if ( sd->state.lr_flag != 2 ) { + if ( type2 == ELE_ALL ) { + for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ ) + sd->magic_addele[i] += val; + } else { + sd->magic_addele[type2] += val; + } + } break; case SP_MAGIC_ADDRACE: - if(sd->state.lr_flag != 2) - sd->magic_addrace[type2]+=val; + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus2: SP_MAGIC_ADDRACE: Invalid Race(%d)\n",type2); + break; + } + if(sd->state.lr_flag != 2){ + if ( type2 >= RC_MAX ){ + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + sd->magic_addrace[i] += val; + } + } else { + sd->magic_addrace[type2]+=val; + } + } break; case SP_MAGIC_ADDSIZE: if(sd->state.lr_flag != 2) sd->magic_addsize[type2]+=val; break; case SP_MAGIC_ATK_ELE: - if(sd->state.lr_flag != 2) - sd->magic_atk_ele[type2]+=val; + if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) { + ShowError("pc_bonus2: SP_MAGIC_ATK_ELE: Invalid element %d\n", type2); + break; + } + if ( sd->state.lr_flag != 2 ) { + if ( type2 == ELE_ALL ) { + for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ ) + sd->magic_atk_ele[i] += val; + } else { + sd->magic_atk_ele[type2] += val; + } + } break; case SP_ADD_DAMAGE_CLASS: switch (sd->state.lr_flag) { @@ -3015,19 +3126,40 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) } break; case SP_WEAPON_COMA_ELE: - if(type2 >= ELE_MAX) { + if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) { ShowError("pc_bonus2: SP_WEAPON_COMA_ELE: Invalid element %d\n", type2); break; } if(sd->state.lr_flag == 2) break; - sd->weapon_coma_ele[type2] += val; + if ( type2 == ELE_ALL ) { + for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ ) + sd->weapon_coma_ele[i] += val; + } else { + sd->weapon_coma_ele[type2] += val; + } sd->special_state.bonus_coma = 1; break; case SP_WEAPON_COMA_RACE: + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus2: SP_WEAPON_COMA_RACE: Invalid Race(%d)\n",type2); + break; + } if(sd->state.lr_flag == 2) break; - sd->weapon_coma_race[type2] += val; + if ( type2 >= RC_MAX ) { + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + sd->weapon_coma_race[i] += val; + } + } else { + sd->weapon_coma_race[type2] += val; + } sd->special_state.bonus_coma = 1; break; case SP_WEAPON_ATK: @@ -3039,8 +3171,25 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) sd->weapon_atk_rate[type2]+=val; break; case SP_CRITICAL_ADDRACE: - if(sd->state.lr_flag != 2) - sd->critaddrace[type2] += val*10; + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus2: SP_CRITICAL_ADDRACE: Invalid Race(%d)\n",type2); + break; + } + if(sd->state.lr_flag != 2){ + if ( type2 >= RC_MAX ){ + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + sd->critaddrace[i] += val*10; + } + } else { + sd->critaddrace[type2] += val*10; + } + } break; case SP_ADDEFF_WHENHIT: if (type2 > SC_MAX) { @@ -3211,12 +3360,46 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) sd->itemhealrate[i].rate += val; break; case SP_EXP_ADDRACE: - if(sd->state.lr_flag != 2) - sd->expaddrace[type2]+=val; + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus2: SP_EXP_ADDRACE: Invalid Race(%d)\n",type2); + break; + } + if(sd->state.lr_flag != 2) { + if ( type2 >= RC_MAX ){ + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + sd->expaddrace[i] += val; + } + } else { + sd->expaddrace[type2] += val; + } + } break; case SP_SP_GAIN_RACE: - if(sd->state.lr_flag != 2) - sd->sp_gain_race[type2]+=val; + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus2: SP_SP_GAIN_RACE: Invalid Race(%d)\n",type2); + break; + } + if(sd->state.lr_flag != 2) { + if ( type2 >= RC_MAX ){ + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + sd->sp_gain_race[i] += val; + } + } else { + sd->sp_gain_race[type2] += val; + } + } break; case SP_ADD_MONSTER_DROP_ITEM: if (sd->state.lr_flag != 2) @@ -3235,19 +3418,61 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) } break; case SP_HP_DRAIN_VALUE_RACE: - if(!sd->state.lr_flag) { - sd->right_weapon.hp_drain[type2].value += val; + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus2: SP_HP_DRAIN_VALUE_RACE: Invalid Race(%d)\n",type2); + break; } - else if(sd->state.lr_flag == 1) { - sd->left_weapon.hp_drain[type2].value += val; + if ( type2 >= RC_MAX ){ + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + if(!sd->state.lr_flag) { + sd->right_weapon.hp_drain[i].value += val; + } + else if(sd->state.lr_flag == 1) { + sd->left_weapon.hp_drain[i].value += val; + } + } + } else { + if(!sd->state.lr_flag) { + sd->right_weapon.hp_drain[type2].value += val; + } + else if(sd->state.lr_flag == 1) { + sd->left_weapon.hp_drain[type2].value += val; + } } break; case SP_SP_DRAIN_VALUE_RACE: - if(!sd->state.lr_flag) { - sd->right_weapon.sp_drain[type2].value += val; + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus2: SP_SP_DRAIN_VALUE_RACE: Invalid Race(%d)\n",type2); + break; } - else if(sd->state.lr_flag == 1) { - sd->left_weapon.sp_drain[type2].value += val; + if ( type2 >= RC_MAX ){ + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + if(!sd->state.lr_flag) { + sd->right_weapon.sp_drain[i].value += val; + } + else if(sd->state.lr_flag == 1) { + sd->left_weapon.sp_drain[i].value += val; + } + } + } else { + if(!sd->state.lr_flag) { + sd->right_weapon.sp_drain[type2].value += val; + } + else if(sd->state.lr_flag == 1) { + sd->left_weapon.sp_drain[type2].value += val; + } } break; case SP_IGNORE_MDEF_RATE: @@ -3259,12 +3484,46 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) sd->ignore_def[type2] += val; break; case SP_SP_GAIN_RACE_ATTACK: - if(sd->state.lr_flag != 2) - sd->sp_gain_race_attack[type2] = cap_value(sd->sp_gain_race_attack[type2] + val, 0, INT16_MAX); + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus2: SP_SP_GAIN_RACE_ATTACK: Invalid Race(%d)\n",type2); + break; + } + if(sd->state.lr_flag != 2) { + if ( type2 >= RC_MAX ) { + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + sd->sp_gain_race_attack[i] = cap_value(sd->sp_gain_race_attack[i] + val, 0, INT16_MAX); + } + } else { + sd->sp_gain_race_attack[type2] = cap_value(sd->sp_gain_race_attack[type2] + val, 0, INT16_MAX); + } + } break; case SP_HP_GAIN_RACE_ATTACK: - if(sd->state.lr_flag != 2) - sd->hp_gain_race_attack[type2] = cap_value(sd->hp_gain_race_attack[type2] + val, 0, INT16_MAX); + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus2: SP_HP_GAIN_RACE_ATTACK: Invalid Race(%d)\n",type2); + break; + } + if(sd->state.lr_flag != 2) { + if ( type2 >= RC_MAX ) { + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + sd->hp_gain_race_attack[i] = cap_value(sd->hp_gain_race_attack[i] + val, 0, INT16_MAX); + } + } else { + sd->hp_gain_race_attack[type2] = cap_value(sd->hp_gain_race_attack[type2] + val, 0, INT16_MAX); + } + } break; case SP_SKILL_USE_SP_RATE: //bonus2 bSkillUseSPrate,n,x; if(sd->state.lr_flag == 2) @@ -3370,8 +3629,25 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) break; #ifdef RENEWAL case SP_RACE_TOLERANCE: - if ( sd->state.lr_flag != 2 ) - sd->race_tolerance[type2] += val; + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus2: SP_RACE_TOLERANCE: Invalid Race(%d)\n",type2); + break; + } + if(sd->state.lr_flag != 2) { + if ( type2 >= RC_MAX ) { + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + sd->race_tolerance[i] += val; + } + } else { + sd->race_tolerance[type2] += val; + } + } break; #endif default: @@ -3383,6 +3659,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) { + int i; nullpo_ret(sd); switch(type){ @@ -3432,23 +3709,69 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) } break; case SP_HP_DRAIN_RATE_RACE: - if(!sd->state.lr_flag) { - sd->right_weapon.hp_drain[type2].rate += type3; - sd->right_weapon.hp_drain[type2].per += val; + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus3: SP_HP_DRAIN_RATE_RACE: Invalid Race(%d)\n",type2); + break; } - else if(sd->state.lr_flag == 1) { - sd->left_weapon.hp_drain[type2].rate += type3; - sd->left_weapon.hp_drain[type2].per += val; + if ( type2 >= RC_MAX ) { + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + if(!sd->state.lr_flag) { + sd->right_weapon.hp_drain[i].rate += type3; + sd->right_weapon.hp_drain[i].per += val; + } + else if(sd->state.lr_flag == 1) { + sd->left_weapon.hp_drain[i].rate += type3; + sd->left_weapon.hp_drain[i].per += val; + } + } + } else { + if(!sd->state.lr_flag) { + sd->right_weapon.hp_drain[type2].rate += type3; + sd->right_weapon.hp_drain[type2].per += val; + } + else if(sd->state.lr_flag == 1) { + sd->left_weapon.hp_drain[type2].rate += type3; + sd->left_weapon.hp_drain[type2].per += val; + } } break; case SP_SP_DRAIN_RATE_RACE: - if(!sd->state.lr_flag) { - sd->right_weapon.sp_drain[type2].rate += type3; - sd->right_weapon.sp_drain[type2].per += val; + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus3: SP_SP_DRAIN_RATE_RACE: Invalid Race(%d)\n",type2); + break; } - else if(sd->state.lr_flag == 1) { - sd->left_weapon.sp_drain[type2].rate += type3; - sd->left_weapon.sp_drain[type2].per += val; + if ( type2 >= RC_MAX ) { + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + if(!sd->state.lr_flag) { + sd->right_weapon.sp_drain[i].rate += type3; + sd->right_weapon.sp_drain[i].per += val; + } + else if(sd->state.lr_flag == 1) { + sd->left_weapon.sp_drain[i].rate += type3; + sd->left_weapon.sp_drain[i].per += val; + } + } + } else { + if(!sd->state.lr_flag) { + sd->right_weapon.sp_drain[type2].rate += type3; + sd->right_weapon.sp_drain[type2].per += val; + } + else if(sd->state.lr_flag == 1) { + sd->left_weapon.sp_drain[type2].rate += type3; + sd->left_weapon.sp_drain[type2].per += val; + } } break; case SP_ADDEFF: @@ -3479,21 +3802,33 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) break; case SP_ADDELE: - if (type2 > ELE_MAX) { - ShowWarning("pc_bonus3 (SP_ADDELE): element %d is out of range.\n", type2); + if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) { + ShowError("pc_bonus3: SP_ADDELE: Invalid element %d\n", type2); break; } - if (sd->state.lr_flag != 2) - pc_bonus_addele(sd, (unsigned char)type2, type3, val); + if ( sd->state.lr_flag != 2 ) { + if ( type2 == ELE_ALL ) { + for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ ) + pc_bonus_addele(sd, (unsigned char)i, type3, val); + } else { + pc_bonus_addele(sd, (unsigned char)type2, type3, val); + } + } break; case SP_SUBELE: - if (type2 > ELE_MAX) { - ShowWarning("pc_bonus3 (SP_SUBELE): element %d is out of range.\n", type2); + if( (type2 >= ELE_MAX && type2 != ELE_ALL) || (type2 < ELE_NEUTRAL) ) { + ShowError("pc_bonus3: SP_SUBELE: Invalid element %d\n", type2); break; } - if (sd->state.lr_flag != 2) - pc_bonus_subele(sd, (unsigned char)type2, type3, val); + if ( sd->state.lr_flag != 2 ) { + if ( type2 == ELE_ALL ) { + for ( i = ELE_NEUTRAL; i < ELE_MAX; i++ ) + pc_bonus_subele(sd, (unsigned char)i, type3, val); + } else { + pc_bonus_subele(sd, (unsigned char)type2, type3, val); + } + } break; case SP_SP_VANISH_RATE: if(sd->state.lr_flag != 2) { @@ -3512,6 +3847,7 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) } int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4,int val) { + int i; nullpo_ret(sd); switch(type) { @@ -3544,27 +3880,55 @@ int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4 break; case SP_SET_DEF_RACE: //bonus4 bSetDefRace,n,x,r,y; - if( type2 >= RC_MAX ) { - ShowWarning("pc_bonus4 (DEF_SET): %d is not supported.\n", type2); + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus4: SP_SET_DEF_RACE: Invalid Race(%d)\n",type2); break; } if(sd->state.lr_flag == 2) break; - sd->def_set_race[type2].rate = type3; - sd->def_set_race[type2].tick = type4; - sd->def_set_race[type2].value = val; + if ( type2 >= RC_MAX ) { + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + sd->def_set_race[i].rate = type3; + sd->def_set_race[i].tick = type4; + sd->def_set_race[i].value = val; + } + } else { + sd->def_set_race[type2].rate = type3; + sd->def_set_race[type2].tick = type4; + sd->def_set_race[type2].value = val; + } break; case SP_SET_MDEF_RACE: //bonus4 bSetMDefRace,n,x,r,y; - if( type2 >= RC_MAX ) { - ShowWarning("pc_bonus4 (MDEF_SET): %d is not supported.\n", type2); + if (type2 == RC_MAX || (type2 > RC_NONDEMIPLAYER && type2 != RC_ALL) || type2 < RC_FORMLESS ){ + ShowWarning("pc_bonus4: SP_SET_MDEF_RACE: Invalid Race(%d)\n",type2); break; } if(sd->state.lr_flag == 2) break; - sd->mdef_set_race[type2].rate = type3; - sd->mdef_set_race[type2].tick = type4; - sd->mdef_set_race[type2].value = val; + if ( type2 >= RC_MAX ) { + for ( i = RC_FORMLESS; i < RC_MAX; i++ ){ + if ( (type2 == RC_NONPLAYER && i == RC_PLAYER) || + (type2 == RC_NONDEMIHUMAN && i == RC_DEMIHUMAN) || + (type2 == RC_DEMIPLAYER && (i != RC_PLAYER && i != RC_DEMIHUMAN)) || + (type2 == RC_NONDEMIPLAYER && (i == RC_PLAYER || i == RC_DEMIHUMAN)) + ) + continue; + sd->mdef_set_race[i].rate = type3; + sd->mdef_set_race[i].tick = type4; + sd->mdef_set_race[i].value = val; + } + } else { + sd->mdef_set_race[type2].rate = type3; + sd->mdef_set_race[type2].tick = type4; + sd->mdef_set_race[type2].value = val; + } break; case SP_ADDEFF: @@ -3622,13 +3986,11 @@ int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4 } /*========================================== - * Grants a player a given skill. Flag values are: - * 0 - Grant permanent skill to be bound to skill tree - * 1 - Grant an item skill (temporary) - * 2 - Like 1, except the level granted can stack with previously learned level. - * 3 - Grant skill unconditionally and forever (persistent to job changes and skill resets) + * Grants a player a given skill. + * Flag values: @see enum pc_skill_flag *------------------------------------------*/ -int pc_skill(TBL_PC* sd, int id, int level, int flag) { +int pc_skill(TBL_PC* sd, int id, int level, int flag) +{ uint16 index = 0; nullpo_ret(sd); @@ -3640,13 +4002,13 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) { ShowError("pc_skill: Skill level %d too high. Max lv supported is %d\n", level, MAX_SKILL_LEVEL); return 0; } - if( flag == 2 && sd->status.skill[index].lv + level > MAX_SKILL_LEVEL ) { + if( flag == SKILL_GRANT_TEMPSTACK && sd->status.skill[index].lv + level > MAX_SKILL_LEVEL ) { ShowError("pc_skill: Skill level bonus %d too high. Max lv supported is %d. Curr lv is %d\n", level, MAX_SKILL_LEVEL, sd->status.skill[index].lv); return 0; } switch( flag ){ - case 0: //Set skill data overwriting whatever was there before. + case SKILL_GRANT_PERMANENT: //Set skill data overwriting whatever was there before. sd->status.skill[index].id = id; sd->status.skill[index].lv = level; sd->status.skill[index].flag = SKILL_FLAG_PERMANENT; @@ -3658,7 +4020,7 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) { if( !skill->db[index].inf ) //Only recalculate for passive skills. status_calc_pc(sd, SCO_NONE); break; - case 1: //Item bonus skill. + case SKILL_GRANT_TEMPORARY: //Item bonus skill. if( sd->status.skill[index].id == id ) { if( sd->status.skill[index].lv >= level ) return 0; @@ -3670,7 +4032,7 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) { } sd->status.skill[index].lv = level; break; - case 2: //Add skill bonus on top of what you had. + case SKILL_GRANT_TEMPSTACK: //Add skill bonus on top of what you had. if( sd->status.skill[index].id == id ) { if( sd->status.skill[index].flag == SKILL_FLAG_PERMANENT ) sd->status.skill[index].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[index].lv; // Store previous level. @@ -3680,7 +4042,7 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) { } sd->status.skill[index].lv += level; break; - case 3: + case SKILL_GRANT_UNCONDITIONAL: sd->status.skill[index].id = id; sd->status.skill[index].lv = level; sd->status.skill[index].flag = SKILL_FLAG_PERM_GRANTED; @@ -3692,8 +4054,8 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) { if( !skill->db[index].inf ) //Only recalculate for passive skills. status_calc_pc(sd, SCO_NONE); break; - default: //Unknown flag? - return 0; + default: //Unknown flag? + return 0; } return 1; } @@ -3737,7 +4099,7 @@ int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip) // remember the card id to insert nameid = sd->status.inventory[idx_card].nameid; - if( pc->delitem(sd,idx_card,1,1,0,LOG_TYPE_OTHER) == 1 ) + if( pc->delitem(sd, idx_card, 1, 1, DELITEM_NORMAL, LOG_TYPE_OTHER) == 1 ) {// failed clif->insert_card(sd,idx_equip,idx_card,1); } @@ -4144,6 +4506,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l * @type * 1 : don't notify deletion * 2 : don't notify weight change + * reason: @see enum delitem_reason * Return: * 0 = success * 1 = invalid itemid or negative amount @@ -4161,7 +4524,7 @@ int pc_delitem(struct map_session_data *sd,int n,int amount,int type, short reas sd->weight -= sd->inventory_data[n]->weight*amount ; if( sd->status.inventory[n].amount <= 0 ){ if(sd->status.inventory[n].equip) - pc->unequipitem(sd,n,3); + pc->unequipitem(sd, n, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); memset(&sd->status.inventory[n],0,sizeof(sd->status.inventory[0])); sd->inventory_data[n] = NULL; } @@ -4211,7 +4574,7 @@ int pc_dropitem(struct map_session_data *sd,int n,int amount) if (!map->addflooritem(&sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 2)) return 0; - pc->delitem(sd, n, amount, 1, 0, LOG_TYPE_PICKDROP_PLAYER); + pc->delitem(sd, n, amount, 1, DELITEM_NORMAL, LOG_TYPE_PICKDROP_PLAYER); clif->dropitem(sd, n, amount); return 1; } @@ -4308,12 +4671,12 @@ int pc_isUseitem(struct map_session_data *sd,int n) if ((item->item_usage.flag&INR_SITTING) && (pc_issit(sd) == 1) && (pc_get_group_level(sd) < item->item_usage.override)) { clif->msgtable(sd, MSG_ITEM_NEED_STANDING); - //clif->colormes(sd->fd,COLOR_WHITE,msg_txt(1474)); + //clif->messagecolor_self(sd->fd, COLOR_WHITE, msg_txt(1474)); return 0; // You cannot use this item while sitting. } - if (sd->state.storage_flag && item->type != IT_CASH) { - clif->colormes(sd->fd, COLOR_RED, msg_sd(sd,1475)); + if (sd->state.storage_flag != STORAGE_FLAG_CLOSED && item->type != IT_CASH) { + clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd,1475)); return 0; // You cannot use this item while storage is open. } @@ -4416,8 +4779,8 @@ int pc_isUseitem(struct map_session_data *sd,int n) clif->msgtable(sd, MSG_ITEM_CANT_OBTAIN_WEIGHT); return 0; } - if( !pc->inventoryblank(sd) ) { - clif->colormes(sd->fd,COLOR_RED,msg_sd(sd,1477)); + if (!pc->inventoryblank(sd)) { + clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd,1477)); return 0; } } @@ -4573,7 +4936,7 @@ int pc_useitem(struct map_session_data *sd,int n) { clif->msgtable(sd, MSG_ITEM_CANT_USE_AREA); // This item cannot be used within this area if( battle_config.item_restricted_consumption_type && sd->status.inventory[n].expire_time == 0 ) { clif->useitemack(sd,n,sd->status.inventory[n].amount-1,true); - pc->delitem(sd,n,1,1,0,LOG_TYPE_CONSUME); + pc->delitem(sd, n, 1, 1, DELITEM_NORMAL, LOG_TYPE_CONSUME); } return 0; } @@ -4596,7 +4959,7 @@ int pc_useitem(struct map_session_data *sd,int n) { else { if (sd->status.inventory[n].expire_time == 0) { clif->useitemack(sd, n, amount - 1, true); - pc->delitem(sd, n, 1, 1, 0, LOG_TYPE_CONSUME); // Rental Usable Items are not deleted until expiration + pc->delitem(sd, n, 1, 1, DELITEM_NORMAL, LOG_TYPE_CONSUME); // Rental Usable Items are not deleted until expiration } else { clif->useitemack(sd, n, 0, false); } @@ -4744,7 +5107,7 @@ int pc_putitemtocart(struct map_session_data *sd,int idx,int amount) return 1; if( (flag = pc->cart_additem(sd,item_data,amount,LOG_TYPE_NONE)) == 0 ) - return pc->delitem(sd,idx,amount,0,5,LOG_TYPE_NONE); + return pc->delitem(sd, idx, amount, 0, DELITEM_TOCART, LOG_TYPE_NONE); return flag; } @@ -4803,7 +5166,7 @@ void pc_bound_clear(struct map_session_data *sd, enum e_item_bound_type type) { case IBT_CHARACTER: for( i = 0; i < MAX_INVENTORY; i++ ){ if( sd->status.inventory[i].bound == type ) { - pc->delitem(sd,i,sd->status.inventory[i].amount,0,1,LOG_TYPE_OTHER); + pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_SKILLUSE, LOG_TYPE_OTHER); // FIXME: is this the correct reason flag? } } break; @@ -4817,7 +5180,7 @@ void pc_bound_clear(struct map_session_data *sd, enum e_item_bound_type type) { if(sd->status.inventory[i].bound == type) { if( gstor ) gstorage->additem(sd,gstor,&sd->status.inventory[i],sd->status.inventory[i].amount); - pc->delitem(sd,i,sd->status.inventory[i].amount,0,1,gstor?LOG_TYPE_GSTORAGE:LOG_TYPE_OTHER); + pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_SKILLUSE, gstor ? LOG_TYPE_GSTORAGE : LOG_TYPE_OTHER); // FIXME: is this the correct reason flag? } } if( gstor ) @@ -5086,7 +5449,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short map_index, int x, int for( i = 0; i < EQI_MAX; i++ ) { if( sd->equip_index[ i ] >= 0 ) if( !pc->isequip( sd , sd->equip_index[ i ] ) ) - pc->unequipitem( sd , sd->equip_index[ i ] , 2 ); + pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_FORCE); } if (battle_config.clear_unit_onwarp&BL_PC) skill->clear_unitgroup(&sd->bl); @@ -6083,7 +6446,7 @@ int pc_stop_following (struct map_session_data *sd) sd->followtarget = -1; sd->ud.target_to = 0; - unit->stop_walking(&sd->bl, 1); + unit->stop_walking(&sd->bl, STOPWALKING_FLAG_FIXPOS); return 0; } @@ -6156,7 +6519,7 @@ void pc_baselevelchanged(struct map_session_data *sd) { for( i = 0; i < EQI_MAX; i++ ) { if( sd->equip_index[i] >= 0 ) { if( sd->inventory_data[ sd->equip_index[i] ]->elvmax && sd->status.base_level > (unsigned int)sd->inventory_data[ sd->equip_index[i] ]->elvmax ) - pc->unequipitem(sd, sd->equip_index[i], 3); + pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } } } @@ -6625,14 +6988,12 @@ int pc_skillup(struct map_session_data *sd,uint16 skill_id) { if (!pc_has_permission(sd, PC_PERM_ALL_SKILL)) // may skill everything at any time anyways, and this would cause a huge slowdown clif->skillinfoblock(sd); } else if( battle_config.skillup_limit ){ - if( sd->sktree.second ) + if (sd->sktree.second) clif->msgtable_num(sd, MSG_SKILL_POINTS_LEFT_JOB1, sd->sktree.second); - else if( sd->sktree.third ) + else if (sd->sktree.third) clif->msgtable_num(sd, MSG_SKILL_POINTS_LEFT_JOB2, sd->sktree.third); - else if( pc->calc_skillpoint(sd) < 9 ) { - /* TODO: official response? */ - clif->colormes(sd->fd,COLOR_RED,"You need the basic skills"); - } + else if (pc->calc_skillpoint(sd) < 9) /* TODO: official response? */ + clif->messagecolor_self(sd->fd, COLOR_RED, "You need the basic skills"); } return 0; } @@ -6702,9 +7063,9 @@ int pc_resetlvl(struct map_session_data* sd,int type) nullpo_ret(sd); if (type != 3) //Also reset skills - pc->resetskill(sd, 0); + pc->resetskill(sd, PCRESETSKILL_NONE); - if(type == 1){ + if(type == 1) { sd->status.skill_point=0; sd->status.base_level=1; sd->status.job_level=1; @@ -6722,8 +7083,8 @@ int pc_resetlvl(struct map_session_data* sd,int type) if(sd->status.class_ == JOB_NOVICE_HIGH) { sd->status.status_point=100; // not 88 [celest] // give platinum skills upon changing - pc->skill(sd,142,1,0); - pc->skill(sd,143,1,0); + pc->skill(sd, NV_FIRSTAID, 1, SKILL_GRANT_PERMANENT); + pc->skill(sd, NV_TRICKDEAD, 1, SKILL_GRANT_PERMANENT); } } @@ -6769,7 +7130,7 @@ int pc_resetlvl(struct map_session_data* sd,int type) for(i=0;i<EQI_MAX;i++) { // unequip items that can't be equipped by base 1 [Valaris] if(sd->equip_index[i] >= 0) if(!pc->isequip(sd,sd->equip_index[i])) - pc->unequipitem(sd,sd->equip_index[i],2); + pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_FORCE); } if ((type == 1 || type == 2 || type == 3) && sd->status.party_id) @@ -6847,19 +7208,17 @@ int pc_resetstate(struct map_session_data* sd) /*========================================== * /resetskill - * if flag&1, perform block resync and status_calc call. - * if flag&2, just count total amount of skill points used by player, do not really reset. - * if flag&4, just reset the skills if the player class is a bard/dancer type (for changesex.) + * @param flag: @see enum pc_resetskill_flag *------------------------------------------*/ int pc_resetskill(struct map_session_data* sd, int flag) { int i, inf2, skill_point=0; nullpo_ret(sd); - if( flag&4 && (sd->class_&MAPID_UPPERMASK) != MAPID_BARDDANCER ) + if( flag&PCRESETSKILL_CHSEX && (sd->class_&MAPID_UPPERMASK) != MAPID_BARDDANCER ) return 0; - if( !(flag&2) ) { //Remove stuff lost when resetting skills. + if( !(flag&PCRESETSKILL_RECOUNT) ) { //Remove stuff lost when resetting skills. /** * It has been confirmed on official server that when you reset skills with a ranked tweakwon your skills are not reset (because you have all of them anyway) @@ -6924,12 +7283,12 @@ int pc_resetskill(struct map_session_data* sd, int flag) if( sd->status.skill[i].flag == SKILL_FLAG_PERM_GRANTED ) continue; - if( flag&4 && !skill_ischangesex(i) ) + if( flag&PCRESETSKILL_CHSEX && !skill_ischangesex(i) ) continue; if( inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn ) { //Only handle quest skills in a special way when you can't learn them manually - if( battle_config.quest_skill_reset && !(flag&2) ) { //Wipe them + if( battle_config.quest_skill_reset && !(flag&PCRESETSKILL_RECOUNT) ) { //Wipe them sd->status.skill[i].lv = 0; sd->status.skill[i].flag = 0; } @@ -6940,18 +7299,18 @@ int pc_resetskill(struct map_session_data* sd, int flag) else if( sd->status.skill[i].flag >= SKILL_FLAG_REPLACED_LV_0 ) skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0); - if( !(flag&2) ) {// reset + if( !(flag&PCRESETSKILL_RECOUNT) ) {// reset sd->status.skill[i].lv = 0; sd->status.skill[i].flag = 0; } } - if( flag&2 || !skill_point ) return skill_point; + if( flag&PCRESETSKILL_RECOUNT || !skill_point ) return skill_point; sd->status.skill_point += skill_point; - if( !(flag&2) ) { + if (!(flag&PCRESETSKILL_RECOUNT)) { // Remove all SCs that can't be inactivated without a skill if( sd->sc.data[SC_STORMKICK_READY] ) status_change_end(&sd->bl, SC_STORMKICK_READY, INVALID_TIMER); @@ -6965,7 +7324,7 @@ int pc_resetskill(struct map_session_data* sd, int flag) status_change_end(&sd->bl, SC_DODGE_READY, INVALID_TIMER); } - if( flag&1 ) { + if (flag&PCRESETSKILL_RESYNC) { clif->updatestatus(sd,SP_SKILLPOINT); clif->skillinfoblock(sd); status_calc_pc(sd,SCO_FORCE); @@ -6997,8 +7356,7 @@ int pc_resethate(struct map_session_data* sd) int i; nullpo_ret(sd); - for (i=0; i<3; i++) - { + for (i = 0; i < MAX_PC_FEELHATE; i++) { sd->hate_mob[i] = -1; pc_setglobalreg(sd,script->add_str(pc->sg_info[i].hate_var),0); } @@ -7115,8 +7473,8 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { nullpo_retr(0, sd); - for(j = 0; j < 5; j++) { - if (sd->devotion[j]){ + for (j = 0; j < MAX_PC_DEVOTION; j++) { + if (sd->devotion[j]) { struct map_session_data *devsd = map->id2sd(sd->devotion[j]); if (devsd) status_change_end(&devsd->bl, SC_DEVOTION, INVALID_TIMER); @@ -7220,7 +7578,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { mob->unlocktarget(md,tick); if (battle_config.mobs_level_up && md->status.hp && (unsigned int)md->level < pc->maxbaselv(sd) - && !md->guardian_data && !md->special_state.ai// Guardians/summons should not level. [Skotlex] + && !md->guardian_data && md->special_state.ai == AI_NONE// Guardians/summons should not level. [Skotlex] ) { // monster level up [Valaris] clif->misceffect(&md->bl,0); @@ -7400,7 +7758,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { int n = eq_n[rnd()%eq_num]; if(rnd()%10000 < per){ if(sd->status.inventory[n].equip) - pc->unequipitem(sd,n,3); + pc->unequipitem(sd, n, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); pc->dropitem(sd,n,1); } } @@ -7413,7 +7771,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { || (type == 2 && sd->status.inventory[i].equip) || type == 3) ){ if(sd->status.inventory[i].equip) - pc->unequipitem(sd,i,3); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); pc->dropitem(sd,i,1); break; } @@ -8062,7 +8420,7 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper) for(i=0;i<EQI_MAX;i++) { if(sd->equip_index[i] >= 0) if(!pc->isequip(sd,sd->equip_index[i])) - pc->unequipitem(sd,sd->equip_index[i],2); // unequip invalid item for class + pc->unequipitem(sd,sd->equip_index[i], PCUNEQUIPITEM_FORCE); // unequip invalid item for class } //Change look, if disguised, you need to undisguise @@ -8257,7 +8615,7 @@ int pc_setoption(struct map_session_data *sd,int type) if(pc->checkskill(sd, MC_PUSHCART) < 10) status_calc_pc(sd,SCO_NONE); //Remove speed penalty. if ( sd->equip_index[EQI_AMMO] > 0 ) - pc->unequipitem(sd, sd->equip_index[EQI_AMMO], 2); + pc->unequipitem(sd, sd->equip_index[EQI_AMMO], PCUNEQUIPITEM_FORCE); } #endif @@ -8294,7 +8652,7 @@ int pc_setoption(struct map_session_data *sd,int type) status_change_end(&sd->bl, (sc_type)i, INVALID_TIMER); } if ( sd->equip_index[EQI_AMMO] > 0 ) - pc->unequipitem(sd, sd->equip_index[EQI_AMMO], 2); + pc->unequipitem(sd, sd->equip_index[EQI_AMMO], PCUNEQUIPITEM_FORCE); } if (type&OPTION_FLYING && !(p_type&OPTION_FLYING)) @@ -8348,7 +8706,7 @@ int pc_setcart(struct map_session_data *sd,int type) { clif->clearcart(sd->fd); clif->updatestatus(sd, SP_CARTINFO); if ( sd->equip_index[EQI_AMMO] > 0 ) - pc->unequipitem(sd, sd->equip_index[EQI_AMMO], 2); + pc->unequipitem(sd, sd->equip_index[EQI_AMMO], PCUNEQUIPITEM_FORCE); break; default:/* everything else is an allowed ID so we can move on */ if( !sd->sc.data[SC_PUSH_CART] ) /* first time, so fill cart data */ @@ -9199,7 +9557,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos) for(i=0;i<EQI_MAX;i++) { if(pos & pc->equip_pos[i]) { if(sd->equip_index[i] >= 0) //Slot taken, remove item from there. - pc->unequipitem(sd,sd->equip_index[i],2); + pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_FORCE); sd->equip_index[i] = n; } @@ -9320,15 +9678,13 @@ void pc_unequipitem_pos(struct map_session_data *sd, int n, int pos) /*========================================== * Called when attemting to unequip an item from player - * type: - * 0 - only unequip - * 1 - calculate status after unequipping - * 2 - force unequip + * type: @see enum pc_unequipitem_flag * Return: * 0 = fail * 1 = success *------------------------------------------*/ -int pc_unequipitem(struct map_session_data *sd,int n,int flag) { +int pc_unequipitem(struct map_session_data *sd,int n,int flag) +{ int i,iflag; bool status_cacl = false; int pos; @@ -9340,13 +9696,13 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) { } // if player is berserk then cannot unequip - if (!(flag & 2) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_NO_SWITCH_EQUIP]) ) + if (!(flag&PCUNEQUIPITEM_FORCE) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_NO_SWITCH_EQUIP]) ) { clif->unequipitemack(sd,n,0,UIA_FAIL); return 0; } - if( !(flag&2) && sd->sc.count && sd->sc.data[SC_KYOUGAKU] ) + if( !(flag&PCUNEQUIPITEM_FORCE) && sd->sc.count && sd->sc.data[SC_KYOUGAKU] ) { clif->unequipitemack(sd,n,0,UIA_FAIL); return 0; @@ -9407,7 +9763,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) { } } - if(flag&1 || status_cacl) { + if(flag&PCUNEQUIPITEM_RECALC || status_cacl) { pc->checkallowskill(sd); status_calc_pc(sd,SCO_NONE); } @@ -9478,7 +9834,7 @@ int pc_checkitem(struct map_session_data *sd) if (!itemdb_available(id)) { ShowWarning("Removed invalid/disabled item id %d from inventory (amount=%d, char_id=%d).\n", id, sd->status.inventory[i].amount, sd->status.char_id); - pc->delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER); + pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); continue; } @@ -9552,28 +9908,28 @@ int pc_checkitem(struct map_session_data *sd) continue; if( sd->status.inventory[i].equip&~pc->equippoint(sd,i) ) { - pc->unequipitem(sd, i, 2); + pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE); calc_flag = 1; continue; } - if ( battle_config.unequip_restricted_equipment & 1 ) { + if (battle_config.unequip_restricted_equipment&1) { int j; - for ( j = 0; j < map->list[sd->bl.m].zone->disabled_items_count; j++ ) { - if ( map->list[sd->bl.m].zone->disabled_items[j] == sd->status.inventory[i].nameid ) { - pc->unequipitem( sd, i, 2 ); + for (j = 0; j < map->list[sd->bl.m].zone->disabled_items_count; j++) { + if (map->list[sd->bl.m].zone->disabled_items[j] == sd->status.inventory[i].nameid) { + pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE); calc_flag = 1; } } } - if ( battle_config.unequip_restricted_equipment & 2 ) { - if ( !itemdb_isspecial( sd->status.inventory[i].card[0] ) ) { + if (battle_config.unequip_restricted_equipment&2) { + if (!itemdb_isspecial(sd->status.inventory[i].card[0])) { int j, slot; - for ( slot = 0; slot < MAX_SLOTS; slot++ ) { - for ( j = 0; j < map->list[sd->bl.m].zone->disabled_items_count; j++ ) { - if ( map->list[sd->bl.m].zone->disabled_items[j] == sd->status.inventory[i].card[slot] ) { - pc->unequipitem( sd, i, 2 ); + for (slot = 0; slot < MAX_SLOTS; slot++) { + for (j = 0; j < map->list[sd->bl.m].zone->disabled_items_count; j++) { + if (map->list[sd->bl.m].zone->disabled_items[j] == sd->status.inventory[i].card[slot]) { + pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE); calc_flag = 1; } } @@ -9709,9 +10065,9 @@ int pc_divorce(struct map_session_data *sd) for( i = 0; i < MAX_INVENTORY; i++ ) { if( sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F ) - pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER); + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); if( p_sd->status.inventory[i].nameid == WEDDING_RING_M || p_sd->status.inventory[i].nameid == WEDDING_RING_F ) - pc->delitem(p_sd, i, 1, 0, 0, LOG_TYPE_OTHER); + pc->delitem(p_sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); } clif->divorced(sd, p_sd->status.name); @@ -10477,8 +10833,8 @@ int pc_readdb(void) { // Reset then read attr_fix for(i=0;i<4;i++) - for(j=0;j<ELE_MAX;j++) - for(k=0;k<ELE_MAX;k++) + for ( j = ELE_NEUTRAL; j<ELE_MAX; j++ ) + for ( k = ELE_NEUTRAL; k<ELE_MAX; k++ ) battle->attr_fix_table[i][j][k]=100; sprintf(line, "%s/"DBPATH"attr_fix.txt", map->db_path); @@ -10505,13 +10861,13 @@ int pc_readdb(void) { lv=atoi(split[0]); n=atoi(split[1]); count++; - for(i=0;i<n && i<ELE_MAX;){ + for ( i = ELE_NEUTRAL; i<n && i<ELE_MAX; ) { if( !fgets(line, sizeof(line), fp) ) break; if(line[0]=='/' && line[1]=='/') continue; - for(j=0,p=line;j<n && j<ELE_MAX && p;j++){ + for ( j = ELE_NEUTRAL, p = line; j<n && j<ELE_MAX && p; j++ ) { while(*p==32 && *p>0) p++; battle->attr_fix_table[lv-1][i][j]=atoi(p); @@ -10639,15 +10995,15 @@ void pc_bank_deposit(struct map_session_data *sd, int money) { void pc_bank_withdraw(struct map_session_data *sd, int money) { unsigned int limit_check = money+sd->status.zeny; - if( money <= 0 ) { + if (money <= 0) { clif->bank_withdraw(sd,BWA_UNKNOWN_ERROR); return; - } else if ( money > sd->status.bank_vault ) { + } else if (money > sd->status.bank_vault) { clif->bank_withdraw(sd,BWA_NO_MONEY); return; - } else if ( limit_check > MAX_ZENY ) { + } else if (limit_check > MAX_ZENY) { /* no official response for this scenario exists. */ - clif->colormes(sd->fd,COLOR_RED,msg_sd(sd,1482)); + clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd,1482)); return; } @@ -11247,6 +11603,7 @@ void pc_defaults(void) { pc->addfame = pc_addfame; pc->famerank = pc_famerank; pc->set_hate_mob = pc_set_hate_mob; + pc->getmaxspiritball = pc_getmaxspiritball; pc->readdb = pc_readdb; pc->map_day_timer = map_day_timer; // by [yor] diff --git a/src/map/pc.h b/src/map/pc.h index c3bf1e4cc..8a110a6d1 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -29,7 +29,8 @@ #define MAX_PC_BONUS 10 #define MAX_PC_SKILL_REQUIRE 5 #define MAX_PC_FEELHATE 3 -#define PVP_CALCRANK_INTERVAL 1000 // PVP calculation interval +#define MAX_PC_DEVOTION 5 ///< Max amount of devotion targets +#define PVP_CALCRANK_INTERVAL 1000 ///< PVP calculation interval //Equip indexes constants. (eg: sd->equip_index[EQI_AMMO] returns the index //where the arrows are equipped) @@ -57,6 +58,20 @@ enum equip_index { EQI_SHADOW_ACC_L, EQI_MAX }; + +enum pc_unequipitem_flag { + PCUNEQUIPITEM_NONE = 0x0, ///< Just unequip + PCUNEQUIPITEM_RECALC = 0x1, ///< Recalculate status after unequipping + PCUNEQUIPITEM_FORCE = 0x2, ///< Force unequip +}; + +enum pc_resetskill_flag { + PCRESETSKILL_NONE = 0x0, + PCRESETSKILL_RESYNC = 0x1, // perform block resync and status_calc call + PCRESETSKILL_RECOUNT = 0x2, // just count total amount of skill points used by player, do not really reset + PCRESETSKILL_CHSEX = 0x4, // just reset the skills if the player class is a bard/dancer type (for changesex.) +}; + struct weapon_data { int atkmods[3]; BEGIN_ZEROED_BLOCK; // all the variables within this block get zero'ed in each call of status_calc_pc @@ -144,7 +159,7 @@ struct map_session_data { unsigned int arrow_atk : 1; unsigned int gangsterparadise : 1; unsigned int rest : 1; - unsigned int storage_flag : 2; //0: closed, 1: Normal Storage open, 2: guild storage open [Skotlex] + unsigned int storage_flag : 2; // @see enum storage_flag unsigned int snovice_dead_flag : 1; //Explosion spirits on death: 0 off, 1 used. unsigned int abra_flag : 2; // Abracadabra bugfix by Aru unsigned int autocast : 1; // Autospell flag [Inkfish] @@ -377,7 +392,7 @@ END_ZEROED_BLOCK; unsigned char mission_count; //Stores the bounty kill count for TK_MISSION short mission_mobid; //Stores the target mob_id for TK_MISSION int die_counter; //Total number of times you've died - int devotion[5]; //Stores the account IDs of chars devoted to. + int devotion[MAX_PC_DEVOTION]; //Stores the account IDs of chars devoted to. int trade_partner; struct { struct { @@ -409,11 +424,11 @@ END_ZEROED_BLOCK; struct mercenary_data *md; struct elemental_data *ed; - struct{ + struct { int m; //-1 - none, other: map index corresponding to map name. unsigned short index; //map index - } feel_map[3];// 0 - Sun; 1 - Moon; 2 - Stars - short hate_mob[3]; + } feel_map[MAX_PC_FEELHATE];// 0 - Sun; 1 - Moon; 2 - Stars + short hate_mob[MAX_PC_FEELHATE]; int pvp_timer; short pvp_point; @@ -727,6 +742,16 @@ enum e_pc_autotrade_update_action { }; /** + * Flag values for pc->skill + */ +enum pc_skill_flag { + SKILL_GRANT_PERMANENT = 0, // Grant permanent skill to be bound to skill tree + SKILL_GRANT_TEMPORARY = 1, // Grant an item skill (temporary) + SKILL_GRANT_TEMPSTACK = 2, // Like 1, except the level granted can stack with previously learned level. + SKILL_GRANT_UNCONDITIONAL = 3, // Grant skill unconditionally and forever (persistent to job changes and skill resets) +}; + +/** * Used to temporarily remember vending data **/ struct autotrade_vending { @@ -957,6 +982,7 @@ END_ZEROED_BLOCK; /* End */ int (*addspiritball) (struct map_session_data *sd,int interval,int max); int (*delspiritball) (struct map_session_data *sd,int count,int type); + int (*getmaxspiritball) (struct map_session_data *sd, int min); void (*addfame) (struct map_session_data *sd,int count); unsigned char (*famerank) (int char_id, int job); int (*set_hate_mob) (struct map_session_data *sd, int pos, struct block_list *bl); diff --git a/src/map/pet.c b/src/map/pet.c index 52a8017b4..8160f88b0 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -91,7 +91,7 @@ int pet_unlocktarget(struct pet_data *pd) pd->target_id=0; pet_stop_attack(pd); - pet_stop_walking(pd,1); + pet_stop_walking(pd, STOPWALKING_FLAG_FIXPOS); return 0; } @@ -280,7 +280,7 @@ int pet_performance(struct map_session_data *sd, struct pet_data *pd) else val = 1; - pet_stop_walking(pd,2000<<8); + pet_stop_walking(pd,STOPWALKING_FLAG_NONE | (2000<<8)); // Stop walking for 2000ms clif->send_petdata(NULL, pd, 4, rnd()%val + 1); pet->lootitem_drop(pd,NULL); return 1; @@ -445,7 +445,7 @@ int pet_recv_petdata(int account_id,struct s_pet *p,int flag) { return 1; } if (!pet->birth_process(sd,p)) //Pet hatched. Delete egg. - pc->delitem(sd,i,1,0,0,LOG_TYPE_OTHER); + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); } else { pet->data_init(sd,p); if(sd->pd && sd->bl.prev != NULL) { @@ -678,7 +678,7 @@ int pet_equipitem(struct map_session_data *sd,int index) { return 1; } - pc->delitem(sd,index,1,0,0,LOG_TYPE_OTHER); + pc->delitem(sd, index, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); pd->pet.equip = nameid; status->set_viewdata(&pd->bl, pd->pet.class_); //Updates view_data. clif->send_petdata(NULL, sd->pd, 3, sd->pd->vd.head_bottom); @@ -743,7 +743,7 @@ int pet_food(struct map_session_data *sd, struct pet_data *pd) { clif->pet_food(sd, food_id, 0); return 1; } - pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME); + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); if (pd->pet.hungry > 90) { pet->set_intimate(pd, pd->pet.intimate - pd->petDB->r_full); @@ -1144,7 +1144,7 @@ int pet_skill_support_timer(int tid, int64 tick, int id, intptr_t data) { } pet_stop_attack(pd); - pet_stop_walking(pd,1); + pet_stop_walking(pd, STOPWALKING_FLAG_FIXPOS); pd->s_skill->timer=timer->add(tick+pd->s_skill->delay*1000,pet->skill_support_timer,sd->bl.id,0); if (skill->get_inf(pd->s_skill->id) & INF_GROUND_SKILL) unit->skilluse_pos(&pd->bl, sd->bl.x, sd->bl.y, pd->s_skill->id, pd->s_skill->lv); diff --git a/src/map/script.c b/src/map/script.c index 1559a2cfa..724b3b135 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -7444,7 +7444,7 @@ void buildin_delitem_delete(struct map_session_data* sd, int idx, int* amount, b {// delete associated pet intif->delete_petdata(MakeDWord(inv->card[1], inv->card[2])); } - pc->delitem(sd, idx, delamount, 0, 0, LOG_TYPE_SCRIPT); + pc->delitem(sd, idx, delamount, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT); } amount[0]-= delamount; @@ -8492,10 +8492,10 @@ BUILDIN(successrefitem) sd->status.inventory[i].refine += up; sd->status.inventory[i].refine = cap_value( sd->status.inventory[i].refine, 0, MAX_REFINE); - pc->unequipitem(sd,i,2); // status calc will happen in pc->equipitem() below + pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE); // status calc will happen in pc->equipitem() below clif->refine(sd->fd,0,i,sd->status.inventory[i].refine); - clif->delitem(sd,i,1,3); + clif->delitem(sd, i, 1, DELITEM_MATERIALCHANGE); //Logs items, got from (N)PC scripts [Lupus] logs->pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i],sd->inventory_data[i]); @@ -8541,10 +8541,10 @@ BUILDIN(failedrefitem) i=pc->checkequip(sd,script->equip[num-1]); if(i >= 0) { sd->status.inventory[i].refine = 0; - pc->unequipitem(sd,i,3); //recalculate bonus + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); //recalculate bonus clif->refine(sd->fd,1,i,sd->status.inventory[i].refine); //notify client of failure - pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); + pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT); clif->misceffect(&sd->bl,2); // display failure effect } @@ -8575,12 +8575,12 @@ BUILDIN(downrefitem) //Logs items, got from (N)PC scripts [Lupus] logs->pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i],sd->inventory_data[i]); - pc->unequipitem(sd,i,2); // status calc will happen in pc->equipitem() below + pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE); // status calc will happen in pc->equipitem() below sd->status.inventory[i].refine -= down; sd->status.inventory[i].refine = cap_value( sd->status.inventory[i].refine, 0, MAX_REFINE); clif->refine(sd->fd,2,i,sd->status.inventory[i].refine); - clif->delitem(sd,i,1,3); + clif->delitem(sd, i, 1, DELITEM_MATERIALCHANGE); //Logs items, got from (N)PC scripts [Lupus] logs->pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i],sd->inventory_data[i]); @@ -8609,8 +8609,8 @@ BUILDIN(delequip) if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); if(i >= 0) { - pc->unequipitem(sd,i,3); //recalculate bonus - pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); //recalculate bonus + pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT); return true; } @@ -8866,7 +8866,7 @@ BUILDIN(autobonus3) { BUILDIN(skill) { int id; int level; - int flag = 1; + int flag = SKILL_GRANT_TEMPORARY; TBL_PC* sd; sd = script->rid2sd(st); @@ -8894,7 +8894,7 @@ BUILDIN(skill) { BUILDIN(addtoskill) { int id; int level; - int flag = 2; + int flag = SKILL_GRANT_TEMPSTACK; TBL_PC* sd; sd = script->rid2sd(st); @@ -9739,8 +9739,7 @@ BUILDIN(monster) if (script_hasdata(st, 10)) { ai = script_getnum(st, 10); - if (ai > 4) - { + if (ai > AI_FLORA) { ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_); return false; } @@ -9844,7 +9843,7 @@ BUILDIN(areamonster) { if (script_hasdata(st, 12)) { ai = script_getnum(st, 12); - if (ai > 4) { + if (ai > AI_FLORA) { ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_); return false; } @@ -11014,7 +11013,7 @@ BUILDIN(homunculus_mutate) if (m_class == HT_EVO && m_id == HT_S && sd->hd->homunculus.level >= 99 && i != INDEX_NOT_FOUND && - !pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_SCRIPT) ) { + !pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT) ) { sd->hd->homunculus.vaporize = HOM_ST_REST; // Remove morph state. homun->call(sd); // Respawn homunculus. homun->mutate(sd->hd, homun_id); @@ -11195,26 +11194,24 @@ BUILDIN(resetstatus) /*========================================== * script command resetskill *------------------------------------------*/ -BUILDIN(resetskill) -{ +BUILDIN(resetskill) { TBL_PC *sd; sd=script->rid2sd(st); if( sd == NULL ) return false; - pc->resetskill(sd,1); + pc->resetskill(sd, PCRESETSKILL_RESYNC); return true; } /*========================================== * Counts total amount of skill points. *------------------------------------------*/ -BUILDIN(skillpointcount) -{ +BUILDIN(skillpointcount) { TBL_PC *sd; sd=script->rid2sd(st); if( sd == NULL ) return false; - script_pushint(st,sd->status.skill_point + pc->resetskill(sd,2)); + script_pushint(st,sd->status.skill_point + pc->resetskill(sd, PCRESETSKILL_RECOUNT)); return true; } @@ -11256,10 +11253,10 @@ static TBL_PC *prepareChangeSex(struct script_state* st) if (sd == NULL) return NULL; - pc->resetskill(sd, 4); + pc->resetskill(sd, PCRESETSKILL_CHSEX); // to avoid any problem with equipment and invalid sex, equipment is unequiped. for (i=0; i<EQI_MAX; i++) - if (sd->equip_index[i] >= 0) pc->unequipitem(sd, sd->equip_index[i], 3); + if (sd->equip_index[i] >= 0) pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); return sd; } @@ -12312,7 +12309,7 @@ BUILDIN(successremovecards) for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++) item_tmp.card[j]=sd->status.inventory[i].card[j]; - pc->delitem(sd,i,1,0,3,LOG_TYPE_SCRIPT); + pc->delitem(sd, i, 1, 0, DELITEM_MATERIALCHANGE, LOG_TYPE_SCRIPT); if ((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) { //chk if can be spawn in inventory otherwise put on floor clif->additem(sd,0,0,flag); @@ -12374,7 +12371,7 @@ BUILDIN(failedremovecards) if (cardflag == 1) { if (typefail == 0 || typefail == 2) { // destroy the item - pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); + pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT); } else if (typefail == 1) { // destroy the card int flag, j; @@ -12392,7 +12389,7 @@ BUILDIN(failedremovecards) for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++) item_tmp.card[j]=sd->status.inventory[i].card[j]; - pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); + pc->delitem(sd, i, 1, 0, DELITEM_FAILREFINE, LOG_TYPE_SCRIPT); if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) { clif->additem(sd,0,0,flag); @@ -13086,7 +13083,7 @@ BUILDIN(clearitem) if(sd==NULL) return true; for (i=0; i<MAX_INVENTORY; i++) { if (sd->status.inventory[i].amount) { - pc->delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_SCRIPT); + pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_SCRIPT); } } return true; @@ -13515,7 +13512,7 @@ BUILDIN(nude) if( sd->equip_index[ i ] >= 0 ) { if( !calcflag ) calcflag = 1; - pc->unequipitem( sd , sd->equip_index[ i ] , 2); + pc->unequipitem(sd, sd->equip_index[i], PCUNEQUIPITEM_FORCE); } } @@ -13862,7 +13859,7 @@ BUILDIN(npcstop) { if( nd ) { unit->bl2ud2(&nd->bl); // ensure nd->ud is safe to edit - unit->stop_walking(&nd->bl,1|4); + unit->stop_walking(&nd->bl, STOPWALKING_FLAG_FIXPOS|STOPWALKING_FLAG_NEXTCELL); } return true; @@ -14487,7 +14484,7 @@ BUILDIN(unequip) if (sd != NULL && num >= 1 && num <= ARRAYLENGTH(script->equip)) { int i = pc->checkequip(sd,script->equip[num-1]); if (i >= 0) - pc->unequipitem(sd,i,1|2); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } return true; } @@ -15493,6 +15490,14 @@ BUILDIN(compare) return true; } +BUILDIN(strcmp) +{ + const char *str1 = script_getstr(st,2); + const char *str2 = script_getstr(st,3); + script_pushint(st,strcmp(str1, str2)); + return true; +} + // List of mathematics commands ---> BUILDIN(log10) @@ -16469,7 +16474,7 @@ BUILDIN(unitstop) { if( bl != NULL ) { unit->bl2ud2(bl); // ensure ((TBL_NPC*)bl)->ud is safe to edit unit->stop_attack(bl); - unit->stop_walking(bl,4); + unit->stop_walking(bl, STOPWALKING_FLAG_NEXTCELL); if( bl->type == BL_MOB ) ((TBL_MOB*)bl)->target_id = 0; } @@ -17395,7 +17400,7 @@ BUILDIN(bg_monster_set_team) { md->bg_id = bg_id; mob_stop_attack(md); - mob_stop_walking(md, 0); + mob_stop_walking(md, STOPWALKING_FLAG_NONE); md->target_id = md->attacked_id = 0; clif->charnameack(0, &md->bl); @@ -20079,6 +20084,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(countstr,"ss?"), BUILDIN_DEF(setnpcdisplay,"sv??"), BUILDIN_DEF(compare,"ss"), // Lordalfa - To bring strstr to scripting Engine. + BUILDIN_DEF(strcmp,"ss"), BUILDIN_DEF(getiteminfo,"ii"), //[Lupus] returns Items Buy / sell Price, etc info BUILDIN_DEF(setiteminfo,"iii"), //[Lupus] set Items Buy / sell Price, etc info BUILDIN_DEF(getequipcardid,"ii"), //[Lupus] returns CARD ID or other info from CARD slot N of equipped item diff --git a/src/map/skill.c b/src/map/skill.c index 58dbe2472..b39ea380f 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -99,7 +99,7 @@ int skill_get_index( uint16 skill_id ) { skill_id = MC_SKILLRANGEMIN + skill_id - MC_SKILLBASE; else if( skill_id >= HM_SKILLBASE ) skill_id = HM_SKILLRANGEMIN + skill_id - HM_SKILLBASE; - //[Ind/Hercules] GO GO GO LESS! - http://hercules.ws/board/topic/512-skill-id-processing-overhaul/ + //[Ind/Hercules] GO GO GO LESS! - http://herc.ws/board/topic/512-skill-id-processing-overhaul/ else if( skill_id > 1019 && skill_id < 8001 ) { if( skill_id < 2058 ) // 1020 - 2000 are empty skill_id = 1020 + skill_id - 2001; @@ -1367,7 +1367,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 break; } - if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai) { + if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai != AI_NONE) { //Pass heritage to Master for status causing effects. [Skotlex] sd = map->id2sd(md->master_id); src = sd?&sd->bl:src; @@ -2013,7 +2013,7 @@ int skill_break_equip (struct block_list *bl, unsigned short where, int rate, in } if (flag) { sd->status.inventory[j].attribute = 1; - pc->unequipitem(sd, j, 3); + pc->unequipitem(sd, j, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } } clif->equiplist(sd); @@ -2232,7 +2232,8 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr if( dmg.flag&BF_MAGIC && (skill_id != NPC_EARTHQUAKE || (battle_config.eq_single_target_reflectable && (flag & 0xFFF) == 1)) ) { /* Need more info cause NPC_EARTHQUAKE is ground type */ // Earthquake on multiple targets is not counted as a target skill. [Inkfish] - if( (dmg.damage || dmg.damage2) && (type = skill->magic_reflect(src, bl, src==dsrc)) ) { + int reflecttype; + if( (dmg.damage || dmg.damage2) && (reflecttype = skill->magic_reflect(src, bl, src==dsrc)) ) { //Magic reflection, switch caster/target struct block_list *tbl = bl; rmdamage = true; @@ -2249,17 +2250,17 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr /* bugreport:7859 magical reflected zeroes blow count */ dmg.blewcount = 0; //Spirit of Wizard blocks Kaite's reflection - if (type == 2 && sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_WIZARD) { + if (reflecttype == 2 && sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_WIZARD) { //Consume one Fragment per hit of the casted skill? [Skotlex] - type = tsd ? pc->search_inventory(tsd, ITEMID_FRAGMENT_OF_CRYSTAL) : 0; - if (type != INDEX_NOT_FOUND) { - if ( tsd ) pc->delitem(tsd, type, 1, 0, 1, LOG_TYPE_CONSUME); + int consumeitem = tsd ? pc->search_inventory(tsd, ITEMID_FRAGMENT_OF_CRYSTAL) : 0; + if (consumeitem != INDEX_NOT_FOUND) { + if ( tsd ) pc->delitem(tsd, consumeitem, 1, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME); dmg.damage = dmg.damage2 = 0; dmg.dmg_lv = ATK_MISS; sc->data[SC_SOULLINK]->val3 = skill_id; sc->data[SC_SOULLINK]->val4 = dsrc->id; } - } else if( type != 2 ) /* Kaite bypasses */ + } else if( reflecttype != 2 ) /* Kaite bypasses */ additional_effects = false; /** @@ -2272,7 +2273,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr #else // issue:6415 in pre-renewal Kaite reflected the entire damage received // regardless of caster's equipment (Aegis 11.1) - if( dmg.dmg_lv != ATK_MISS && type == 1 ) //Wiz SL canceled and consumed fragment + if( dmg.dmg_lv != ATK_MISS && reflecttype == 1 ) //Wiz SL canceled and consumed fragment #endif { short s_ele = skill->get_ele(skill_id, skill_lv); @@ -2321,12 +2322,12 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr struct block_list *nbl; nbl = battle->get_enemy_area(bl,bl->x,bl->y,2,BL_CHAR,bl->id); if (nbl) { // Only one target is chosen. - clif->skill_damage(bl, nbl, tick, status_get_amotion(src), 0, status_fix_damage(bl,nbl,damage * skill_lv / 10,0), 1, OB_OBOROGENSOU_TRANSITION_ATK, -1, 6); + clif->skill_damage(bl, nbl, tick, status_get_amotion(src), 0, status_fix_damage(bl,nbl,damage * skill_lv / 10,0), 1, OB_OBOROGENSOU_TRANSITION_ATK, -1, BDT_SKILL); } } //Skill hit type - type=(skill_id==0)?5:skill->get_hit(skill_id); + type=(skill_id==0)?BDT_SPLASH:skill->get_hit(skill_id); if(damage < dmg.div_ //Only skills that knockback even when they miss. [Skotlex] @@ -2335,7 +2336,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr if(skill_id == CR_GRANDCROSS||skill_id == NPC_GRANDDARKNESS) { if(battle_config.gx_disptype) dsrc = src; - if(src == bl) type = 4; + if(src == bl) type = BDT_ENDURE; else flag|=SD_ANIMATION; } if(skill_id == NJ_TATAMIGAESHI) { @@ -2441,7 +2442,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr //Display damage. switch( skill_id ) { case PA_GOSPEL: //Should look like Holy Cross [Skotlex] - dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, 5); + dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion, damage, dmg.div_, CR_HOLYCROSS, -1, BDT_SPLASH); break; //Skills that need be passed as a normal attack for the client to display correctly. case HVAN_EXPLOSION: @@ -2459,13 +2460,13 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr case AS_SPLASHER: if( flag&SD_ANIMATION ) // the surrounding targets - dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, 5); // needs -1 as skill level + dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, BDT_SPLASH); // needs -1 as skill level else // the central target doesn't display an animation - dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -2, 5); // needs -2(!) as skill level + dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -2, BDT_SPLASH); // needs -2(!) as skill level break; case WL_HELLINFERNO: case SR_EARTHSHAKER: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,-2,6); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,-2,BDT_SKILL); break; case KO_MUCHANAGE: if( dmg.dmg_lv == ATK_FLEE ) @@ -2473,17 +2474,17 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr case WL_SOULEXPANSION: case WL_COMET: case NJ_HUUMA: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,skill_lv,8); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,skill_lv,BDT_MULTIHIT); break; case WL_CHAINLIGHTNING_ATK: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,WL_CHAINLIGHTNING,-2,6); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,WL_CHAINLIGHTNING,-2,BDT_SKILL); break; case LG_OVERBRAND_BRANDISH: case LG_OVERBRAND: /* Fall through */ dmg.amotion = status_get_amotion(src) * 2; case LG_OVERBRAND_PLUSATK: - dmg.dmotion = clif->skill_damage(dsrc,bl,tick,status_get_amotion(src),dmg.dmotion,damage,dmg.div_,skill_id,-1,5); + dmg.dmotion = clif->skill_damage(dsrc,bl,tick,status_get_amotion(src),dmg.dmotion,damage,dmg.div_,skill_id,-1,BDT_SPLASH); break; case EL_FIRE_BOMB: case EL_FIRE_BOMB_ATK: @@ -2506,29 +2507,29 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr case GN_CRAZYWEED_ATK: case KO_BAKURETSU: case NC_MAGMA_ERUPTION: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,5); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,BDT_SPLASH); break; case GN_SLINGITEM_RANGEMELEEATK: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,GN_SLINGITEM,-2,6); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,GN_SLINGITEM,-2,BDT_SKILL); break; case SC_FEINTBOMB: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,skill_lv,5); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,skill_lv,BDT_SPLASH); break; case EL_STONE_RAIN: - dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,(flag&1)?8:5); + dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,(flag&1)?BDT_MULTIHIT:BDT_SPLASH); break; case WM_SEVERE_RAINSTORM_MELEE: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,-2,6); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,-2,BDT_SPLASH); break; case WM_REVERBERATION_MELEE: case WM_REVERBERATION_MAGIC: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_REVERBERATION,-2,6); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_REVERBERATION,-2,BDT_SKILL); break; case WL_TETRAVORTEX_FIRE: case WL_TETRAVORTEX_WATER: case WL_TETRAVORTEX_WIND: case WL_TETRAVORTEX_GROUND: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_, WL_TETRAVORTEX,-1,5); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_, WL_TETRAVORTEX,-1,BDT_SPLASH); break; case HT_CLAYMORETRAP: case HT_BLASTMINE: @@ -2537,17 +2538,17 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr case RA_CLUSTERBOMB: case RA_FIRINGTRAP: case RA_ICEBOUNDTRAP: - dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, (flag&SD_LEVEL) ? -1 : skill_lv, 5); + dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, (flag&SD_LEVEL) ? -1 : skill_lv, BDT_SPLASH); if( dsrc != src ) // avoid damage display redundancy break; case HT_LANDMINE: dmg.dmotion = clif->skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, type); break; case HW_GRAVITATION: - dmg.dmotion = clif->damage(bl, bl, 0, 0, damage, 1, 4, 0); + dmg.dmotion = clif->damage(bl, bl, 0, 0, damage, 1, BDT_ENDURE, 0); break; case WZ_SIGHTBLASTER: - dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, (flag&SD_LEVEL) ? -1 : skill_lv, 5); + dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, (flag&SD_LEVEL) ? -1 : skill_lv, BDT_SPLASH); break; case AB_DUPLELIGHT_MELEE: case AB_DUPLELIGHT_MAGIC: @@ -2629,6 +2630,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr tsd->status.skill[cidx].flag = SKILL_FLAG_PLAGIARIZED; clif->addskill(tsd,copy_skill); } else { + int plagiarismlvl; lv = skill_lv; if ( tsd->cloneskill_id ) { idx = skill->get_index(tsd->cloneskill_id); @@ -2640,8 +2642,8 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr } } - if ((type = pc->checkskill(tsd,RG_PLAGIARISM)) < lv) - lv = type; + if ((plagiarismlvl = pc->checkskill(tsd,RG_PLAGIARISM)) < lv) + lv = plagiarismlvl; tsd->cloneskill_id = copy_skill; pc_setglobalreg(tsd, script->add_str("CLONE_SKILL"), copy_skill); @@ -2757,12 +2759,12 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr ) && check_distance_bl(bl, d_bl, sce->val3) ) { if(!rmdamage){ - clif->damage(d_bl,d_bl, 0, 0, damage, 0, 0, 0); + clif->damage(d_bl,d_bl, 0, 0, damage, 0, BDT_NORMAL, 0); status_fix_damage(NULL,d_bl, damage, 0); } else{ //Reflected magics are done directly on the target not on paladin //This check is only for magical skill. //For BF_WEAPON skills types track var rdamage and function battle_calc_return_damage - clif->damage(bl,bl, 0, 0, damage, 0, 0, 0); + clif->damage(bl,bl, 0, 0, damage, 0, BDT_NORMAL, 0); status_fix_damage(bl,bl, damage, 0); } } @@ -2856,11 +2858,11 @@ void skill_attack_combo2_unknown(int *attack_type, struct block_list* src, struc void skill_attack_display_unknown(int *attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag, int *type, struct Damage *dmg, int64 *damage) { if (*flag & SD_ANIMATION && dmg->div_ < 2) //Disabling skill animation doesn't works on multi-hit. - *type = 5; + *type = BDT_SPLASH; if (bl->type == BL_SKILL ) { TBL_SKILL *su = (TBL_SKILL*)bl; if (su->group && skill->get_inf2(su->group->skill_id) & INF2_TRAP) // show damage on trap targets - clif->skill_damage(src, bl, *tick, dmg->amotion, dmg->dmotion, *damage, dmg->div_, *skill_id, (*flag & SD_LEVEL) ? -1 : *skill_lv, 5); + clif->skill_damage(src, bl, *tick, dmg->amotion, dmg->dmotion, *damage, dmg->div_, *skill_id, (*flag & SD_LEVEL) ? -1 : *skill_lv, BDT_SPLASH); } dmg->dmotion = clif->skill_damage(dsrc, bl, *tick, dmg->amotion, dmg->dmotion, *damage, dmg->div_, *skill_id, (*flag & SD_LEVEL) ? -1 : *skill_lv, *type); } @@ -2909,7 +2911,7 @@ int skill_area_sub(struct block_list *bl, va_list ap) { if(battle->check_target(src,bl,flag) > 0) { // several splash skills need this initial dummy packet to display correctly if (flag&SD_PREAMBLE && skill->area_temp[2] == 0) - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if (flag&(SD_SPLASH|SD_PREAMBLE)) skill->area_temp[2]++; @@ -3154,7 +3156,7 @@ int skill_check_condition_mercenary(struct block_list *bl, int skill_id, int lv, // Consume items for (i = 0; i < ARRAYLENGTH(itemid); i++) { if (index[i] != INDEX_NOT_FOUND) - pc->delitem(sd, index[i], amount[i], 0, 1, LOG_TYPE_CONSUME); + pc->delitem(sd, index[i], amount[i], 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME); } if( type&2 ) @@ -3334,7 +3336,7 @@ int skill_timerskill(int tid, int64 tick, int id, intptr_t data) { break; case SC_ESCAPE: if( skl->type < 4+skl->skill_lv ){ - clif->skill_damage(src,src,tick,0,0,-30000,1,skl->skill_id,skl->skill_lv,5); + clif->skill_damage(src,src,tick,0,0,-30000,1,skl->skill_id,skl->skill_lv,BDT_SPLASH); skill->blown(src,src,1,unit->getdir(src),0); skill->addtimerskill(src,tick+80,src->id,0,0,skl->skill_id,skl->skill_lv,skl->type+1,0); } @@ -3833,9 +3835,16 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 if( dir > 2 && dir < 6 ) y = -i; else if( dir == 7 || dir < 2 ) y = i; else y = 0; - if( (mbl == src || (!map_flag_gvg2(src->m) && !map->list[src->m].flag.battleground) ) // only NJ_ISSEN don't have slide effect in GVG - && unit->movepos(src, mbl->x+x, mbl->y+y, 1, 1) - ) { + if ((mbl == src || (!map_flag_gvg2(src->m) && !map->list[src->m].flag.battleground))) { // only NJ_ISSEN don't have slide effect in GVG + if (!(unit->movepos(src, mbl->x+x, mbl->y+y, 1, 1))) { + // The cell is not reachable (wall, object, ...), move next to the target + if (x > 0) x = -1; + else if (x < 0) x = 1; + if (y > 0) y = -1; + else if (y < 0) y = 1; + + unit->movepos(src, bl->x+x, bl->y+y, 1, 1); + } clif->slide(src, src->x, src->y); clif->fixpos(src); clif->spiritball(src); @@ -3933,7 +3942,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 /* Fall through */ case LG_MOONSLASHER: case MH_XENO_SLASHER: - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); break; default: break; @@ -4088,7 +4097,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 break; case CH_PALMSTRIKE: // Palm Strike takes effect 1sec after casting. [Skotlex] //clif->skill_nodamage(src,bl,skill_id,skill_lv,0); //Can't make this one display the correct attack animation delay :/ - clif->damage(src,bl,status_get_amotion(src),0,-1,1,4,0); //Display an absorbed damage attack. + clif->damage(src,bl,status_get_amotion(src),0,-1,1,BDT_ENDURE,0); //Display an absorbed damage attack. skill->addtimerskill(src, tick + (1000+status_get_amotion(src)), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag); break; @@ -4542,7 +4551,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); // Need confirm it. } else { map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id); - clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if( sd ) pc->overheat(sd,1); } break; @@ -4561,7 +4570,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 skill->area_temp[5] = y; map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_damage_id); skill->addtimerskill(src,tick + 800,src->id,x,y,skill_id,skill_lv,0,flag); // To teleport Self - clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6); + clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,BDT_SKILL); } break; case LG_PINPOINTATTACK: @@ -4619,7 +4628,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); } else{ map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id); - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); } break; @@ -4686,7 +4695,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 else { int i = skill->get_splash(skill_id,skill_lv); clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1); - clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if( rnd()%100 < 30 ) map->foreachinrange(skill->area_sub,bl,i,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); else @@ -4696,7 +4705,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 case EL_ROCK_CRUSHER: clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1); - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if( rnd()%100 < 50 ) skill->attack(BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag); else @@ -4709,7 +4718,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 else { int i = skill->get_splash(skill_id,skill_lv); clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1); - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if( rnd()%100 < 30 ) map->foreachinrange(skill->area_sub,bl,i,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); else @@ -4722,7 +4731,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 case EL_WIND_SLASH: case EL_STONE_HAMMER: clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1); - clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); skill->attack(skill->get_type(skill_id),src,src,bl,skill_id,skill_lv,tick,flag); break; @@ -4735,7 +4744,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1 type2 = type-1; clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1); - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if( (esc && esc->data[type2]) || (tsc && tsc->data[type]) ) { elemental->clean_single_effect(ele, skill_id); } @@ -5038,7 +5047,7 @@ int skill_castend_id(int tid, int64 tick, int id, intptr_t data) { } if (ud->walktimer != INVALID_TIMER && ud->skill_id != TK_RUN && ud->skill_id != RA_WUGDASH) - unit->stop_walking(src,1); + unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS); if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) ) ud->canact_tick = tick + skill->delay_fix(src, ud->skill_id, ud->skill_lv); // Tests show wings don't overwrite the delay but skill scrolls do. [Inkfish] @@ -6098,7 +6107,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin } i = 0; - count = (sd)? min(skill_lv,5) : 1; // Mercenary only can Devote owner + count = (sd)? min(skill_lv,MAX_PC_DEVOTION) : 1; // Mercenary only can Devote owner if( sd ) { // Player Devoting Player ARR_FIND(0, count, i, sd->devotion[i] == bl->id ); @@ -6126,22 +6135,17 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case MO_CALLSPIRITS: if(sd) { - int limit = skill_lv; - if( sd->sc.data[SC_RAISINGDRAGON] ) - limit += sd->sc.data[SC_RAISINGDRAGON]->val1; clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - pc->addspiritball(sd,skill->get_time(skill_id,skill_lv),limit); + pc->addspiritball(sd, skill->get_time(skill_id, skill_lv), pc->getmaxspiritball(sd, 0)); } break; case CH_SOULCOLLECT: if(sd) { - int limit = 5, i; - if( sd->sc.data[SC_RAISINGDRAGON] ) - limit += sd->sc.data[SC_RAISINGDRAGON]->val1; + int i, limit = pc->getmaxspiritball(sd, 5); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - for (i = 0; i < limit; i++) - pc->addspiritball(sd,skill->get_time(skill_id,skill_lv),limit); + for ( i = 0; i < limit; i++ ) + pc->addspiritball(sd, skill->get_time(skill_id, skill_lv), limit); } break; @@ -6233,7 +6237,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin count = map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id); if( !count && ( skill_id == NC_AXETORNADO || skill_id == SR_SKYNETBLOW || skill_id == KO_HAPPOKUNAI ) ) - clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); } break; @@ -6285,7 +6289,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin { //Self Destruction hits everyone in range (allies+enemies) //Except for Summoned Marine spheres on non-versus maps, where it's just enemy. - int targetmask = ((!md || md->special_state.ai == 2) && !map_flag_vs(src->m))? + int targetmask = ((!md || md->special_state.ai == AI_SPHERE) && !map_flag_vs(src->m))? BCT_ENEMY:BCT_ALL; clif->skill_nodamage(src, src, skill_id, -1, 1); map->delblock(src); //Required to prevent chain-self-destructions hitting back. @@ -7710,7 +7714,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case 3: // 1000 damage, random armor destroyed { status_fix_damage(src, bl, 1000, 0); - clif->damage(src,bl,0,0,1000,0,0,0); + 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); @@ -7747,14 +7751,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin break; case 10: // 6666 damage, atk matk halved, cursed status_fix_damage(src, bl, 6666, 0); - clif->damage(src,bl,0,0,6666,0,0,0); + clif->damage(src,bl,0,0,6666,0,BDT_NORMAL,0); sc_start(src,bl,SC_INCATKRATE,100,-50,skill->get_time2(skill_id,skill_lv)); sc_start(src,bl,SC_INCMATKRATE,100,-50,skill->get_time2(skill_id,skill_lv)); sc_start(src,bl,SC_CURSE,skill_lv,100,skill->get_time2(skill_id,skill_lv)); break; case 11: // 4444 damage status_fix_damage(src, bl, 4444, 0); - clif->damage(src,bl,0,0,4444,0,0,0); + clif->damage(src,bl,0,0,4444,0,BDT_NORMAL,0); break; case 12: // stun sc_start(src,bl,SC_STUN,100,skill_lv,5000); @@ -8132,7 +8136,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case LG_EARTHDRIVE: { int splash; - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); splash = skill->get_splash(skill_id,skill_lv); if( skill_id == LG_EARTHDRIVE ) { int dummy = 1; @@ -8313,7 +8317,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case GC_PHANTOMMENACE: { int r; - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); r = skill->get_splash(skill_id, skill_lv); map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR, @@ -8609,7 +8613,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin * Ranger **/ case RA_FEARBREEZE: - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); break; @@ -8650,7 +8654,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case RA_SENSITIVEKEEN: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR|BL_SKILL,src,skill_id,skill_lv,tick,flag|BCT_ENEMY,skill->castend_damage_id); break; /** @@ -8677,7 +8681,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin break; case NC_ANALYZE: - clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src,bl,type, 30 + 12 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv))); if( sd ) pc->overheat(sd,1); @@ -8689,7 +8693,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin if( (failure = sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv))) ) { map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),splash_target(src),src,skill_id,skill_lv,tick,flag|BCT_ENEMY|SD_SPLASH|1,skill->castend_damage_id);; - clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6); + clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,BDT_SKILL); if (sd) pc->overheat(sd,1); } clif->skill_nodamage(src,src,skill_id,skill_lv,failure); @@ -8809,7 +8813,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin break; case LG_TRAMPLE: - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); map->foreachinrange(skill->destroy_trap,bl,skill->get_splash(skill_id,skill_lv),BL_SKILL,tick); break; @@ -8847,7 +8851,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin switch( opt ) { case 1: sc_start(src,bl,SC_SHIELDSPELL_DEF,100,opt,INVALID_TIMER); //Splash AoE ATK - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); status_change_end(bl,SC_SHIELDSPELL_DEF,INVALID_TIMER); break; @@ -8874,13 +8878,13 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin switch( opt ) { case 1: sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,INVALID_TIMER); //Splash AoE MATK - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); status_change_end(bl,SC_SHIELDSPELL_MDEF,INVALID_TIMER); break; case 2: sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,sd->bonus.shieldmdef * 2000); //Splash AoE Lex Divina - clif->skill_damage(src,bl,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_nodamage_id); break; case 3: @@ -8993,7 +8997,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin } } else { int count = 0; - clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); count = map->forcountinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv), (sd)?sd->spiritball_old:15, // Assume 15 spiritballs in non-characters BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id); if( sd ) pc->delspiritball(sd, count, 0); @@ -9003,13 +9007,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin break; case SR_RAISINGDRAGON: - if( sd ) { - short max = 5 + skill_lv; - int i; + if ( sd ) { + int i, max; sc_start(src, bl, SC_EXPLOSIONSPIRITS, 100, skill_lv, skill->get_time(skill_id, skill_lv)); - for( i = 0; i < max; i++ ) // Don't call more than max available spheres. - pc->addspiritball(sd, skill->get_time(skill_id, skill_lv), max); - clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv))); + clif->skill_nodamage(src, bl, skill_id, skill_lv, + sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); + max = pc->getmaxspiritball(sd, 0); + for ( i = 0; i < max; i++ ) + pc->addspiritball(sd, skill->get_time(MO_CALLSPIRITS, skill_lv), max); } break; @@ -9027,7 +9032,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin } clif->skill_nodamage(src, bl, skill_id, skill_lv, sp ? 1:0); } else { - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|BCT_SELF|SD_SPLASH|1, skill->castend_nodamage_id); } break; @@ -9035,12 +9040,12 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case SR_POWERVELOCITY: if( !dstsd ) break; - if( sd && dstsd->spiritball <= 5 ) { - int i; - for(i = 0; i <= 5; i++) { - pc->addspiritball(dstsd, skill->get_time(MO_CALLSPIRITS, pc->checkskill(sd,MO_CALLSPIRITS)), i); - pc->delspiritball(sd, sd->spiritball, 0); + if ( sd && (dstsd->class_&MAPID_BASEMASK) != MAPID_GUNSLINGER ) { + int i, max = pc->getmaxspiritball(dstsd, 5); + for ( i = 0; i < max; i++ ) { + pc->addspiritball(dstsd, skill->get_time(MO_CALLSPIRITS, 1), max); } + pc->delspiritball(sd, sd->spiritball, 0); } clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); break; @@ -9196,7 +9201,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin madnesscheck = map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill->area_sub_count); sc_start(src, bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv)); if ( madnesscheck >= 8 )//The god of madness deals 9999 fixed unreduceable damage when 8 or more enemy players are affected. - status_fix_damage(src, bl, 9999, clif->damage(src, bl, 0, 0, 9999, 0, 0, 0)); + status_fix_damage(src, bl, 9999, clif->damage(src, bl, 0, 0, 9999, 0, BDT_NORMAL, 0)); //skill->attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);//To renable when I can confirm it deals damage like this. Data shows its dealt as reflected damage which I don't have it coded like that yet. [Rytech] } else if( sd ) { int rate = sstatus->int_ / 6 + (sd? sd->status.job_level:0) / 5 + skill_lv * 4; @@ -9332,7 +9337,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin break; } clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, 0, 1, skill_id, -2, 6); + clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, 0, 1, skill_id, -2, BDT_SKILL); break; case GM_SANDMAN: @@ -9557,7 +9562,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin elemental->clean_single_effect(ele, skill_id); } else { clif->skill_nodamage(src,src,skill_id,skill_lv,1); - clif->skill_damage(src, ( skill_id == EL_GUST || skill_id == EL_BLAST || skill_id == EL_WILD_STORM )?src:bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, ( skill_id == EL_GUST || skill_id == EL_BLAST || skill_id == EL_WILD_STORM )?src:bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); if( skill_id == EL_WIND_STEP ) // There aren't teleport, just push the master away. skill->blown(src,bl,(rnd()%skill->get_blewcount(skill_id,skill_lv))+1,rnd()%8,0); sc_start(src, src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv)); @@ -9572,7 +9577,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case EL_ZEPHYR: case EL_POWER_OF_GAIA: clif->skill_nodamage(src,src,skill_id,skill_lv,1); - clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); skill->unitsetting(src,skill_id,skill_lv,bl->x,bl->y,0); break; @@ -9588,7 +9593,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin elemental->clean_single_effect(ele, skill_id); } else { // This not heals at the end. - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); sc_start(src, src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv)); sc_start(src, bl,type,100,src->id,skill->get_time(skill_id,skill_lv)); } @@ -9665,8 +9670,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin clif->skill_nodamage(src, src, skill_id, skill_lv, 1); clif->slide(src, bl->x, bl->y) ; sc_start(src, src, SC_CONFUSION, 25, skill_lv, skill->get_time(skill_id, skill_lv)); - if ( !is_boss(bl) && unit->stop_walking(&sd->bl, 1) && unit->movepos(bl, x, y, 0, 0) ) - { + if ( !is_boss(bl) && unit->stop_walking(&sd->bl, STOPWALKING_FLAG_FIXPOS) && unit->movepos(bl, x, y, 0, 0) ) { if( dstsd && pc_issit(dstsd) ) pc->setstand(dstsd); clif->slide(bl, x, y) ; @@ -9689,7 +9693,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin case KG_KAGEMUSYA: clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(src, bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); break; case KG_KAGEHUMI: @@ -9708,7 +9712,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin status_change_end(bl, SC_HARMONIZE, INVALID_TIMER); } if( skill->area_temp[2] == 1 ){ - clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); sc_start(src, src, SC_STOP, 100, skill_lv, skill->get_time(skill_id, skill_lv)); } } else { @@ -9962,7 +9966,7 @@ int skill_castend_pos(int tid, int64 tick, int id, intptr_t data) src->type, src->id, ud->skill_id, ud->skill_lv, ud->skillx, ud->skilly); if (ud->walktimer != INVALID_TIMER) - unit->stop_walking(src,1); + unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS); if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) ) ud->canact_tick = tick + skill->delay_fix(src, ud->skill_id, ud->skill_lv); @@ -10658,7 +10662,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui break; case RK_WINDCUTTER: - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); /* Fall through */ case NC_COLDSLOWER: case RK_DRAGONBREATH: @@ -10698,7 +10702,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui clif->skill_fail(sd,skill_id,USESKILL_FAIL_GC_POISONINGWEAPON,0); return 0; } - clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6); + clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,BDT_SKILL); skill->unitsetting(src, skill_id, skill_lv, x, y, flag); //status_change_end(src,SC_POISONINGWEAPON,INVALID_TIMER); // 08/31/2011 - When using poison smoke, you no longer lose the poisoning weapon effect. break; @@ -10735,7 +10739,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case RA_DETONATOR: r = skill->get_splash(skill_id, skill_lv); map->foreachinarea(skill->detonator, src->m, x-r, y-r, x+r, y+r, BL_SKILL, src); - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); break; /** * Mechanic @@ -11071,6 +11075,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ * According to data provided in RE, SW life is equal to 3 times caster's health **/ val2 = status_get_max_hp(src) * 3; + val3 = skill_lv+1; #else val2 = skill_lv+1; #endif @@ -11386,7 +11391,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ } break; case NPC_EARTHQUAKE: - clif->skill_damage(src, src, timer->gettick(), status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + clif->skill_damage(src, src, timer->gettick(), status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL); break; default: skill->unitsetting1_unknown(src, &skill_id, &skill_lv, &x, &y, &flag, &val1, &val2, &val3); @@ -11782,7 +11787,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 struct skill_unit_group *sg; struct block_list *ss; TBL_PC* tsd; - struct status_data *tstatus; + struct status_data *tstatus, *bst; struct status_change *tsc, *ssc; struct skill_unit_group_tickset *ts; enum sc_type type; @@ -11806,6 +11811,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 return 0; tstatus = status->get_status_data(bl); + bst = status->get_base_status(bl); type = status->skill2sc(sg->skill_id); skill_id = sg->skill_id; @@ -12454,7 +12460,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6 if (tsc && (tsc->data[SC_HALLUCINATIONWALK] || tsc->data[SC_VACUUM_EXTREME])) { return 0; } else { - sg->limit -= 100 * tstatus->str/20; + sg->limit -= 1000 * bst->str/20; sc_start(ss, bl, SC_VACUUM_EXTREME, 100, sg->skill_lv, sg->limit); if ( !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground && !is_boss(bl) ) { @@ -12921,7 +12927,8 @@ int skill_check_condition_mob_master_sub (struct block_list *bl, va_list ap) { mob_class=va_arg(ap,int); skill_id=va_arg(ap,int); c=va_arg(ap,int *); - if( md->master_id != src_id || md->special_state.ai != (unsigned)(skill_id == AM_SPHEREMINE?2:skill_id == KO_ZANZOU?4:skill_id == MH_SUMMON_LEGION?1:3) ) + if( md->master_id != src_id + || md->special_state.ai != (skill_id == AM_SPHEREMINE?AI_SPHERE:skill_id == KO_ZANZOU?AI_ZANZOU:skill_id == MH_SUMMON_LEGION?AI_ATTACK:AI_FLORA) ) return 0; //Non alchemist summoned mobs have nothing to do here. if(md->class_==mob_class) (*c)++; @@ -13035,8 +13042,8 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id sd->itemid = sd->itemindex = -1; if( skill_id == WZ_EARTHSPIKE && sc && sc->data[SC_EARTHSCROLL] && rnd()%100 > sc->data[SC_EARTHSCROLL]->val2 ) // [marquis007] ; //Do not consume item. - else if( sd->status.inventory[i].expire_time == 0 ) - pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME); // Rental usable items are not consumed until expiration + else if( sd->status.inventory[i].expire_time == 0 ) // Rental usable items are not consumed until expiration + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); } return 1; } @@ -13641,7 +13648,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id MOBID_EMPERIUM, MOBID_GUARIDAN_STONE1, MOBID_GUARIDAN_STONE2)) { char output[128]; sprintf(output, "You're too close to a stone or emperium to do this skill"); /* TODO official response? or message.conf it */ - clif->colormes(sd->fd, COLOR_RED, output); + clif->messagecolor_self(sd->fd, COLOR_RED, output); return 0; } } @@ -14075,7 +14082,7 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id, skill->get_desc(skill_id), require.ammo_qty, itemdb_jname(sd->status.inventory[i].nameid)); - clif->colormes(sd->fd,COLOR_RED,e_msg); + clif->messagecolor_self(sd->fd, COLOR_RED, e_msg); return 0; } if (!(require.ammo&1<<sd->inventory_data[i]->look)) { //Ammo type check. Send the "wrong weapon type" message @@ -14211,7 +14218,7 @@ int skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, uin } if ((n = pc->search_inventory(sd,req.itemid[i])) != INDEX_NOT_FOUND) - pc->delitem(sd,n,req.amount[i],0,1,LOG_TYPE_CONSUME); + pc->delitem(sd, n, req.amount[i], 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME); } } @@ -15078,7 +15085,7 @@ void skill_repairweapon (struct map_session_data *sd, int idx) { clif->equiplist(target_sd); - pc->delitem(sd,pc->search_inventory(sd,material),1,0,0,LOG_TYPE_CONSUME); + pc->delitem(sd, pc->search_inventory(sd, material), 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); // FIXME: is this the correct reason flag? clif->item_repaireffect(sd,idx,0); @@ -15147,7 +15154,7 @@ void skill_weaponrefine (struct map_session_data *sd, int idx) else per += 5 * ((signed int)sd->status.job_level - 50); - pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER); + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); // FIXME: is this the correct reason flag? if (per > rnd() % 1000) { int ep = 0; logs->pick_pc(sd, LOG_TYPE_OTHER, -1, item, ditem); @@ -15155,9 +15162,9 @@ void skill_weaponrefine (struct map_session_data *sd, int idx) logs->pick_pc(sd, LOG_TYPE_OTHER, 1, item, ditem); if(item->equip) { ep = item->equip; - pc->unequipitem(sd,idx,3); + pc->unequipitem(sd, idx, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } - clif->delitem(sd,idx,1,0); + clif->delitem(sd, idx, 1, DELITEM_NORMAL); clif->upgrademessage(sd->fd, 0,item->nameid); clif->inventorylist(sd); clif->refine(sd->fd,0,idx,item->refine); @@ -15183,9 +15190,9 @@ void skill_weaponrefine (struct map_session_data *sd, int idx) } else { item->refine = 0; if(item->equip) - pc->unequipitem(sd,idx,3); + pc->unequipitem(sd, idx, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); clif->refine(sd->fd,1,idx,item->refine); - pc->delitem(sd,idx,1,0,0, LOG_TYPE_OTHER); + pc->delitem(sd, idx, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); clif->misceffect(&sd->bl,2); clif->emotion(&sd->bl, E_OMG); } @@ -15725,7 +15732,7 @@ int skill_trap_splash(struct block_list *bl, va_list ap) { skill->blown(src,bl,skill->get_blewcount(sg->skill_id,sg->skill_lv),-1,0); break; case UNT_ELECTRICSHOCKER: - clif->skill_damage(src,bl,tick,0,0,-30000,1,sg->skill_id,sg->skill_lv,5); + clif->skill_damage(src,bl,tick,0,0,-30000,1,sg->skill_id,sg->skill_lv,BDT_SPLASH); break; case UNT_MAGENTATRAP: case UNT_COBALTTRAP: @@ -15912,7 +15919,7 @@ bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit) return false; } - status->damage(bl, src, damage, 0, clif->damage(src, src, 500, 500, damage, hit, (hit > 1 ? 8 : 0), 0), 0); + status->damage(bl, src, damage, 0, clif->damage(src, src, 500, 500, damage, hit, (hit > 1 ? BDT_MULTIHIT : BDT_NORMAL), 0), 0); /* because damage can cancel it */ if( sc->data[SC__SHADOWFORM] && (--sc->data[SC__SHADOWFORM]->val3) <= 0 ) { @@ -15945,7 +15952,8 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int su->group=group; su->alive=1; su->val1=val1; - su->val2=val2; + su->val2 = val2; + su->prev = 0; idb_put(skill->unit_db, su->bl.id, su); map->addiddb(&su->bl); @@ -16539,7 +16547,7 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) { dissonance = skill->dance_switch(su, 0); - if( su->range >= 0 && group->interval != -1 ) { + if( su->range >= 0 && group->interval != -1 && su->bl.id != su->prev) { if( battle_config.skill_wall_check ) map->foreachinshootrange(skill->unit_timer_sub_onplace, bl, su->range, group->bl_flag, bl,tick); else @@ -16555,6 +16563,8 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) { group->bl_flag= BL_NUL; } } + if ( group->limit == group->interval ) + su->prev = su->bl.id; } if( dissonance ) skill->dance_switch(su, 1); @@ -16886,12 +16896,12 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, if (j == INDEX_NOT_FOUND) continue; if( slot[i]==ITEMID_STAR_CRUMB ) { - pc->delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE); + pc->delitem(sd, j, 1, 1, DELITEM_NORMAL, LOG_TYPE_PRODUCE); // FIXME: is this the correct reason flag? sc++; } if( slot[i] >= ITEMID_FLAME_HEART && slot[i] <= ITEMID_GREAT_NATURE && ele == 0 ) { static const int ele_table[4]={3,1,4,2}; - pc->delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE); + pc->delitem(sd, j, 1, 1, DELITEM_NORMAL, LOG_TYPE_PRODUCE); // FIXME: is this the correct reason flag? ele=ele_table[slot[i]-994]; } } @@ -16937,7 +16947,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, if (j != INDEX_NOT_FOUND) { y = sd->status.inventory[j].amount; if(y>x)y=x; - pc->delitem(sd,j,y,0,0,LOG_TYPE_PRODUCE); + pc->delitem(sd, j, y, 0, DELITEM_NORMAL, LOG_TYPE_PRODUCE); // FIXME: is this the correct reason flag? } else ShowError("skill_produce_mix: material item error\n"); @@ -17472,7 +17482,7 @@ int skill_arrow_create (struct map_session_data *sd, int nameid) if(index < 0 || (j = pc->search_inventory(sd,nameid)) == INDEX_NOT_FOUND) return 1; - pc->delitem(sd,j,1,0,0,LOG_TYPE_PRODUCE); + pc->delitem(sd, j, 1, 0, DELITEM_NORMAL, LOG_TYPE_PRODUCE); // FIXME: is this the correct reason flag? for(i=0;i<MAX_ARROW_RESOURCE;i++) { memset(&tmp_item,0,sizeof(tmp_item)); tmp_item.identify = 1; @@ -17498,7 +17508,7 @@ int skill_poisoningweapon( struct map_session_data *sd, int nameid) { sc_type type; int chance, i; nullpo_ret(sd); - if( nameid <= 0 || (i = pc->search_inventory(sd,nameid)) == INDEX_NOT_FOUND || pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME) ) { + if (nameid <= 0 || (i = pc->search_inventory(sd,nameid)) == INDEX_NOT_FOUND || pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME)) { clif->skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_LEVEL,0); return 0; } @@ -17555,15 +17565,16 @@ int skill_magicdecoy(struct map_session_data *sd, int nameid) { nullpo_ret(sd); skill_id = sd->menuskill_val; - if (nameid <= 0 || !itemdb_is_element(nameid) || (i = pc->search_inventory(sd,nameid)) == INDEX_NOT_FOUND - || !skill_id || pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME) + if (nameid <= 0 || !itemdb_is_element(nameid) || !skill_id + || (i = pc->search_inventory(sd, nameid)) == INDEX_NOT_FOUND + || pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME) != 0 ) { clif->skill_fail(sd,NC_MAGICDECOY,USESKILL_FAIL_LEVEL,0); return 0; } // Spawn Position - pc->delitem(sd,i,1,0,0,LOG_TYPE_CONSUME); + pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_CONSUME); // FIXME: is this intended to be there twice? x = sd->sc.comet_x; y = sd->sc.comet_y; sd->sc.comet_x = sd->sc.comet_y = 0; @@ -17699,7 +17710,7 @@ int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv, return 1; } - if( pc->delitem(sd,idx,del_amount,0,1,LOG_TYPE_CONSUME) ) { + if( pc->delitem(sd, idx, del_amount, 0, DELITEM_SKILLUSE, LOG_TYPE_CONSUME) ) { clif->skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0); return 1; } diff --git a/src/map/skill.h b/src/map/skill.h index c5341e9bd..bbf5b5458 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -1732,6 +1732,7 @@ struct skill_unit { int limit; int val1,val2; short alive,range; + int prev; }; struct skill_unit_group_tickset { diff --git a/src/map/status.c b/src/map/status.c index b0ae7d261..fd75ef81c 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1194,7 +1194,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, if(d_bl &&((d_bl->type == BL_MER && ((TBL_MER *)d_bl)->master && ((TBL_MER *)d_bl)->master->bl.id == target->id) || (d_bl->type == BL_PC && ((TBL_PC *)d_bl)->devotion[sce->val2] == target->id)) && check_distance_bl(target, d_bl, sce->val3)) { - clif->damage(d_bl, d_bl, 0, 0, hp, 0, 0, 0); + clif->damage(d_bl, d_bl, 0, 0, hp, 0, BDT_NORMAL, 0); status_fix_damage(NULL, d_bl, hp, 0); return 0; } @@ -1261,7 +1261,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, } if( src && target->type == BL_PC && (((TBL_PC*)target)->disguise) > 0 ) {// stop walking when attacked in disguise to prevent walk-delay bug - unit->stop_walking( target, 1 ); + unit->stop_walking(target, STOPWALKING_FLAG_FIXPOS); } if (st->hp || (flag&8)) { @@ -1344,7 +1344,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, unit->remove_map(target,CLR_DEAD,ALC_MARK); else { //Some death states that would normally be handled by unit_remove_map unit->stop_attack(target); - unit->stop_walking(target,1); + unit->stop_walking(target, STOPWALKING_FLAG_FIXPOS); unit->skillcastcancel(target,0); clif->clearunit_area(target,CLR_DEAD); skill->unit_move(target,timer->gettick(),4); @@ -1656,10 +1656,15 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin return 0; if (sc->data[SC_DC_WINKCHARM] && target && !flag) { //Prevents skill usage - if( unit->bl2ud(src) && (unit->bl2ud(src))->walktimer == INVALID_TIMER ) - unit->walktobl(src, map->id2bl(sc->data[SC_DC_WINKCHARM]->val2), 3, 1); - clif->emotion(src, E_LV); - return 0; + struct block_list *winkcharm_target = map->id2bl(sc->data[SC_DC_WINKCHARM]->val2); + if (winkcharm_target != NULL) { + if (unit->bl2ud(src) && (unit->bl2ud(src))->walktimer == INVALID_TIMER) + unit->walktobl(src, map->id2bl(sc->data[SC_DC_WINKCHARM]->val2), 3, 1); + clif->emotion(src, E_LV); + return 0; + } else { + status_change_end(src, SC_DC_WINKCHARM, INVALID_TIMER); + } } if (sc->data[SC_BLADESTOP]) { @@ -1874,7 +1879,7 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) { if (battle_config.slaves_inherit_speed && md->master_id) flag|=8; - if (md->master_id && md->special_state.ai>1) + if (md->master_id && md->special_state.ai > AI_ATTACK) flag|=16; if (!flag) @@ -1910,8 +1915,8 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) { //Max HP setting from Summon Flora/marine Sphere struct unit_data *ud = unit->bl2ud(mbl); //Remove special AI when this is used by regular mobs. - if (mbl->type == BL_MOB && !((TBL_MOB*)mbl)->special_state.ai) - md->special_state.ai = 0; + if (mbl->type == BL_MOB && ((TBL_MOB*)mbl)->special_state.ai == AI_NONE) + md->special_state.ai = AI_NONE; if (ud) { // different levels of HP according to skill level if (ud->skill_id == AM_SPHEREMINE) { @@ -2217,7 +2222,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { } bstatus->aspd_rate = 1000; bstatus->ele_lv = 1; - bstatus->race = RC_DEMIHUMAN; + bstatus->race = RC_PLAYER; // Autobonus pc->delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),true); @@ -3027,7 +3032,7 @@ int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt) { nstatus->def_ele = ELE_NEUTRAL; nstatus->ele_lv = 1; - nstatus->race = RC_DEMIHUMAN; + nstatus->race = RC_PLAYER; nstatus->size = nd->size; nstatus->rhw.range = 1 + nstatus->size; nstatus->mode = (MD_CANMOVE|MD_CANATTACK); @@ -3557,7 +3562,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) { if (!(st->mode&MD_CANATTACK)) unit->stop_attack(bl); if (!(st->mode&MD_CANMOVE)) - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); } // No status changes alter these yet. @@ -5960,7 +5965,7 @@ int status_get_party_id(struct block_list *bl) { struct mob_data *md=(TBL_MOB*)bl; if( md->master_id > 0 ) { struct map_session_data *msd; - if (md->special_state.ai && (msd = map->id2sd(md->master_id)) != NULL) + if (md->special_state.ai != AI_NONE && (msd = map->id2sd(md->master_id)) != NULL) return msd->status.party_id; return -md->master_id; } @@ -6003,7 +6008,7 @@ int status_get_guild_id(struct block_list *bl) { // Guardian guild data may not been available yet, castle data is always set return (md->guardian_data->g)?md->guardian_data->g->guild_id:md->guardian_data->castle->guild_id; } - if( md->special_state.ai && (msd = map->id2sd(md->master_id)) != NULL ) + if (md->special_state.ai != AI_NONE && (msd = map->id2sd(md->master_id)) != NULL) return msd->status.guild_id; //Alchemist's mobs [Skotlex] break; } @@ -6045,7 +6050,7 @@ int status_get_emblem_id(struct block_list *bl) { struct mob_data *md = (struct mob_data *)bl; if (md->guardian_data) //Guardian's guild [Skotlex] return (md->guardian_data->g) ? md->guardian_data->g->emblem_id:0; - if (md->special_state.ai && (msd = map->id2sd(md->master_id)) != NULL) + if (md->special_state.ai != AI_NONE && (msd = map->id2sd(md->master_id)) != NULL) return msd->guild_emblem_id; //Alchemist's mobs [Skotlex] } break; @@ -6517,9 +6522,6 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ case SC_COLD: tick_def2 = bst->vit*100 + status->get_lv(bl)*20; break; - case SC_VACUUM_EXTREME: - tick_def2 = bst->str*50; - break; case SC_MANDRAGORA: sc_def = (st->vit + st->luk)*20; break; @@ -6974,7 +6976,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t i = sd->equip_index[EQI_HAND_R]; if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) { opt_flag|=2; - pc->unequipitem(sd,i,3); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } if (!opt_flag) return 0; } @@ -6990,7 +6992,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t i = sd->equip_index[EQI_HAND_L]; if ( i < 0 || !sd->inventory_data[i] || sd->inventory_data[i]->type != IT_ARMOR ) return 0; - pc->unequipitem(sd,i,3); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; @@ -7002,7 +7004,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t i = sd->equip_index[EQI_ARMOR]; if ( i < 0 || !sd->inventory_data[i] ) return 0; - pc->unequipitem(sd,i,3); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; @@ -7014,7 +7016,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t i = sd->equip_index[EQI_HEAD_TOP]; if ( i < 0 || !sd->inventory_data[i] ) return 0; - pc->unequipitem(sd,i,3); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; @@ -7084,12 +7086,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t if( !(sd->bonus.unstripable_equip&EQP_ACC_L) ) { i = sd->equip_index[EQI_ACC_L]; if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR ) - pc->unequipitem(sd,i,3); //L-Accessory + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); //L-Accessory } if( !(sd->bonus.unstripable_equip&EQP_ACC_R) ) { i = sd->equip_index[EQI_ACC_R]; if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR ) - pc->unequipitem(sd,i,3); //R-Accessory + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); //R-Accessory } if( i < 0 ) return 0; @@ -7539,7 +7541,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t struct map_session_data *tsd; if( sd ) { int i; - for( i = 0; i < 5; i++ ) { + for( i = 0; i < MAX_PC_DEVOTION; i++ ) { if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) ) status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_ALL); } @@ -7638,7 +7640,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t struct map_session_data *tsd; if( sd ) { int i; - for( i = 0; i < 5; i++ ) { + for( i = 0; i < MAX_PC_DEVOTION; i++ ) { if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) ) status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL); } @@ -7896,7 +7898,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t if( bl->type&(BL_PC|BL_MER) ) { if( sd ) { - for( i = 0; i < 5; i++ ) { + for( i = 0; i < MAX_PC_DEVOTION; i++ ) { if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) ) status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL); } @@ -7916,7 +7918,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t if (sd) { struct map_session_data *tsd; int i; - for (i = 0; i < 5; i++) { + for (i = 0; i < MAX_PC_DEVOTION; i++) { //See if there are devoted characters, and pass the status to them. [Skotlex] if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i]))) status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,SCFLAG_NOAVOID); @@ -8809,6 +8811,9 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t else val2 = val2 / 4 * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level] break; + case SC_GENTLETOUCH_ENERGYGAIN: + val2 = 10 + 5 * val1; + break; case SC_PYROTECHNIC_OPTION: val2 = 60; break; @@ -9257,11 +9262,11 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t case SC_NEEDLE_OF_PARALYZE: case SC_DEATHBOUND: case SC_NETHERWORLD: - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); break; case SC_ANKLESNARE: if( battle_config.skill_trap_type || !map_flag_gvg(bl->m) ) - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); break; case SC_HIDING: case SC_CLOAKING: @@ -9783,7 +9788,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const begin_spurt = false; ud->state.running = 0; if (ud->walktimer != INVALID_TIMER) - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); } if (begin_spurt && sce->val1 >= 7 && DIFF_TICK(timer->gettick(), starttick) <= 1000 @@ -9806,7 +9811,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const if( bl->type == BL_PC ) { // Clear Status from others int i; - for( i = 0; i < 5; i++ ) { + for( i = 0; i < MAX_PC_DEVOTION; i++ ) { if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) && tsd->sc.data[type] ) status_change_end(&tsd->bl, type, INVALID_TIMER); } @@ -10078,7 +10083,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const struct block_list* src = map->id2bl(sce->val2); if( tid == -1 || !src) break; // Terminated by Damage - status_fix_damage(src,bl,400*sce->val1,clif->damage(bl,bl,0,0,400*sce->val1,0,0,0)); + status_fix_damage(src,bl,400*sce->val1,clif->damage(bl,bl,0,0,400*sce->val1,0,BDT_NORMAL,0)); } break; case SC_WUGDASH: @@ -10087,7 +10092,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const if (ud) { ud->state.running = 0; if (ud->walktimer != -1) - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); } } break; @@ -10130,15 +10135,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const map->foreachinrange(status->change_timer_sub, bl, battle_config.area_size,BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, timer->gettick()); break; case SC_RAISINGDRAGON: - if( sd && sce->val2 && !pc_isdead(sd) ) { + if ( sd && sce->val2 && !pc_isdead(sd) ) { int i; - i = min(sd->spiritball,5); - pc->delspiritball(sd, sd->spiritball, 0); + if ( (i = (sd->spiritball - 5)) > 0 ) + pc->delspiritball(sd, i, 0); status_change_end(bl, SC_EXPLOSIONSPIRITS, INVALID_TIMER); - while( i > 0 ) { - pc->addspiritball(sd, skill->get_time(MO_CALLSPIRITS, pc->checkskill(sd,MO_CALLSPIRITS)), 5); - --i; - } } break; case SC_CURSEDCIRCLE_TARGET: @@ -10577,7 +10578,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { case SC_STONE: if(sc->opt1 == OPT1_STONEWAIT && sce->val3) { sce->val4 = 0; - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); unit->stop_attack(bl); sc->opt1 = OPT1_STONE; clif->changeoption(bl); @@ -10624,14 +10625,16 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { case SC_KNOWLEDGE: if (!sd) break; - if (bl->m == sd->feel_map[0].m - || bl->m == sd->feel_map[1].m - || bl->m == sd->feel_map[2].m - ) { - //Timeout will be handled by pc->setpos - sce->timer = INVALID_TIMER; - return 0; + { + int i; + for (i = 0; i < MAX_PC_FEELHATE; i++) { + if (bl->m == sd->feel_map[i].m) { + //Timeout will be handled by pc->setpos + sce->timer = INVALID_TIMER; + return 0; + } } + } break; case SC_BLOODING: @@ -10818,7 +10821,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { case SC_PYREXIA: if( --(sce->val4) > 0 ) { map->freeblock_lock(); - clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,0,0); + clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,BDT_NORMAL,0); status_fix_damage(NULL,bl,100,0); if( sc->data[type] ) { sc_timer_next(3000+tick,status->change_timer,bl->id,data); @@ -10834,7 +10837,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { damage += st->vit * (sce->val1 - 3); unit->skillcastcancel(bl,2); map->freeblock_lock(); - status->damage(bl, bl, damage, 0, clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,0,0), 1); + status->damage(bl, bl, damage, 0, clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,BDT_NORMAL,0), 1); if( sc->data[type] ) { sc_timer_next(1000 + tick, status->change_timer, bl->id, data ); } @@ -10896,7 +10899,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { if( --(sce->val4) > 0 ) { //Damage is every 10 seconds including 3%sp drain. map->freeblock_lock(); - clif->damage(bl,bl,status_get_amotion(bl),1,1,0,0,0); + clif->damage(bl,bl,status_get_amotion(bl),1,1,0,BDT_NORMAL,0); status->damage(NULL, bl, 1, st->max_sp * 3 / 100, 0, 0); //cancel dmg only if cancelable if( sc->data[type] ) { sc_timer_next(10000 + tick, status->change_timer, bl->id, data ); @@ -10953,7 +10956,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { int damage = 1000 + 3 * status_get_max_hp(bl) / 100; // Deals fixed (1000 + 3%*MaxHP) map->freeblock_lock(); - clif->damage(bl,bl,0,0,damage,1,9,0); //damage is like endure effect with no walk delay + clif->damage(bl,bl,0,0,damage,1,BDT_MULTIENDURE,0); //damage is like endure effect with no walk delay status->damage(src, bl, damage, 0, 0, 1); if( sc->data[type]){ // Target still lives. [LimitLine] @@ -11055,7 +11058,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { break; map->freeblock_lock(); damage = sce->val3; - status->damage(src, bl, damage, 0, clif->damage(bl,bl,st->amotion,st->dmotion+200,damage,1,0,0), 1); + status->damage(src, bl, damage, 0, clif->damage(bl,bl,st->amotion,st->dmotion+200,damage,1,BDT_NORMAL,0), 1); unit->skillcastcancel(bl,1); if ( sc->data[type] ) { sc_timer_next(1000 + tick, status->change_timer, bl->id, data); @@ -11163,7 +11166,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { int damage = st->max_hp / 100; // Suggestion 1% each second if( damage >= st->hp ) damage = st->hp - 1; // Do not kill, just keep you with 1 hp minimum map->freeblock_lock(); - status_fix_damage(NULL,bl,damage,clif->damage(bl,bl,0,0,damage,0,0,0)); + status_fix_damage(NULL,bl,damage,clif->damage(bl,bl,0,0,damage,0,BDT_NORMAL,0)); if( sc->data[type] ) { sc_timer_next(1000 + tick, status->change_timer, bl->id, data); } @@ -11261,7 +11264,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { if( --(sce->val4) > 0 ) { status->charge(bl,0,sce->val2); // Reduce 8 every 10 seconds. if( sd && !pc_issit(sd) ) { // Force to sit every 10 seconds. - pc_stop_walking(sd,1|4); + pc_stop_walking(sd, STOPWALKING_FLAG_FIXPOS|STOPWALKING_FLAG_NEXTCELL); pc_stop_attack(sd); pc_setsit(sd); clif->sitting(bl); diff --git a/src/map/status.h b/src/map/status.h index b370a9c88..af11683a0 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -1655,49 +1655,6 @@ enum { OPT3_CONTRACT = 0x00020000, }; -enum { - OPTION_NOTHING = 0x00000000, - OPTION_SIGHT = 0x00000001, - OPTION_HIDE = 0x00000002, - OPTION_CLOAK = 0x00000004, - OPTION_FALCON = 0x00000010, - OPTION_RIDING = 0x00000020, - OPTION_INVISIBLE = 0x00000040, - OPTION_ORCISH = 0x00000800, - OPTION_WEDDING = 0x00001000, - OPTION_RUWACH = 0x00002000, - OPTION_CHASEWALK = 0x00004000, - OPTION_FLYING = 0x00008000, //Note that clientside Flying and Xmas are 0x8000 for clients prior to 2007. - OPTION_XMAS = 0x00010000, - OPTION_TRANSFORM = 0x00020000, - OPTION_SUMMER = 0x00040000, - OPTION_DRAGON1 = 0x00080000, - OPTION_WUG = 0x00100000, - OPTION_WUGRIDER = 0x00200000, - OPTION_MADOGEAR = 0x00400000, - OPTION_DRAGON2 = 0x00800000, - OPTION_DRAGON3 = 0x01000000, - OPTION_DRAGON4 = 0x02000000, - OPTION_DRAGON5 = 0x04000000, - OPTION_HANBOK = 0x08000000, - OPTION_OKTOBERFEST = 0x10000000, - -#ifndef NEW_CARTS - OPTION_CART1 = 0x00000008, - OPTION_CART2 = 0x00000080, - OPTION_CART3 = 0x00000100, - OPTION_CART4 = 0x00000200, - OPTION_CART5 = 0x00000400, - - /* compound constant for older carts */ - OPTION_CART = OPTION_CART1|OPTION_CART2|OPTION_CART3|OPTION_CART4|OPTION_CART5, -#endif - - // compound constants - OPTION_DRAGON = OPTION_DRAGON1|OPTION_DRAGON2|OPTION_DRAGON3|OPTION_DRAGON4|OPTION_DRAGON5, - OPTION_COSTUME = OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST, -}; - //Defines for the manner system [Skotlex] enum manner_flags { diff --git a/src/map/storage.c b/src/map/storage.c index 79a5ad52d..2706b3683 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -83,7 +83,7 @@ int storage_storageopen(struct map_session_data *sd) { nullpo_ret(sd); - if(sd->state.storage_flag) + if (sd->state.storage_flag != STORAGE_FLAG_CLOSED) return 1; //Already open? if( !pc_can_give_items(sd) ) { @@ -92,7 +92,7 @@ int storage_storageopen(struct map_session_data *sd) return 1; } - sd->state.storage_flag = 1; + sd->state.storage_flag = STORAGE_FLAG_NORMAL; storage->sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items)); clif->storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items)); clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE); @@ -190,9 +190,11 @@ int storage_delitem(struct map_session_data* sd, int n, int amount) { memset(&sd->status.storage.items[n],0,sizeof(sd->status.storage.items[0])); sd->status.storage.storage_amount--; - if( sd->state.storage_flag == 1 ) clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE); + if( sd->state.storage_flag == STORAGE_FLAG_NORMAL ) + clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE); } - if( sd->state.storage_flag == 1 ) clif->storageitemremoved(sd,n,amount); + if( sd->state.storage_flag == STORAGE_FLAG_NORMAL ) + clif->storageitemremoved(sd,n,amount); return 0; } @@ -219,9 +221,9 @@ int storage_storageadd(struct map_session_data* sd, int index, int amount) { return 0; if( storage->additem(sd,&sd->status.inventory[index],amount) == 0 ) - pc->delitem(sd,index,amount,0,4,LOG_TYPE_STORAGE); + pc->delitem(sd, index, amount, 0, DELITEM_TOSTORAGE, LOG_TYPE_STORAGE); else - clif->dropitem(sd, index,0); + clif->dropitem(sd, index, 0); return 1; } @@ -325,7 +327,7 @@ void storage_storageclose(struct map_session_data* sd) { if( map->save_settings&4 ) chrif->save(sd,0); //Invokes the storage saving as well. - sd->state.storage_flag = 0; + sd->state.storage_flag = STORAGE_FLAG_CLOSED; } /*========================================== @@ -337,7 +339,7 @@ void storage_storage_quit(struct map_session_data* sd, int flag) { if (map->save_settings&4) chrif->save(sd, flag); //Invokes the storage saving as well. - sd->state.storage_flag = 0; + sd->state.storage_flag = STORAGE_FLAG_CLOSED; } /** @@ -380,7 +382,7 @@ int storage_guild_storageopen(struct map_session_data* sd) if(sd->status.guild_id <= 0) return 2; - if(sd->state.storage_flag) + if (sd->state.storage_flag != STORAGE_FLAG_CLOSED) return 1; //Can't open both storages at a time. if( !pc_can_give_items(sd) ) { //check is this GM level can open guild storage and store items [Lupus] @@ -399,7 +401,7 @@ int storage_guild_storageopen(struct map_session_data* sd) return 1; gstor->storage_status = 1; - sd->state.storage_flag = 2; + sd->state.storage_flag = STORAGE_FLAG_GUILD; storage->sortitem(gstor->items, ARRAYLENGTH(gstor->items)); clif->storagelist(sd, gstor->items, ARRAYLENGTH(gstor->items)); clif->updatestorageamount(sd, gstor->storage_amount, MAX_GUILD_STORAGE); @@ -525,10 +527,10 @@ int storage_guild_storageadd(struct map_session_data* sd, int index, int amount) return 0; } - if(gstorage->additem(sd,stor,&sd->status.inventory[index],amount)==0) - pc->delitem(sd,index,amount,0,4,LOG_TYPE_GSTORAGE); + if( gstorage->additem(sd,stor,&sd->status.inventory[index],amount) == 0 ) + pc->delitem(sd, index, amount, 0, DELITEM_TOSTORAGE, LOG_TYPE_GSTORAGE); else - clif->dropitem(sd, index,0); + clif->dropitem(sd, index, 0); return 1; } @@ -694,7 +696,7 @@ int storage_guild_storageclose(struct map_session_data* sd) { gstorage->save(sd->status.account_id, sd->status.guild_id,0); stor->storage_status=0; } - sd->state.storage_flag = 0; + sd->state.storage_flag = STORAGE_FLAG_CLOSED; return 0; } @@ -707,7 +709,7 @@ int storage_guild_storage_quit(struct map_session_data* sd, int flag) { if(flag) { //Only during a guild break flag is 1 (don't save storage) - sd->state.storage_flag = 0; + sd->state.storage_flag = STORAGE_FLAG_CLOSED; stor->storage_status = 0; clif->storageclose(sd); if (map->save_settings&4) @@ -721,7 +723,7 @@ int storage_guild_storage_quit(struct map_session_data* sd, int flag) { else gstorage->save(sd->status.account_id,sd->status.guild_id,1); } - sd->state.storage_flag = 0; + sd->state.storage_flag = STORAGE_FLAG_CLOSED; stor->storage_status = 0; return 0; diff --git a/src/map/storage.h b/src/map/storage.h index 6393e124a..6a9e7a2ac 100644 --- a/src/map/storage.h +++ b/src/map/storage.h @@ -12,6 +12,15 @@ struct guild_storage; struct item; struct map_session_data; +/** + * Acceptable values for map_session_data.state.storage_flag + */ +enum storage_flag { + STORAGE_FLAG_CLOSED = 0, // Closed + STORAGE_FLAG_NORMAL = 1, // Normal Storage open + STORAGE_FLAG_GUILD = 2, // Guild Storage open +}; + struct storage_interface { /* */ void (*reconnect) (void); diff --git a/src/map/trade.c b/src/map/trade.c index 7417f05af..a17938779 100644 --- a/src/map/trade.c +++ b/src/map/trade.c @@ -145,8 +145,8 @@ void trade_tradeack(struct map_session_data *sd, int type) { } //Check if you can start trade. - if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.storage_flag - || tsd->npc_id || tsd->state.vending || tsd->state.buyingstore || tsd->state.storage_flag + if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.storage_flag != STORAGE_FLAG_CLOSED + || tsd->npc_id || tsd->state.vending || tsd->state.buyingstore || tsd->state.storage_flag != STORAGE_FLAG_CLOSED ) { //Fail clif->tradestart(sd, 2); @@ -208,13 +208,13 @@ int impossible_trade_check(struct map_session_data *sd) intif->wis_message_to_gm(map->wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm); // if we block people if (battle_config.ban_hack_trade < 0) { - chrif->char_ask_name(-1, sd->status.name, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block + chrif->char_ask_name(-1, sd->status.name, CHAR_ASK_NAME_BLOCK, 0, 0, 0, 0, 0, 0); set_eof(sd->fd); // forced to disconnect because of the hack // message about the ban safestrncpy(message_to_gm, msg_txt(540), sizeof(message_to_gm)); // This player has been definitively blocked. // if we ban people } else if (battle_config.ban_hack_trade > 0) { - chrif->char_ask_name(-1, sd->status.name, 2, 0, 0, 0, 0, battle_config.ban_hack_trade, 0); // type: 2 - ban (year, month, day, hour, minute, second) + chrif->char_ask_name(-1, sd->status.name, CHAR_ASK_NAME_BAN, 0, 0, 0, 0, battle_config.ban_hack_trade, 0); // type: 2 - ban (year, month, day, hour, minute, second) set_eof(sd->fd); // forced to disconnect because of the hack // message about the ban sprintf(message_to_gm, msg_txt(507), battle_config.ban_hack_trade); // This player has been banned for %d minute(s). @@ -561,7 +561,7 @@ void trade_tradecommit(struct map_session_data *sd) { flag = pc->additem(tsd, &sd->status.inventory[n], sd->deal.item[trade_i].amount,LOG_TYPE_TRADE); if (flag == 0) - pc->delitem(sd, n, sd->deal.item[trade_i].amount, 1, 6, LOG_TYPE_TRADE); + pc->delitem(sd, n, sd->deal.item[trade_i].amount, 1, DELITEM_SOLD, LOG_TYPE_TRADE); else clif->additem(sd, n, sd->deal.item[trade_i].amount, 0); sd->deal.item[trade_i].index = 0; @@ -573,7 +573,7 @@ void trade_tradecommit(struct map_session_data *sd) { flag = pc->additem(sd, &tsd->status.inventory[n], tsd->deal.item[trade_i].amount,LOG_TYPE_TRADE); if (flag == 0) - pc->delitem(tsd, n, tsd->deal.item[trade_i].amount, 1, 6, LOG_TYPE_TRADE); + pc->delitem(tsd, n, tsd->deal.item[trade_i].amount, 1, DELITEM_SOLD, LOG_TYPE_TRADE); else clif->additem(tsd, n, tsd->deal.item[trade_i].amount, 0); tsd->deal.item[trade_i].index = 0; diff --git a/src/map/unit.c b/src/map/unit.c index 6a30c7e79..5ead7527e 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -737,7 +737,7 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool if( ud == NULL) return 0; - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); unit->stop_attack(bl); if( checkpath && (map->getcell(bl->m,dst_x,dst_y,CELL_CHKNOPASS) || !path->search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,easy,CELL_CHKNOREACH)) ) @@ -834,7 +834,7 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag) ny = result&0xffff; if(!su) { - unit->stop_walking(bl, 0); + unit->stop_walking(bl, STOPWALKING_FLAG_NONE); } if( sd ) { @@ -952,14 +952,10 @@ int unit_warp(struct block_list *bl,short m,short x,short y,clr_type type) /*========================================== * Caused the target object to stop moving. - * Flag values: - * &0x1: Issue a fixpos packet afterwards - * &0x2: Force the unit to move one cell if it hasn't yet - * &0x4: Enable moving to the next cell when unit was already half-way there - * (may cause on-touch/place side-effects, such as a scripted map change) + * Flag values: @see unit_stopwalking_flag. + * Upper bytes may be used for other purposes depending on the unit type. *------------------------------------------*/ -int unit_stop_walking(struct block_list *bl,int type) -{ +int unit_stop_walking(struct block_list *bl, int flag) { struct unit_data *ud; const struct TimerData* td; int64 tick; @@ -976,22 +972,22 @@ int unit_stop_walking(struct block_list *bl,int type) ud->walktimer = INVALID_TIMER; ud->state.change_walk_target = 0; tick = timer->gettick(); - if( (type&0x02 && !ud->walkpath.path_pos) //Force moving at least one cell. - || (type&0x04 && td && DIFF_TICK(td->tick, tick) <= td->data/2) //Enough time has passed to cover half-cell + if( (flag&STOPWALKING_FLAG_ONESTEP && !ud->walkpath.path_pos) //Force moving at least one cell. + || (flag&STOPWALKING_FLAG_NEXTCELL && td && DIFF_TICK(td->tick, tick) <= td->data/2) //Enough time has passed to cover half-cell ) { ud->walkpath.path_len = ud->walkpath.path_pos+1; unit->walktoxy_timer(INVALID_TIMER, tick, bl->id, ud->walkpath.path_pos); } - if(type&0x01) + if(flag&STOPWALKING_FLAG_FIXPOS) clif->fixpos(bl); ud->walkpath.path_len = 0; ud->walkpath.path_pos = 0; ud->to_x = bl->x; ud->to_y = bl->y; - if(bl->type == BL_PET && type&~0xff) - ud->canmove_tick = timer->gettick() + (type>>8); + if(bl->type == BL_PET && flag&~STOPWALKING_FLAG_MASK) + ud->canmove_tick = timer->gettick() + (flag>>8); //Read, the check in unit_set_walkdelay means dmg during running won't fall through to this place in code [Kevin] if (ud->state.running) { @@ -1169,17 +1165,14 @@ int unit_set_walkdelay(struct block_list *bl, int64 tick, int delay, int type) { //Stop walking, if chasing, readjust timers. if (delay == 1) { //Minimal delay (walk-delay) disabled. Just stop walking. - unit->stop_walking(bl,4); + unit->stop_walking(bl, STOPWALKING_FLAG_NEXTCELL); } else { //Resume running after can move again [Kevin] - if(ud->state.running) - { + if (ud->state.running) { timer->add(ud->canmove_tick, unit->resume_running, bl->id, (intptr_t)ud); - } - else - { - unit->stop_walking(bl,4); - if(ud->target) + } else { + unit->stop_walking(bl, STOPWALKING_FLAG_NEXTCELL); + if (ud->target) timer->add(ud->canmove_tick+1, unit->walktobl_sub, bl->id, ud->target); } } @@ -1376,7 +1369,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui case NPC_SUMMONSLAVE: case NPC_SUMMONMONSTER: case AL_TELEPORT: - if( ((TBL_MOB*)src)->master_id && ((TBL_MOB*)src)->special_state.ai ) + if (((TBL_MOB*)src)->master_id && ((TBL_MOB*)src)->special_state.ai != AI_NONE) return 0; } @@ -1547,8 +1540,8 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui } } - if(!ud->state.running) //need TK_RUN or WUGDASH handler to be done before that, see bugreport:6026 - unit->stop_walking(src,1);// even though this is not how official works but this will do the trick. bugreport:6829 + if (!ud->state.running) //need TK_RUN or WUGDASH handler to be done before that, see bugreport:6026 + unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS);// even though this is not how official works but this will do the trick. bugreport:6829 // in official this is triggered even if no cast time. clif->skillcasting(src, src->id, target_id, 0,0, skill_id, skill->get_ele(skill_id, skill_lv), casttime); @@ -1745,7 +1738,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui } } - unit->stop_walking(src,1); + unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS); // in official this is triggered even if no cast time. clif->skillcasting(src, src->id, 0, skill_x, skill_y, skill_id, skill->get_ele(skill_id, skill_lv), casttime); if( casttime > 0 ) { @@ -2134,7 +2127,7 @@ int unit_attack_timer_sub(struct block_list* src, int tid, int64 tick) { ud->dir = map->calc_dir(src, target->x,target->y ); } if(ud->walktimer != INVALID_TIMER) - unit->stop_walking(src,1); + unit->stop_walking(src, STOPWALKING_FLAG_FIXPOS); if(md) { //First attack is always a normal attack if(md->state.skillstate == MSS_ANGRY || md->state.skillstate == MSS_BERSERK) { @@ -2329,7 +2322,7 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i map->freeblock_lock(); if (ud->walktimer != INVALID_TIMER) - unit->stop_walking(bl,0); + unit->stop_walking(bl, STOPWALKING_FLAG_NONE); if (ud->skilltimer != INVALID_TIMER) unit->skillcastcancel(bl,0); @@ -2398,18 +2391,18 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i } //Leave/reject all invitations. if(sd->chatID) - chat->leave(sd,0); + chat->leave(sd, false); if(sd->trade_partner) trade->cancel(sd); buyingstore->close(sd); searchstore->close(sd); if( sd->menuskill_id != AL_TELEPORT ) { // issue: 8027 - if(sd->state.storage_flag == 1) + if(sd->state.storage_flag == STORAGE_FLAG_NORMAL) storage->pc_quit(sd,0); - else if (sd->state.storage_flag == 2) + else if (sd->state.storage_flag == STORAGE_FLAG_GUILD) gstorage->pc_quit(sd,0); - sd->state.storage_flag = 0; //Force close it when being warped. + sd->state.storage_flag = STORAGE_FLAG_CLOSED; //Force close it when being warped. } if(sd->party_invite>0) party->reply_invite(sd,sd->party_invite,0); diff --git a/src/map/unit.h b/src/map/unit.h index 881fa16f4..d434d52e4 100644 --- a/src/map/unit.h +++ b/src/map/unit.h @@ -13,6 +13,19 @@ struct map_session_data; struct block_list; +/** + * Bitmask values usable as a flag in unit_stopwalking + */ +enum unit_stopwalking_flag { + STOPWALKING_FLAG_NONE = 0x00, + STOPWALKING_FLAG_FIXPOS = 0x01, ///< Issue a fixpos packet afterwards + STOPWALKING_FLAG_ONESTEP = 0x02, ///< Force the unit to move one cell if it hasn't yet + STOPWALKING_FLAG_NEXTCELL = 0x04, ///< Enable moving to the next cell when unit was already half-way there + /// (may cause on-touch/place side-effects, such as a scripted map change) + STOPWALKING_FLAG_MASK = 0xff, ///< Mask all of the above + // Note: Upper bytes are reserved for duration. +}; + struct unit_data { struct block_list *bl; struct walkpath_data walkpath; diff --git a/src/map/vending.c b/src/map/vending.c index 8ae3f36a4..b32c3e43e 100644 --- a/src/map/vending.c +++ b/src/map/vending.c @@ -38,7 +38,7 @@ void vending_closevending(struct map_session_data* sd) { nullpo_retv(sd); if( sd->state.vending ) { - sd->state.vending = false; + sd->state.vending = 0; clif->closevendingboard(&sd->bl, 0); idb_remove(vending->db, sd->status.char_id); } |