summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/mmo.h2
-rw-r--r--src/map/atcommand.c117
-rw-r--r--src/map/battle.c439
-rw-r--r--src/map/battle.h1
-rw-r--r--src/map/battleground.c14
-rw-r--r--src/map/battleground.h1
-rw-r--r--src/map/buyingstore.c6
-rw-r--r--src/map/chrif.c194
-rw-r--r--src/map/chrif.h104
-rw-r--r--src/map/clif.c113
-rw-r--r--src/map/clif.h1
-rw-r--r--src/map/guild.c6
-rw-r--r--src/map/instance.c45
-rw-r--r--src/map/intif.c22
-rw-r--r--src/map/itemdb.c641
-rw-r--r--src/map/itemdb.h180
-rw-r--r--src/map/log.c4
-rw-r--r--src/map/map.c63
-rw-r--r--src/map/map.h3
-rw-r--r--src/map/mob.c25
-rw-r--r--src/map/npc.c47
-rw-r--r--src/map/packets.h213
-rw-r--r--src/map/packets_struct.h13
-rw-r--r--src/map/party.c43
-rw-r--r--src/map/party.h2
-rw-r--r--src/map/pc.c1696
-rw-r--r--src/map/pc.h5
-rw-r--r--src/map/pet.c4
-rw-r--r--src/map/quest.c8
-rw-r--r--src/map/script.c353
-rw-r--r--src/map/script.h10
-rw-r--r--src/map/searchstore.c4
-rw-r--r--src/map/skill.c115
-rw-r--r--src/map/skill.h3
-rw-r--r--src/map/status.c1275
-rw-r--r--src/map/status.h10
-rw-r--r--src/map/storage.c126
-rw-r--r--src/map/storage.h73
-rw-r--r--src/map/trade.c14
-rw-r--r--src/map/trade.h7
-rw-r--r--src/map/unit.c4
-rw-r--r--src/map/vending.c4
-rw-r--r--src/plugins/db2sql.c16
43 files changed, 3690 insertions, 2336 deletions
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 8643d2b54..6e5dae099 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -534,7 +534,7 @@ struct guild {
/* TODO: still used for something?|: */
unsigned short save_flag; // for TXT saving
- unsigned short *instance;
+ short *instance;
unsigned short instances;
void *channel;
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index b6a9e42ee..b778aab6c 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -745,7 +745,7 @@ ACMD(save)
if (sd->status.pet_id > 0 && sd->pd)
intif_save_petdata(sd->status.account_id, &sd->pd->pet);
- chrif_save(sd,0);
+ chrif->save(sd,0);
clif->message(fd, msg_txt(6)); // Your save point has been changed.
@@ -816,8 +816,7 @@ ACMD(storage)
if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading || sd->state.storage_flag)
return false;
- if (storage_storageopen(sd) == 1)
- { //Already open.
+ if (storage->open(sd) == 1) { //Already open.
clif->message(fd, msg_txt(250));
return false;
}
@@ -853,7 +852,7 @@ ACMD(guildstorage)
return false;
}
- storage_guild_storageopen(sd);
+ gstorage->open(sd);
clif->message(fd, msg_txt(920)); // Guild storage opened.
return true;
}
@@ -1146,8 +1145,8 @@ ACMD(item)
if (number <= 0)
number = 1;
- if ((item_data = itemdb_searchname(item_name)) == NULL &&
- (item_data = itemdb_exists(atoi(item_name))) == NULL)
+ if ((item_data = itemdb->search_name(item_name)) == NULL &&
+ (item_data = itemdb->exists(atoi(item_name))) == NULL)
{
clif->message(fd, msg_txt(19)); // Invalid item ID or name.
return false;
@@ -1204,8 +1203,8 @@ ACMD(item2)
number = 1;
item_id = 0;
- if ((item_data = itemdb_searchname(item_name)) != NULL ||
- (item_data = itemdb_exists(atoi(item_name))) != NULL)
+ if ((item_data = itemdb->search_name(item_name)) != NULL ||
+ (item_data = itemdb->exists(atoi(item_name))) != NULL)
item_id = item_data->nameid;
if (item_id > 500) {
@@ -2129,8 +2128,8 @@ ACMD(produce)
return false;
}
- if ( (item_data = itemdb_searchname(item_name)) == NULL &&
- (item_data = itemdb_exists(atoi(item_name))) == NULL ) {
+ if ( (item_data = itemdb->search_name(item_name)) == NULL &&
+ (item_data = itemdb->exists(atoi(item_name))) == NULL ) {
clif->message(fd, msg_txt(170)); //This item is not an equipment.
return false;
}
@@ -2549,7 +2548,7 @@ ACMD(makeegg)
return false;
}
- if ((item_data = itemdb_searchname(message)) != NULL) // for egg name
+ if ((item_data = itemdb->search_name(message)) != NULL) // for egg name
id = item_data->nameid;
else
if ((id = mobdb_searchname(message)) != 0) // for monster name
@@ -2746,7 +2745,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, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block
clif->message(fd, msg_txt(88)); // Character name sent to char-server to ask it.
return true;
@@ -2843,7 +2842,7 @@ ACMD(char_ban)
return false;
}
- chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 2, year, month, day, hour, minute, second); // type: 2 - ban
+ chrif->char_ask_name(sd->status.account_id, atcmd_player_name, 2, year, month, day, hour, minute, second); // type: 2 - ban
clif->message(fd, msg_txt(88)); // Character name sent to char-server to ask it.
return true;
@@ -2864,7 +2863,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, 3, 0, 0, 0, 0, 0, 0); // type: 3 - unblock
clif->message(fd, msg_txt(88)); // Character name sent to char-server to ask it.
return true;
@@ -2885,7 +2884,7 @@ ACMD(char_unban)
}
// send answer to login server via char-server
- chrif_char_ask_name(sd->status.account_id, atcmd_player_name, 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban
+ chrif->char_ask_name(sd->status.account_id, atcmd_player_name, 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban
clif->message(fd, msg_txt(88)); // Character name sent to char-server to ask it.
return true;
@@ -3396,7 +3395,7 @@ ACMD(idsearch)
sprintf(atcmd_output, msg_txt(77), item_name); // The reference result of '%s' (name: id):
clif->message(fd, atcmd_output);
- match = itemdb_searchname_array(item_array, MAX_SEARCH, item_name);
+ match = itemdb->search_name_array(item_array, MAX_SEARCH, item_name);
if (match > MAX_SEARCH) {
sprintf(atcmd_output, msg_txt(269), MAX_SEARCH, match);
clif->message(fd, atcmd_output);
@@ -3583,7 +3582,7 @@ ACMD(partyrecall)
ACMD(reloaditemdb)
{
nullpo_retr(-1, sd);
- itemdb_reload();
+ itemdb->reload();
clif->message(fd, msg_txt(97)); // Item database has been reloaded.
return true;
@@ -3689,7 +3688,7 @@ ACMD(reloadbattleconf)
)
{ // Exp or Drop rates changed.
mob_reload(); //Needed as well so rate changes take effect.
- chrif_ragsrvinfo(battle_config.base_exp_rate, battle_config.job_exp_rate, battle_config.item_rate_common);
+ chrif->ragsrvinfo(battle_config.base_exp_rate, battle_config.job_exp_rate, battle_config.item_rate_common);
}
clif->message(fd, msg_txt(255));
return true;
@@ -4024,6 +4023,11 @@ ACMD(mount_peco)
return false;
}
+ if( sd->sc.data[SC_ALL_RIDING] ) {
+ clif->message(fd, msg_txt(1476)); // You are already mounting something else
+ return false;
+ }
+
if( (sd->class_&MAPID_THIRDMASK) == MAPID_RUNE_KNIGHT && pc->checkskill(sd,RK_DRAGONTRAINING) > 0 ) {
if( !(sd->sc.option&OPTION_DRAGON1) ) {
clif->message(sd->fd,msg_txt(1119)); // You have mounted your Dragon.
@@ -5011,7 +5015,7 @@ ACMD(email)
return false;
}
- chrif_changeemail(sd->status.account_id, actual_email, new_email);
+ chrif->changeemail(sd->status.account_id, actual_email, new_email);
clif->message(fd, msg_txt(148)); // Information sended to login-server via char-server.
return true;
}
@@ -5233,7 +5237,7 @@ ACMD(storeall)
if (sd->state.storage_flag != 1)
{ //Open storage.
- if( storage_storageopen(sd) == 1 ) {
+ if( storage->open(sd) == 1 ) {
clif->message(fd, msg_txt(1161)); // You currently cannot open your storage.
return false;
}
@@ -5243,10 +5247,10 @@ ACMD(storeall)
if (sd->status.inventory[i].amount) {
if(sd->status.inventory[i].equip != 0)
pc->unequipitem(sd, i, 3);
- storage_storageadd(sd, i, sd->status.inventory[i].amount);
+ storage->add(sd, i, sd->status.inventory[i].amount);
}
}
- storage_storageclose(sd);
+ storage->close(sd);
clif->message(fd, msg_txt(1162)); // All items stored.
return true;
@@ -5264,9 +5268,9 @@ ACMD(clearstorage)
j = sd->status.storage.storage_amount;
for (i = 0; i < j; ++i) {
- storage_delitem(sd, i, sd->status.storage.items[i].amount);
+ storage->delitem(sd, i, sd->status.storage.items[i].amount);
}
- storage_storageclose(sd);
+ storage->close(sd);
clif->message(fd, msg_txt(1394)); // Your storage was cleaned.
return true;
@@ -5276,7 +5280,7 @@ ACMD(cleargstorage)
{
int i, j;
struct guild *g;
- struct guild_storage *gstorage;
+ struct guild_storage *guild_storage;
nullpo_retr(-1, sd);
g = sd->guild;
@@ -5296,18 +5300,18 @@ ACMD(cleargstorage)
return false;
}
- gstorage = guild2storage2(sd->status.guild_id);
- if (gstorage == NULL) {// Doesn't have opened @gstorage yet, so we skip the deletion since *shouldn't* have any item there.
+ guild_storage = gstorage->id2storage2(sd->status.guild_id);
+ if (guild_storage == NULL) {// Doesn't have opened @gstorage yet, so we skip the deletion since *shouldn't* have any item there.
return false;
}
- j = gstorage->storage_amount;
- gstorage->lock = 1; // Lock @gstorage: do not allow any item to be retrieved or stored from any guild member
+ j = guild_storage->storage_amount;
+ guild_storage->lock = 1; // Lock @gstorage: do not allow any item to be retrieved or stored from any guild member
for (i = 0; i < j; ++i) {
- guild_storage_delitem(sd, gstorage, i, gstorage->items[i].amount);
+ gstorage->delitem(sd, guild_storage, i, guild_storage->items[i].amount);
}
- storage_guild_storageclose(sd);
- gstorage->lock = 0; // Cleaning done, release lock
+ gstorage->close(sd);
+ guild_storage->lock = 0; // Cleaning done, release lock
clif->message(fd, msg_txt(1395)); // Your guild storage was cleaned.
return true;
@@ -5799,8 +5803,8 @@ ACMD(autolootitem)
if (action < 3) // add or remove
{
- if ((item_data = itemdb_exists(atoi(message))) == NULL)
- item_data = itemdb_searchname(message);
+ if ((item_data = itemdb->exists(atoi(message))) == NULL)
+ item_data = itemdb->search_name(message);
if (!item_data) {
// No items founds in the DB with Id or Name
clif->message(fd, msg_txt(1189)); // Item not found.
@@ -5853,7 +5857,7 @@ ACMD(autolootitem)
{
if (sd->state.autolootid[i] == 0)
continue;
- if (!(item_data = itemdb_exists(sd->state.autolootid[i]))) {
+ if (!(item_data = itemdb->exists(sd->state.autolootid[i]))) {
ShowDebug("Non-existant item %d on autolootitem list (account_id: %d, char_id: %d)", sd->state.autolootid[i], sd->status.account_id, sd->status.char_id);
continue;
}
@@ -6514,7 +6518,7 @@ ACMD(changesex)
// 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);
- chrif_changesex(sd);
+ chrif->changesex(sd);
return true;
}
@@ -6696,7 +6700,7 @@ ACMD(mobinfo)
j = 0;
for (i = 0; i < MAX_MOB_DROP; i++) {
int droprate;
- if (mob->dropitem[i].nameid <= 0 || mob->dropitem[i].p < 1 || (item_data = itemdb_exists(mob->dropitem[i].nameid)) == NULL)
+ if (mob->dropitem[i].nameid <= 0 || mob->dropitem[i].p < 1 || (item_data = itemdb->exists(mob->dropitem[i].nameid)) == NULL)
continue;
droprate = mob->dropitem[i].p;
@@ -6721,7 +6725,7 @@ ACMD(mobinfo)
strcpy(atcmd_output, msg_txt(1248)); // MVP Items:
j = 0;
for (i = 0; i < MAX_MVP_DROP; i++) {
- if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_exists(mob->mvpitem[i].nameid)) == NULL)
+ if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb->exists(mob->mvpitem[i].nameid)) == NULL)
continue;
if (mob->mvpitem[i].p > 0) {
j++;
@@ -7143,8 +7147,8 @@ ACMD(iteminfo)
clif->message(fd, msg_txt(1276)); // Please enter an item name/ID (usage: @ii/@iteminfo <item name/ID>).
return false;
}
- if ((item_array[0] = itemdb_exists(atoi(message))) == NULL)
- count = itemdb_searchname_array(item_array, MAX_SEARCH, message);
+ if ((item_array[0] = itemdb->exists(atoi(message))) == NULL)
+ count = itemdb->search_name_array(item_array, MAX_SEARCH, message);
if (!count) {
clif->message(fd, msg_txt(19)); // Invalid item ID or name.
@@ -7192,8 +7196,8 @@ ACMD(whodrops)
clif->message(fd, msg_txt(1284)); // Please enter item name/ID (usage: @whodrops <item name/ID>).
return false;
}
- if ((item_array[0] = itemdb_exists(atoi(message))) == NULL)
- count = itemdb_searchname_array(item_array, MAX_SEARCH, message);
+ if ((item_array[0] = itemdb->exists(atoi(message))) == NULL)
+ count = itemdb->search_name_array(item_array, MAX_SEARCH, message);
if (!count) {
clif->message(fd, msg_txt(19)); // Invalid item ID or name.
@@ -7569,6 +7573,7 @@ return true;\
checkflag(nojobexp); checkflag(nomobloot); checkflag(nomvploot); checkflag(nightenabled);
checkflag(nodrop); checkflag(novending); checkflag(loadevent);
checkflag(nochat); checkflag(partylock); checkflag(guildlock); checkflag(src4instance);
+ checkflag(notomb);
clif->message(sd->fd," ");
clif->message(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
clif->message(sd->fd,msg_txt(1313)); // Type "@mapflag available" to list the available mapflags.
@@ -7605,6 +7610,7 @@ return true;\
setflag(nojobexp); setflag(nomobloot); setflag(nomvploot); setflag(nightenabled);
setflag(nodrop); setflag(novending); setflag(loadevent);
setflag(nochat); setflag(partylock); setflag(guildlock); setflag(src4instance);
+ setflag(notomb);
clif->message(sd->fd,msg_txt(1314)); // Invalid flag name or flag.
clif->message(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
@@ -7616,7 +7622,7 @@ return true;\
clif->message(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,");
clif->message(sd->fd,"fog, fireworks, sakura, leaves, nobaseexp, nojobexp, nomobloot,");
clif->message(sd->fd,"nomvploot, nightenabled, nodrop, novending, loadevent, nochat, partylock,");
- clif->message(sd->fd,"guildlock, src4instance");
+ clif->message(sd->fd,"guildlock, src4instance, notomb");
#undef checkflag
#undef setflag
@@ -8112,7 +8118,7 @@ ACMD(itemlist)
const struct item* it = &items[i];
struct item_data* itd;
- if( it->nameid == 0 || (itd = itemdb_exists(it->nameid)) == NULL )
+ if( it->nameid == 0 || (itd = itemdb->exists(it->nameid)) == NULL )
continue;
counter += it->amount;
@@ -8195,7 +8201,7 @@ ACMD(itemlist)
{
struct item_data* card;
- if( it->card[j] == 0 || (card = itemdb_exists(it->card[j])) == NULL )
+ if( it->card[j] == 0 || (card = itemdb->exists(it->card[j])) == NULL )
continue;
counter2++;
@@ -8308,7 +8314,7 @@ ACMD(delitem)
return false;
}
- if( ( id = itemdb_searchname(item_name) ) != NULL || ( id = itemdb_exists(atoi(item_name)) ) != NULL )
+ if( ( id = itemdb->search_name(item_name) ) != NULL || ( id = itemdb->exists(atoi(item_name)) ) != NULL )
{
nameid = id->nameid;
}
@@ -8472,6 +8478,11 @@ ACMD(charcommands)
/* for new mounts */
ACMD(mount2) {
+ if( sd->sc.option&(OPTION_WUGRIDER|OPTION_RIDING|OPTION_DRAGON|OPTION_MADOGEAR) ) {
+ clif->message(fd, msg_txt(1476)); // You are already mounting something else
+ return false;
+ }
+
clif->message(sd->fd,msg_txt(1362)); // NOTICE: If you crash with mount your LUA is outdated.
if( !(sd->sc.data[SC_ALL_RIDING]) ) {
clif->message(sd->fd,msg_txt(1363)); // You have mounted.
@@ -9046,11 +9057,17 @@ ACMD(channel) {
return false;
}
- if( sub2[0] == '\0' || ( pl_sd = iMap->nick2sd(sub2) ) == NULL ) {
- sprintf(atcmd_output, msg_txt(1434), sub2);// Player '%s' was not found
- clif->message(fd, atcmd_output);
- return false;
+ if (!message || !*message || sscanf(message, "%s %s %24[^\n]", key, sub1, sub2) < 1) {
+ sprintf(atcmd_output, msg_txt(1434), sub2);// Player '%s' was not found
+ clif->message(fd, atcmd_output);
+ return false;
}
+
+ if( sub2[0] == '\0' || ( pl_sd = iMap->nick2sd(sub2) ) == NULL ) {
+ sprintf(atcmd_output, msg_txt(1434), sub2);// Player '%s' was not found
+ clif->message(fd, atcmd_output);
+ return false;
+ }
if( pc_has_permission(pl_sd, PC_PERM_HCHSYS_ADMIN) ) {
clif->message(fd, msg_txt(1464)); // Ban failed, not possible to ban this user.
diff --git a/src/map/battle.c b/src/map/battle.c
index ace947aca..d67684e7b 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -429,18 +429,19 @@ int battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, uin
damage = battle->calc_sizefix(sd, damage, EQI_HAND_R, size, flag&8);
else
damage = battle->calc_sizefix(sd, damage, EQI_HAND_L, size, flag&8);
+
+ if( flag&2 && sd->bonus.arrow_atk )
+ damage += sd->bonus.arrow_atk;
if( sd->bonus.eatk > 0 )
eatk = sd->bonus.eatk;
- if( flag&2 && sd->bonus.arrow_atk )
- eatk += sd->bonus.arrow_atk;
}
-
+
if( sc && sc->count ){
if( sc->data[SC_ZENKAI] && watk->ele == sc->data[SC_ZENKAI]->val2 )
eatk += 200;
#ifdef RENEWAL_EDP
- if( sc->data[SC_EDP] && skill_id != AS_GRIMTOOTH && skill_id != AS_VENOMKNIFE ){
+ if( sc->data[SC_EDP] && skill_id != AS_GRIMTOOTH && skill_id != AS_VENOMKNIFE && skill_id != ASC_BREAKER ){
eatk = eatk * sc->data[SC_EDP]->val3 / 100; // 400%
damage = damage * sc->data[SC_EDP]->val4 / 100; // 500%
damage--; // temporary until we find the correct formula [malufett]
@@ -448,19 +449,14 @@ int battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, uin
#endif
}
- /* [malufett]
- some unknown factors that needs to be discovered. PS: it's something related with ranged attacks
- if( eatk ){
- eatk += unknown value;
- eatk = eatk * (unknown value) / 100;
+ if( skill_id != ASC_METEORASSAULT ){
+ if( sc && sc->data[SC_SUB_WEAPONPROPERTY] ) // Temporary. [malufett]
+ damage += damage * sc->data[SC_SUB_WEAPONPROPERTY]->val2 / 100;
}
- */
- if( sc && sc->data[SC_WATK_ELEMENT] )
- damage = damage + eatk;
- else
- damage = battle->calc_elefix(src, bl, skill_id, skill_lv, damage + eatk, nk, n_ele, s_ele, s_ele_, false, flag);
-
+ // Temporary. [malufett]
+ damage = battle->calc_elefix(src, bl, skill_id, skill_lv, damage, nk, n_ele, s_ele, s_ele_, type == EQI_HAND_L, flag);
+
/**
* In RE Shield Bommerang takes weapon element only for damage calculation,
* - resist calculation is always against neutral
@@ -468,11 +464,12 @@ int battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, uin
if ( skill_id == CR_SHIELDBOOMERANG )
s_ele = s_ele_ = ELE_NEUTRAL;
- if( type == EQI_HAND_R )
- damage = battle->calc_cardfix(BF_WEAPON, src, bl, nk, s_ele, s_ele_, damage, 2, flag2);
- else
- damage = battle->calc_cardfix(BF_WEAPON, src, bl, nk, s_ele, s_ele_, damage, 3, flag2);
+ // attacker side
+ damage = battle->calc_cardfix(BF_WEAPON, src, bl, nk, s_ele, s_ele_, damage, 2|(type == EQI_HAND_L), flag2);
+ // target side
+ damage = battle->calc_cardfix(BF_WEAPON, src, bl, nk, s_ele, s_ele_, damage, 0, flag2);
+
return damage;
}
#endif
@@ -488,18 +485,13 @@ int battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, uin
* &8: Skip target size adjustment (Extremity Fist?)
*&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)
*/
-
#ifdef RENEWAL
int 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)
{
int damage, batk;
- struct status_change *sc = status_get_sc(src);
struct status_data *status = status_get_status_data(src);
- if( sc && sc->data[SC_TK_SEVENWIND] && !sc->data[SC_WATK_ELEMENT] )
- batk = battle->calc_elefix(src, bl, skill_id, skill_lv, status->batk, nk, n_ele, s_ele, s_ele_, false, flag);
- else
- batk = status->batk;
+ batk = battle->calc_elefix(src, bl, skill_id, skill_lv, status_calc_batk(bl, status_get_sc(src), status->batk, false), nk, n_ele, ELE_NEUTRAL, ELE_NEUTRAL, false, flag);
if( type == EQI_HAND_L )
damage = batk + 3 * battle->calc_weapon_damage(src, bl, skill_id, skill_lv, &status->lhw, nk, n_ele, s_ele, s_ele_, status_get_size(bl), type, flag, flag2) / 4;
@@ -732,13 +724,19 @@ int battle_calc_masteryfix(struct block_list *src, struct block_list *target, ui
case CR_ACIDDEMONSTRATION:
return damage;
case NJ_SYURIKEN:
- if( (skill = pc->checkskill(sd,NJ_TOBIDOUGU)) > 0 && weapon )
+ if( (skill = pc->checkskill(sd,NJ_TOBIDOUGU)) > 0
+#ifndef RENEWAL
+ && weapon
+#endif
+ )
damage += 3 * skill;
break;
+#ifndef RENEWAL
case NJ_KUNAI:
if( weapon )
damage += 60;
break;
+#endif
case RA_WUGDASH:
case RA_WUGSTRIKE:
case RA_WUGBITE:
@@ -816,35 +814,26 @@ int battle_calc_elefix(struct block_list *src, struct block_list *target, uint16
damage += battle_attr_fix(src,target,50*skill_lv,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
}
}
- if( sc && sc->data[SC_WATK_ELEMENT] )
- { // Descriptions indicate this means adding a percent of a normal attack in another element. [Skotlex]
- damage =
#ifndef RENEWAL
- battle->calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, ((TBL_PC*)src), (flag?2:0))
-#else
- battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, (flag?2:0)|(sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), 0)
-#endif
- * sc->data[SC_WATK_ELEMENT]->val2 / 100;
-
- damage += battle->attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
+ if( sc && sc->data[SC_SUB_WEAPONPROPERTY] )
+ { // Descriptions indicate this means adding a percent of a normal attack in another element. [Skotlex]
+ damage = battle->calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, BL_CAST(BL_PC, src), (flag?2:0)) * sc->data[SC_SUB_WEAPONPROPERTY]->val2 / 100;
+ damage += battle->attr_fix(src, target, damage, sc->data[SC_SUB_WEAPONPROPERTY]->val1, tstatus->def_ele, tstatus->ele_lv);
if( left ){
- damage =
-#ifndef RENEWAL
- battle->calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, ((TBL_PC*)src), (flag?2:0))
-#else
- battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_L, (flag?2:0)|(sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), 0)
-#endif
- * sc->data[SC_WATK_ELEMENT]->val2 / 100;
- damage += battle->attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
+ damage = battle->calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, BL_CAST(BL_PC, src), (flag?2:0)) * sc->data[SC_SUB_WEAPONPROPERTY]->val2 / 100;
+ damage += battle->attr_fix(src, target, damage, sc->data[SC_SUB_WEAPONPROPERTY]->val1, tstatus->def_ele, tstatus->ele_lv);
}
}
-
+#endif
return damage;
}
/*==========================================
* Calculates card bonuses damage adjustments.
+ * cflag(cardfix flag):
+ * &1 - calc for left hand.
+ * &2 - atker side cardfix(BF_WEAPON) otherwise target side(BF_WEAPON).
*------------------------------------------*/
-int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int damage, int left, int flag){
+int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int damage, int cflag, int wflag){
struct map_session_data *sd, *tsd;
short cardfix = 1000, t_class, s_class, s_race2, t_race2;
struct status_data *sstatus, *tstatus;
@@ -863,19 +852,19 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
sstatus = status_get_status_data(src);
tstatus = status_get_status_data(target);
s_race2 = status_get_race2(src);
-
+
switch(attack_type){
case BF_MAGIC:
if ( sd && !(nk&NK_NO_CARDFIX_ATK) ) {
- cardfix=cardfix*(100+sd->magic_addrace[tstatus->race])/100;
+ cardfix = cardfix * (100 + sd->magic_addrace[tstatus->race]) / 100;
if (!(nk&NK_NO_ELEFIX))
- cardfix=cardfix*(100+sd->magic_addele[tstatus->def_ele])/100;
- cardfix=cardfix*(100+sd->magic_addsize[tstatus->size])/100;
- cardfix=cardfix*(100+sd->magic_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS])/100;
- cardfix=cardfix*(100+sd->magic_atk_ele[s_ele])/100;
- for(i=0; i< ARRAYLENGTH(sd->add_mdmg) && sd->add_mdmg[i].rate;i++) {
+ cardfix = cardfix*(100+sd->magic_addele[tstatus->def_ele]) / 100;
+ cardfix = cardfix * (100 + sd->magic_addsize[tstatus->size]) / 100;
+ cardfix = cardfix * (100 + sd->magic_addrace[is_boss(target)?RC_BOSS:RC_NONBOSS]) / 100;
+ cardfix = cardfix * (100 + sd->magic_atk_ele[s_ele])/100;
+ for(i=0; i< ARRAYLENGTH(sd->add_mdmg) && sd->add_mdmg[i].rate; i++) {
if(sd->add_mdmg[i].class_ == t_class) {
- cardfix=cardfix*(100+sd->add_mdmg[i].rate)/100;
+ cardfix = cardfix * (100 + sd->add_mdmg[i].rate) / 100;
break;
}
}
@@ -891,29 +880,29 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
{
if(tsd->subele2[i].ele != s_ele) continue;
- if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&flag&BF_RANGEMASK &&
- tsd->subele2[i].flag&flag&BF_SKILLMASK))
+ if(!(tsd->subele2[i].flag&wflag&BF_WEAPONMASK &&
+ tsd->subele2[i].flag&wflag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&wflag&BF_SKILLMASK))
continue;
ele_fix += tsd->subele2[i].rate;
}
- cardfix=cardfix*(100-ele_fix)/100;
+ cardfix = cardfix * (100 - ele_fix) / 100;
}
- cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
- 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;
+ cardfix = cardfix * (100 - tsd->subsize[sstatus->size]) / 100;
+ 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;
+ 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) {
- cardfix=cardfix*(100-tsd->add_mdef[i].rate)/100;
+ cardfix = cardfix * (100-tsd->add_mdef[i].rate) / 100;
break;
}
}
//It was discovered that ranged defense also counts vs magic! [Skotlex]
- if ( flag&BF_SHORT )
+ if ( wflag&BF_SHORT )
cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
else
cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
@@ -923,78 +912,78 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
if( tsd->sc.data[SC_PROTECT_MDEF] )
cardfix = cardfix * ( 100 - tsd->sc.data[SC_PROTECT_MDEF]->val1 ) / 100;
- if (cardfix != 1000)
+ if( cardfix != 1000 )
damage = damage * cardfix / 1000;
}
break;
case BF_WEAPON:
t_race2 = status_get_race2(target);
- if( sd && !(nk&NK_NO_CARDFIX_ATK) && (left&2) )
+ if( cflag&2 && sd && !(nk&NK_NO_CARDFIX_ATK) )
{
short cardfix_ = 1000;
if(sd->state.arrow_atk)
{
- cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race]+sd->arrow_addrace[tstatus->race])/100;
+ cardfix = cardfix * (100 + sd->right_weapon.addrace[tstatus->race] + sd->arrow_addrace[tstatus->race]) / 100;
if (!(nk&NK_NO_ELEFIX))
{
int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->arrow_addele[tstatus->def_ele];
for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if(!(sd->right_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
- sd->right_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
- sd->right_weapon.addele2[i].flag&flag&BF_SKILLMASK))
+ if(!(sd->right_weapon.addele2[i].flag&wflag&BF_WEAPONMASK &&
+ sd->right_weapon.addele2[i].flag&wflag&BF_RANGEMASK &&
+ sd->right_weapon.addele2[i].flag&wflag&BF_SKILLMASK))
continue;
ele_fix += sd->right_weapon.addele2[i].rate;
}
- cardfix=cardfix*(100+ele_fix)/100;
+ cardfix = cardfix * (100 + ele_fix) / 100;
}
- 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;
+ 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;
+ 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;
+ cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race])/100;
if (!(nk&NK_NO_ELEFIX)) {
int ele_fix = sd->right_weapon.addele[tstatus->def_ele];
for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if(!(sd->right_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
- sd->right_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
- sd->right_weapon.addele2[i].flag&flag&BF_SKILLMASK))
+ if(!(sd->right_weapon.addele2[i].flag&wflag&BF_WEAPONMASK &&
+ sd->right_weapon.addele2[i].flag&wflag&BF_RANGEMASK &&
+ sd->right_weapon.addele2[i].flag&wflag&BF_SKILLMASK))
continue;
ele_fix += sd->right_weapon.addele2[i].rate;
}
- cardfix=cardfix*(100+ele_fix)/100;
+ cardfix = cardfix * (100+ele_fix) / 100;
}
- 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;
+ 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;
+ cardfix = cardfix * (100 + sd->right_weapon.addrace[RC_NONDEMIHUMAN]) / 100;
- if( left&1 )
+ if( cflag&1 )
{
- cardfix_=cardfix_*(100+sd->left_weapon.addrace[tstatus->race])/100;
+ cardfix_=cardfix_*(100+sd->left_weapon.addrace[tstatus->race])/100;
if (!(nk&NK_NO_ELEFIX)) {
- int ele_fix_lh = sd->left_weapon.addele[tstatus->def_ele];
+ int ele_fix_lh = sd->left_weapon.addele[tstatus->def_ele];
for (i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++) {
if (sd->left_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if(!(sd->left_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
- sd->left_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
- sd->left_weapon.addele2[i].flag&flag&BF_SKILLMASK))
+ if(!(sd->left_weapon.addele2[i].flag&wflag&BF_WEAPONMASK &&
+ sd->left_weapon.addele2[i].flag&wflag&BF_RANGEMASK &&
+ sd->left_weapon.addele2[i].flag&wflag&BF_SKILLMASK))
continue;
ele_fix_lh += sd->left_weapon.addele2[i].rate;
}
- cardfix=cardfix*(100+ele_fix_lh)/100;
+ cardfix = cardfix * (100+ele_fix_lh) / 100;
}
- 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;
+ 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;
}
@@ -1002,114 +991,122 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
else
{
int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[tstatus->def_ele];
- for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
+ for (i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++) {
if (sd->right_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if(!(sd->right_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
- sd->right_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
- sd->right_weapon.addele2[i].flag&flag&BF_SKILLMASK))
+ if(!(sd->right_weapon.addele2[i].flag&wflag&BF_WEAPONMASK &&
+ sd->right_weapon.addele2[i].flag&wflag&BF_RANGEMASK &&
+ sd->right_weapon.addele2[i].flag&wflag&BF_SKILLMASK))
continue;
ele_fix += sd->right_weapon.addele2[i].rate;
}
for (i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++) {
if (sd->left_weapon.addele2[i].ele != tstatus->def_ele) continue;
- if(!(sd->left_weapon.addele2[i].flag&flag&BF_WEAPONMASK &&
- sd->left_weapon.addele2[i].flag&flag&BF_RANGEMASK &&
- sd->left_weapon.addele2[i].flag&flag&BF_SKILLMASK))
+ if(!(sd->left_weapon.addele2[i].flag&wflag&BF_WEAPONMASK &&
+ sd->left_weapon.addele2[i].flag&wflag&BF_RANGEMASK &&
+ sd->left_weapon.addele2[i].flag&wflag&BF_SKILLMASK))
continue;
ele_fix += sd->left_weapon.addele2[i].rate;
}
- cardfix=cardfix*(100+sd->right_weapon.addrace[tstatus->race]+sd->left_weapon.addrace[tstatus->race])/100;
- cardfix=cardfix*(100+ele_fix)/100;
- 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;
+ cardfix = cardfix * (100 + sd->right_weapon.addrace[tstatus->race] + sd->left_weapon.addrace[tstatus->race]) / 100;
+ cardfix = cardfix * (100 + ele_fix) / 100;
+ 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;
+ cardfix = cardfix * (100+sd->right_weapon.addrace[RC_NONDEMIHUMAN] + sd->left_weapon.addrace[RC_NONDEMIHUMAN]) / 100;
}
}
+
for( i = 0; i < ARRAYLENGTH(sd->right_weapon.add_dmg) && sd->right_weapon.add_dmg[i].rate; i++ )
{
if( sd->right_weapon.add_dmg[i].class_ == t_class )
{
- cardfix=cardfix*(100+sd->right_weapon.add_dmg[i].rate)/100;
+ cardfix = cardfix * (100 + sd->right_weapon.add_dmg[i].rate) / 100;
break;
}
}
- if( left&1 )
+ if( cflag&1 )
{
for( i = 0; i < ARRAYLENGTH(sd->left_weapon.add_dmg) && sd->left_weapon.add_dmg[i].rate; i++ )
{
if( sd->left_weapon.add_dmg[i].class_ == t_class )
{
- cardfix_=cardfix_*(100+sd->left_weapon.add_dmg[i].rate)/100;
+ cardfix_ = cardfix_ * (100 + sd->left_weapon.add_dmg[i].rate) / 100;
break;
}
}
}
- if( flag&BF_LONG )
- cardfix = cardfix * ( 100 + sd->bonus.long_attack_atk_rate ) / 100;
- if( (left&1) && cardfix_ != 1000 )
+ if( wflag&BF_LONG )
+ cardfix = cardfix * (100 + sd->bonus.long_attack_atk_rate) / 100;
+
+ if( (cflag&1) && cardfix_ != 1000 )
damage = damage * cardfix_ / 1000;
else if( cardfix != 1000 )
damage = damage * cardfix / 1000;
- }else if( tsd && !(nk&NK_NO_CARDFIX_DEF) ){
- if( !(nk&NK_NO_ELEFIX) )
+ break; // end Attacker side
+ }
+ // Target side
+ if( tsd && !(nk&NK_NO_CARDFIX_DEF) )
{
- int ele_fix = tsd->subele[s_ele];
- for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
- {
- if(tsd->subele2[i].ele != s_ele) continue;
- if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&flag&BF_RANGEMASK &&
- tsd->subele2[i].flag&flag&BF_SKILLMASK))
- continue;
- ele_fix += tsd->subele2[i].rate;
- }
- cardfix=cardfix*(100-ele_fix)/100;
- if( left&1 && s_ele_ != s_ele )
+ if( !(nk&NK_NO_ELEFIX) )
{
- int ele_fix_lh = tsd->subele[s_ele_];
+ int ele_fix = tsd->subele[s_ele];
for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
{
- if(tsd->subele2[i].ele != s_ele_) continue;
- if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&flag&BF_RANGEMASK &&
- tsd->subele2[i].flag&flag&BF_SKILLMASK))
+ if(tsd->subele2[i].ele != s_ele) continue;
+ if(!(tsd->subele2[i].flag&wflag&BF_WEAPONMASK &&
+ tsd->subele2[i].flag&wflag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&wflag&BF_SKILLMASK))
continue;
- ele_fix_lh += tsd->subele2[i].rate;
+ ele_fix += tsd->subele2[i].rate;
+ }
+ cardfix=cardfix*(100-ele_fix)/100;
+ if( cflag&1 && s_ele_ != s_ele )
+ {
+ int ele_fix_lh = tsd->subele[s_ele_];
+ for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
+ {
+ if(tsd->subele2[i].ele != s_ele_) continue;
+ if(!(tsd->subele2[i].flag&wflag&BF_WEAPONMASK &&
+ tsd->subele2[i].flag&wflag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&wflag&BF_SKILLMASK))
+ continue;
+ ele_fix_lh += tsd->subele2[i].rate;
+ }
+ cardfix = cardfix * (100 - ele_fix_lh) / 100;
}
- cardfix=cardfix*(100-ele_fix_lh)/100;
}
- }
- cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
- 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;
+ cardfix = cardfix * (100-tsd->subsize[sstatus->size]) / 100;
+ 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 ) {
- cardfix=cardfix*(100-tsd->add_def[i].rate)/100;
- break;
+ for( i = 0; i < ARRAYLENGTH(tsd->add_def) && tsd->add_def[i].rate;i++ )
+ {
+ if( tsd->add_def[i].class_ == s_class )
+ {
+ cardfix = cardfix * (100 - tsd->add_def[i].rate) / 100;
+ break;
+ }
}
- }
- if( flag&BF_SHORT )
- cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
- else // BF_LONG (there's no other choice)
- cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
+ if( wflag&BF_SHORT )
+ cardfix = cardfix * (100 - tsd->bonus.near_attack_def_rate) / 100;
+ else // BF_LONG (there's no other choice)
+ cardfix = cardfix * (100 - tsd->bonus.near_attack_def_rate) / 100;
- if( tsd->sc.data[SC_PROTECT_DEF] )
- cardfix = cardfix * ( 100 - tsd->sc.data[SC_PROTECT_DEF]->val1 ) / 100;
+ if( tsd->sc.data[SC_PROTECT_DEF] )
+ cardfix = cardfix * (100 - tsd->sc.data[SC_PROTECT_DEF]->val1) / 100;
- if( cardfix != 1000 )
- damage = damage * cardfix / 1000;
- }
+ if( cardfix != 1000 )
+ damage = damage * cardfix / 1000;
+ }
break;
case BF_MISC:
if( tsd && !(nk&NK_NO_CARDFIX_DEF) ){
@@ -1120,25 +1117,25 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
for (i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++)
{
if(tsd->subele2[i].ele != s_ele) continue;
- if(!(tsd->subele2[i].flag&flag&BF_WEAPONMASK &&
- tsd->subele2[i].flag&flag&BF_RANGEMASK &&
- tsd->subele2[i].flag&flag&BF_SKILLMASK))
+ if(!(tsd->subele2[i].flag&wflag&BF_WEAPONMASK &&
+ tsd->subele2[i].flag&wflag&BF_RANGEMASK &&
+ tsd->subele2[i].flag&wflag&BF_SKILLMASK))
continue;
ele_fix += tsd->subele2[i].rate;
}
- cardfix=cardfix*(100-ele_fix)/100;
+ cardfix = cardfix * (100 - ele_fix) / 100;
}
- cardfix=cardfix*(100-tsd->subsize[sstatus->size])/100;
- 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;
+ cardfix = cardfix*(100-tsd->subsize[sstatus->size]) / 100;
+ 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;
+ cardfix = cardfix * (100 - tsd->subrace[RC_NONDEMIHUMAN]) / 100;
cardfix = cardfix * ( 100 - tsd->bonus.misc_def_rate ) / 100;
- if( flag&BF_SHORT )
+ if( wflag&BF_SHORT )
cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100;
- else // BF_LONG (there's no other choice)
+ else // BF_LONG (there's no other choice)
cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
if (cardfix != 1000)
@@ -1260,12 +1257,12 @@ int battle_calc_defense(int attack_type, struct block_list *src, struct block_li
#ifdef RENEWAL
/**
* RE DEF Reduction
- * Damage = Attack * (4000+eDEF)/(4000+eDEF*10) - sDEF
* Pierce defence gains 1 atk per def/2
**/
- if( def1 == -400 ) /* being hit by a gazillion units, you hit the jackpot and got -400 which creates a division by 0 and subsequently crashes */
- def1 = -399;
+ if( def1 < -399 ) // it stops at -399
+ def1 = 399; // in aegis it set to 1 but in our case it may lead to exploitation so limit it to 399
+ //return 1;
if( flag&2 )
damage += def1 >> 1;
@@ -1274,7 +1271,7 @@ int battle_calc_defense(int attack_type, struct block_list *src, struct block_li
if( flag&4 )
damage -= (def1 + vit_def);
else
- damage = damage * (4000+def1) / (4000+10*def1) - vit_def;
+ damage = (int)((100.0f - def1 / (def1 + 400.0f) * 90.0f) / 100.0f * damage - vit_def);
}
#else
@@ -1318,9 +1315,12 @@ int battle_calc_defense(int attack_type, struct block_list *src, struct block_li
#ifdef RENEWAL
/**
* RE MDEF Reduction
- * Damage = Magic Attack * (1000+eMDEF)/(1000+eMDEF) - sMDEF
**/
- damage = damage * (1000 + mdef) / (1000 + mdef * 10) - mdef2;
+ if( mdef < -99 ) // it stops at -99
+ mdef = 99; // in aegis it set to 1 but in our case it may lead to exploitation so limit it to 99
+ //return 1;
+
+ damage = (int)((100.0f - mdef / (mdef + 100.0f) * 90.0f) / 100.0f * damage - mdef2);
#else
if(battle_config.magic_defense_type)
damage = damage - mdef*battle_config.magic_defense_type - mdef2;
@@ -1489,7 +1489,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
skillratio += 300 + 100 * skill_lv + status_get_int(src);
RE_LVL_DMOD(100);
break;
- case WL_FROSTMISTY: // MATK [{( Skill Level x 100 ) + 200 } x ( Caster’s Base Level / 100 )] %
+ case WL_FROSTMISTY: // MATK [{( Skill Level x 100 ) + 200 } x ( Caster�s Base Level / 100 )] %
skillratio += 100 + 100 * skill_lv;
RE_LVL_DMOD(100);
break;
@@ -1975,7 +1975,12 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
skillratio += 100 * (skill_lv+1);
break;
case GS_PIERCINGSHOT:
- skillratio += 20 * skill_lv;
+#ifdef RENEWAL
+ if( sd && sd->weapontype1 == W_RIFLE )
+ skillratio += 50 + 30 * skill_lv;
+ else
+#endif
+ skillratio += 20 * skill_lv;
break;
case GS_RAPIDSHOWER:
skillratio += 10 * skill_lv;
@@ -2008,6 +2013,11 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
case NJ_KIRIKAGE:
skillratio += 100 * (skill_lv-1);
break;
+#ifdef RENEWAL
+ case NJ_KUNAI:
+ skillratio += 50 + 150 * skill_lv;
+ break;
+#endif
case KN_CHARGEATK:
{
int k = (flag-1)/3; //+100% every 3 cells of distance
@@ -2070,7 +2080,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
}
break;
case RK_STORMBLAST:
- skillratio += -100 + 100 * (sd ? pc->checkskill(sd,RK_RUNEMASTERY) : 1) + 100 * (status_get_int(src) / 4);
+ skillratio += -100 + 100 *(sd ? pc->checkskill(sd,RK_RUNEMASTERY) : 1) + status_get_int(src) / 8;
break;
case RK_PHANTOMTHRUST:
skillratio += -100 + 50 * skill_lv + 10 * ( sd ? pc->checkskill(sd,KN_SPEARMASTERY) : 10);
@@ -2090,7 +2100,6 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
//ATK [{(Skill Level x 100) + 300} x Caster's Base Level / 120]% + ATK [(AGI x 2) + (Caster's Job Level x 4)]%
skillratio += 200 + (100 * skill_lv);
RE_LVL_DMOD(120);
- skillratio += status_get_agi(src) * 2 + (sd?sd->status.job_level:0) * 4;
break;
case GC_ROLLINGCUTTER:
skillratio += -50 + 50 * skill_lv;
@@ -3439,7 +3448,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
ad.damage = 0;
}
}
-
#ifndef RENEWAL
ad.damage = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
#endif
@@ -3585,7 +3593,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
case PA_GOSPEL:
md.damage = 1+rnd()%9999;
break;
- case CR_ACIDDEMONSTRATION:
+ case CR_ACIDDEMONSTRATION:
#ifdef RENEWAL
{// [malufett]
int matk=0, atk;
@@ -4338,12 +4346,18 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
//Adds an absolute value to damage. 100 = +100 damage
#define ATK_ADD( a ) { wd.damage+= a; if (flag.lh) wd.damage2+= a; }
#define ATK_ADD2( a , b ) { wd.damage+= a; if (flag.lh) wd.damage2+= b; }
-
+#ifdef RENEWAL
+#define GET_NORMAL_ATTACK( f ) { wd.damage = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, f, wd.flag); }
+#define GET_NORMAL_ATTACK2( f ) { wd.damage2 = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_L, f, wd.flag); }
+#endif
switch (skill_id)
{ //Calc base damage according to skill
case PA_SACRIFICE:
wd.damage = sstatus->max_hp* 9/100;
wd.damage2 = 0;
+#ifdef RENEWAL
+ wd.damage = battle->calc_elefix(src, target, skill_id, skill_lv, wd.damage, nk, n_ele, s_ele, s_ele_, false, wd.flag); // temporary [malufett]
+#endif
break;
case NJ_ISSEN: // [malufett]
#ifndef RENEWAL
@@ -4353,21 +4367,29 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
{
short totaldef = status_get_total_def(target);
i = 0;
- wd.damage = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), wd.flag);
+ GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) );
if( sc && sc->data[SC_NJ_BUNSINJYUTSU] && (i=sc->data[SC_NJ_BUNSINJYUTSU]->val2) > 0 )
wd.div_ = ~( i++ + 2 ) + 1;
- wd.damage *= sstatus->hp * skill_lv;
- wd.damage = wd.damage / sstatus->max_hp + sstatus->hp + i * (wd.damage / sstatus->max_hp + sstatus->hp) / 5;
+ if( wd.damage ){
+ wd.damage *= sstatus->hp * skill_lv;
+ wd.damage = wd.damage / sstatus->max_hp + sstatus->hp + i * (wd.damage / sstatus->max_hp + sstatus->hp) / 5;
+ }
ATK_ADD(-totaldef);
if( is_boss(target) )
ATK_RATE(50);
flag.idef = 1;
}
break;
+ case NJ_SYURIKEN: // [malufett]
+ GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) );
+ wd.damage += battle->calc_masteryfix(src, target, skill_id, skill_lv, 4 * skill_lv + (sd ? sd->bonus.arrow_atk : 0), wd.div_, 0, flag.weapon) - status_get_total_def(target);
+ flag.idef = 1;
+ break;
case MO_EXTREMITYFIST: // [malufett]
- wd.damage = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|8, wd.flag);
+ GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|8 );
// first value is still not confirm.
- wd.damage = status_get_sp(src) + 10 * status_get_sp(src) * wd.damage / 100 + 8 * wd.damage;
+ if( wd.damage )
+ wd.damage = status_get_sp(src) + 10 * status_get_sp(src) * wd.damage / 100 + 8 * wd.damage + 250 + 150 * skill_lv;
flag.tdef = 1;
#endif
break;
@@ -4445,10 +4467,10 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
i |= 16; // for ex. shuriken must not be influenced by DEX
}
#ifdef RENEWAL
- wd.damage = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, i, wd.flag);
+ GET_NORMAL_ATTACK( i );
wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon);
if (flag.lh){
- wd.damage2 = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_L, i, wd.flag);
+ GET_NORMAL_ATTACK2( i );
wd.damage2 = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage2, wd.div_, 1, flag.weapon);
}
#else
@@ -4500,6 +4522,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if( sc->data[SC_UNLIMIT] && wd.flag&BF_LONG )
ATK_ADD( 50 * sc->data[SC_UNLIMIT]->val1 );
}
+
if( tsc && skill_id != PA_SACRIFICE ){
if( tsc->data[SC_DARKCROW] && wd.flag&BF_SHORT )
ATK_ADD( 30 * tsc->data[SC_DARKCROW]->val1 );
@@ -4511,6 +4534,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
else
{
+
+ #ifdef RENEWAL
+ if( sd && skill_id == NJ_KUNAI ){
+ flag.tdef = 1;
+ ATK_ADD( sd->bonus.arrow_atk );
+ }
+ #endif
switch(skill_id){
#ifdef RENEWAL
case LK_SPIRALPIERCE:
@@ -4535,13 +4565,14 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
//Constant/misc additions from skills
switch (skill_id) {
- case MO_EXTREMITYFIST:
- ATK_ADD(250 + 150*skill_lv);
- break;
#ifdef RENEWAL
case HW_MAGICCRASHER:
ATK_ADD(battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag).damage / 5);
break;
+#else
+ case MO_EXTREMITYFIST:
+ ATK_ADD(250 + 150*skill_lv);
+ break;
#endif
case TK_DOWNKICK:
case TK_STORMKICK:
@@ -4559,8 +4590,10 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
ATK_ADD( battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag).damage );
flag.tdef = 1;
#endif
+#ifndef RENEWAL
case NJ_SYURIKEN:
ATK_ADD(4*skill_lv);
+#endif
break;
case HT_FREEZINGTRAP:
if(sd)
@@ -4570,6 +4603,9 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if( sd && sd->weight )
ATK_ADD( sd->weight / 8 );
break;
+ case GC_COUNTERSLASH:
+ ATK_ADD( status_get_agi(src) * 2 + (sd?sd->status.job_level:0) * 4 );
+ break;
case SR_TIGERCANNON: // (Tiger Cannon skill level x 240) + (Target Base Level x 40)
ATK_ADD( skill_lv * 240 + status_get_lv(target) * 40 );
if( sc && sc->data[SC_COMBOATTACK]
@@ -4611,18 +4647,20 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
skill_id == LG_SHIELDPRESS || skill_id == RK_HUNDREDSPEAR ||
skill_id == CR_SHIELDCHARGE ) )
ATK_ADDRATE(sc->data[SC_GLOOMYDAY_SK]->val2);
+
+#ifndef RENEWAL_EDP
if( sc->data[SC_EDP] ){
switch(skill_id){
-#ifndef RENEWAL_EDP
- case AS_SPLASHER: case AS_VENOMKNIFE:
+ case AS_SPLASHER:
case AS_GRIMTOOTH:
- break;
+ case ASC_BREAKER:
+ case AS_VENOMKNIFE:
case ASC_METEORASSAULT: break;
default:
ATK_ADDRATE(sc->data[SC_EDP]->val3);
-#endif
}
}
+#endif
if(sc->data[SC_STYLE_CHANGE]){
TBL_HOM *hd = BL_CAST(BL_HOM,src);
if (hd) ATK_ADD(hd->homunculus.spiritball * 3);
@@ -4799,6 +4837,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
}
#endif
+
#ifndef RENEWAL
if (sd) {
if (skill_id != CR_SHIELDBOOMERANG) //Only Shield boomerang doesn't takes the Star Crumbs bonus.
@@ -4825,9 +4864,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
//Card Fix, tsd side
if(tsd){ //if player on player then it was already measured above
- wd.damage = battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, 2, wd.flag);
- if( flag.lh )
- wd.damage2 = battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage2, 3, wd.flag);
+ wd.damage = battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, (flag.lh?1:0), wd.flag);
}
#endif
if( flag.infdef ) { //Plants receive 1 damage when hit
@@ -5763,6 +5800,9 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
case ASC_METEORASSAULT:
case RG_RAID:
case MC_CARTREVOLUTION:
+ case HT_CLAYMORETRAP:
+ case RA_ICEBOUNDTRAP:
+ case RA_FIRINGTRAP:
#endif
state |= BCT_ENEMY;
strip_enemy = 0;
@@ -6285,7 +6325,6 @@ static const struct _battle_data {
{ "mobs_level_up_exp_rate", &battle_config.mobs_level_up_exp_rate, 1, 1, INT_MAX, },
{ "pk_min_level", &battle_config.pk_min_level, 55, 1, INT_MAX, },
{ "skill_steal_max_tries", &battle_config.skill_steal_max_tries, 0, 0, UCHAR_MAX, },
- { "finding_ore_rate", &battle_config.finding_ore_rate, 100, 0, INT_MAX, },
{ "exp_calc_type", &battle_config.exp_calc_type, 0, 0, 1, },
{ "exp_bonus_attacker", &battle_config.exp_bonus_attacker, 25, 0, INT_MAX, },
{ "exp_bonus_max_attacker", &battle_config.exp_bonus_max_attacker, 12, 2, INT_MAX, },
@@ -6537,14 +6576,14 @@ void Hercules_report(char* date, char *time_c) {
WBUFL(buf,6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + BFLAG_LENGTH + ( i * ( BFLAG_LENGTH + 4 ) ) ) = *battle_data[i].val;
}
- chrif_send_report(buf, 6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) );
+ chrif->send_report(buf, 6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) );
aFree(buf);
#undef BFLAG_LENGTH
}
static int Hercules_report_timer(int tid, unsigned int tick, int id, intptr_t data) {
- if( chrif_isconnected() ) {/* char server relays it, so it must be online. */
+ if( chrif->isconnected() ) {/* char server relays it, so it must be online. */
Hercules_report(__DATE__,__TIME__);
}
return 0;
diff --git a/src/map/battle.h b/src/map/battle.h
index 7d41a02c5..37968f53a 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -325,7 +325,6 @@ struct Battle_Config {
int mobs_level_up_exp_rate; // [Valaris]
int pk_min_level; // [celest]
int skill_steal_max_tries; //max steal skill tries on a mob. if 0, then w/o limit [Lupus]
- int finding_ore_rate; // orn
int exp_calc_type;
int exp_bonus_attacker;
int exp_bonus_max_attacker;
diff --git a/src/map/battleground.c b/src/map/battleground.c
index 64bc25269..88cc323bf 100644
--- a/src/map/battleground.c
+++ b/src/map/battleground.c
@@ -420,9 +420,20 @@ int bg_id2pos ( int queue_id, int account_id ) {
}
return 0;
}
+void bg_queue_ready_ack (struct bg_arena *arena, struct map_session_data *sd, bool response) {
+ if( arena->begin_timer == INVALID_TIMER || !sd->bg_queue.arena || sd->bg_queue.arena != arena ) {
+ bg->queue_pc_cleanup(sd);
+ return;
+ }
+ if( response ) {
+ sd->bg_queue.ready = 1;
+ /* check if all are ready then cancell timer, and start game */
+ } else
+ bg->queue_pc_cleanup(sd);
+}
void bg_queue_player_cleanup(struct map_session_data *sd) {
if ( sd->bg_queue.client_has_bg_data ) {
- clif->bgqueue_notice_delete(sd,BGQND_CLOSEWINDOW, sd->bg_queue.arena->id);
+ clif->bgqueue_notice_delete(sd,BGQND_CLOSEWINDOW, sd->bg_queue.arena ? sd->bg_queue.arena->id : 0);
}
script->queue_remove(sd->bg_queue.arena->queue_id,sd->status.account_id);
sd->bg_queue.arena = NULL;
@@ -726,6 +737,7 @@ void battleground_defaults(void) {
bg->begin_timer = bg_begin_timer;
bg->queue_pregame = bg_queue_pregame;
bg->fillup_timer = bg_fillup_timer;
+ bg->queue_ready_ack = bg_queue_ready_ack;
/* */
bg->config_read = bg_config_read;
}
diff --git a/src/map/battleground.h b/src/map/battleground.h
index 8fe9f3b77..030d13d90 100644
--- a/src/map/battleground.h
+++ b/src/map/battleground.h
@@ -96,6 +96,7 @@ struct battleground_interface {
int (*begin_timer) (int tid, unsigned int tick, int id, intptr_t data);
void (*queue_pregame) (struct bg_arena *arena);
int (*fillup_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ void (*queue_ready_ack) (struct bg_arena *arena, struct map_session_data *sd, bool response);
/* */
void (*config_read) (void);
} bg_s;
diff --git a/src/map/buyingstore.c b/src/map/buyingstore.c
index 764b51015..7041042df 100644
--- a/src/map/buyingstore.c
+++ b/src/map/buyingstore.c
@@ -137,7 +137,7 @@ void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
amount = RBUFW(itemlist,i*8+2);
price = RBUFL(itemlist,i*8+4);
- if( ( id = itemdb_exists(nameid) ) == NULL || amount == 0 )
+ if( ( id = itemdb->exists(nameid) ) == NULL || amount == 0 )
{// invalid input
break;
}
@@ -384,8 +384,8 @@ void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int
}
if( iMap->save_settings&128 ) {
- chrif_save(sd, 0);
- chrif_save(pl_sd, 0);
+ chrif->save(sd, 0);
+ chrif->save(pl_sd, 0);
}
// check whether or not there is still something to buy
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 6e076e6d8..9e8b18d3b 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -53,39 +53,39 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
//2af9: Incoming, chrif_connectack -> 'answer of the 2af8 login(ok / fail)'
//2afa: Outgoing, chrif_sendmap -> 'sending our maps'
//2afb: Incoming, chrif_sendmapack -> 'Maps received successfully / or not ..'
-//2afc: Outgoing, chrif_scdata_request -> request sc_data for pc->authok'ed char. <- new command reuses previous one.
-//2afd: Incoming, chrif_authok -> 'client authentication ok'
+//2afc: Outgoing, chrif->scdata_request -> request sc_data for pc->authok'ed char. <- new command reuses previous one.
+//2afd: Incoming, chrif->authok -> 'client authentication ok'
//2afe: Outgoing, send_usercount_tochar -> 'sends player count of this map server to charserver'
-//2aff: Outgoing, send_users_tochar -> 'sends all actual connected character ids to charserver'
+//2aff: Outgoing, chrif->send_users_tochar -> 'sends all actual connected character ids to charserver'
//2b00: Incoming, iMap->setusers -> 'set the actual usercount? PACKET.2B COUNT.L.. ?' (not sure)
-//2b01: Outgoing, chrif_save -> 'charsave of char XY account XY (complete struct)'
-//2b02: Outgoing, chrif_charselectreq -> 'player returns from ingame to charserver to select another char.., this packets includes sessid etc' ? (not 100% sure)
+//2b01: Outgoing, chrif->save -> 'charsave of char XY account XY (complete struct)'
+//2b02: Outgoing, chrif->charselectreq -> 'player returns from ingame to charserver to select another char.., this packets includes sessid etc' ? (not 100% sure)
//2b03: Incoming, clif_charselectok -> '' (i think its the packet after enterworld?) (not sure)
//2b04: Incoming, chrif_recvmap -> 'getting maps from charserver of other mapserver's'
-//2b05: Outgoing, chrif_changemapserver -> 'Tell the charserver the mapchange / quest for ok...'
+//2b05: Outgoing, chrif->changemapserver -> 'Tell the charserver the mapchange / quest for ok...'
//2b06: Incoming, chrif_changemapserverack -> 'awnser of 2b05, ok/fail, data: dunno^^'
-//2b07: Outgoing, chrif_removefriend -> 'Tell charserver to remove friend_id from char_id friend list'
-//2b08: Outgoing, chrif_searchcharid -> '...'
+//2b07: Outgoing, chrif->removefriend -> 'Tell charserver to remove friend_id from char_id friend list'
+//2b08: Outgoing, chrif->searchcharid -> '...'
//2b09: Incoming, map_addchariddb -> 'Adds a name to the nick db'
//2b0a: Incoming/Outgoing, socket_datasync()
//2b0b: Outgoing, update charserv skillid2idx
-//2b0c: Outgoing, chrif_changeemail -> 'change mail address ...'
+//2b0c: Outgoing, chrif->changeemail -> 'change mail address ...'
//2b0d: Incoming, chrif_changedsex -> 'Change sex of acc XY'
-//2b0e: Outgoing, chrif_char_ask_name -> 'Do some operations (change sex, ban / unban etc)'
+//2b0e: Outgoing, chrif->char_ask_name -> 'Do some operations (change sex, ban / unban etc)'
//2b0f: Incoming, chrif_char_ask_name_answer -> 'answer of the 2b0e'
-//2b10: Outgoing, chrif_updatefamelist -> 'Update the fame ranking lists and send them'
-//2b11: Outgoing, chrif_divorce -> 'tell the charserver to do divorce'
+//2b10: Outgoing, chrif->updatefamelist -> 'Update the fame ranking lists and send them'
+//2b11: Outgoing, chrif->divorce -> 'tell the charserver to do divorce'
//2b12: Incoming, chrif_divorceack -> 'divorce chars
//2b13: FREE
//2b14: Incoming, chrif_accountban -> 'not sure: kick the player with message XY'
//2b15: FREE
-//2b16: Outgoing, chrif_ragsrvinfo -> 'sends base / job / drop rates ....'
-//2b17: Outgoing, chrif_char_offline -> 'tell the charserver that the char is now offline'
-//2b18: Outgoing, chrif_char_reset_offline -> 'set all players OFF!'
-//2b19: Outgoing, chrif_char_online -> 'tell the charserver that the char .. is online'
-//2b1a: Outgoing, chrif_buildfamelist -> 'Build the fame ranking lists and send them'
+//2b16: Outgoing, chrif->ragsrvinfo -> 'sends base / job / drop rates ....'
+//2b17: Outgoing, chrif->char_offline -> 'tell the charserver that the char is now offline'
+//2b18: Outgoing, chrif->char_reset_offline -> 'set all players OFF!'
+//2b19: Outgoing, chrif->char_online -> 'tell the charserver that the char .. is online'
+//2b1a: Outgoing, chrif->buildfamelist -> 'Build the fame ranking lists and send them'
//2b1b: Incoming, chrif_recvfamelist -> 'Receive fame ranking lists'
-//2b1c: Outgoing, chrif_save_scdata -> 'Send sc_data of player for saving.'
+//2b1c: Outgoing, chrif->save_scdata -> 'Send sc_data of player for saving.'
//2b1d: Incoming, chrif_load_scdata -> 'received sc_data of player for loading.'
//2b1e: Incoming, chrif_update_ip -> 'Reqest forwarded from char-server for interserver IP sync.' [Lance]
//2b1f: Incoming, chrif_disconnectplayer -> 'disconnects a player (aid X) with the message XY ... 0x81 ..' [Sirius]
@@ -95,10 +95,9 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
//2b23: Outgoing, chrif_keepalive. charserver ping.
//2b24: Incoming, chrif_keepalive_ack. charserver ping reply.
//2b25: Incoming, chrif_deadopt -> 'Removes baby from Father ID and Mother ID'
-//2b26: Outgoing, chrif_authreq -> 'client authentication request'
+//2b26: Outgoing, chrif->authreq -> 'client authentication request'
//2b27: Incoming, chrif_authfail -> 'client authentication failed'
-int chrif_connected = 0;
int char_fd = -1;
int srvinfo;
static char char_ip_str[128];
@@ -106,14 +105,13 @@ static uint32 char_ip = 0;
static uint16 char_port = 6121;
static char userid[NAME_LENGTH], passwd[NAME_LENGTH];
static int chrif_state = 0;
-int other_mapserver_count=0; //Holds count of how many other map servers are online (apart of this instance) [Skotlex]
//Interval at which map server updates online listing. [Valaris]
#define CHECK_INTERVAL 3600000
//Interval at which map server sends number of connected users. [Skotlex]
#define UPDATE_INTERVAL 10000
//This define should spare writing the check in every function. [Skotlex]
-#define chrif_check(a) { if(!chrif_isconnected()) return a; }
+#define chrif_check(a) { if(!chrif->isconnected()) return a; }
/// Resets all the data.
@@ -139,7 +137,7 @@ struct auth_node* chrif_search(int account_id) {
}
struct auth_node* chrif_auth_check(int account_id, int char_id, enum sd_state state) {
- struct auth_node *node = chrif_search(account_id);
+ struct auth_node *node = chrif->search(account_id);
return ( node && node->char_id == char_id && node->state == state ) ? node : NULL;
}
@@ -147,7 +145,7 @@ struct auth_node* chrif_auth_check(int account_id, int char_id, enum sd_state st
bool chrif_auth_delete(int account_id, int char_id, enum sd_state state) {
struct auth_node *node;
- if ( (node = chrif_auth_check(account_id, char_id, state) ) ) {
+ if ( (node = chrif->auth_check(account_id, char_id, state) ) ) {
int fd = node->sd ? node->sd->fd : node->fd;
if ( session[fd] && session[fd]->session_data == node->sd )
@@ -171,7 +169,7 @@ bool chrif_auth_delete(int account_id, int char_id, enum sd_state state) {
static bool chrif_sd_to_auth(TBL_PC* sd, enum sd_state state) {
struct auth_node *node;
- if ( chrif_search(sd->status.account_id) )
+ if ( chrif->search(sd->status.account_id) )
return false; //Already exists?
node = ers_alloc(auth_db_ers, struct auth_node);
@@ -208,12 +206,12 @@ static bool chrif_auth_logout(TBL_PC* sd, enum sd_state state) {
}
bool chrif_auth_finished(TBL_PC* sd) {
- struct auth_node *node= chrif_search(sd->status.account_id);
+ struct auth_node *node= chrif->search(sd->status.account_id);
if ( node && node->sd == sd && node->state == ST_LOGIN ) {
node->sd = NULL;
- return chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
+ return chrif->auth_delete(node->account_id, node->char_id, ST_LOGIN);
}
return false;
@@ -276,8 +274,8 @@ int chrif_save(struct map_session_data *sd, int flag) {
if (flag && sd->state.active) { //Store player data which is quitting
//FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex]
- if ( chrif_isconnected() )
- chrif_save_scdata(sd);
+ if ( chrif->isconnected() )
+ chrif->save_scdata(sd);
if ( !chrif_auth_logout(sd,flag == 1 ? ST_LOGOUT : ST_MAPCHANGE) )
ShowError("chrif_save: Failed to set up player %d:%d for proper quitting!\n", sd->status.account_id, sd->status.char_id);
}
@@ -286,7 +284,7 @@ int chrif_save(struct map_session_data *sd, int flag) {
//For data sync
if (sd->state.storage_flag == 2)
- storage_guild_storagesave(sd->status.account_id, sd->status.guild_id, flag);
+ gstorage->save(sd->status.account_id, sd->status.guild_id, flag);
if (flag)
sd->state.storage_flag = 0; //Force close it.
@@ -367,7 +365,7 @@ int chrif_recvmap(int fd) {
if (battle_config.etc_log)
ShowStatus("Received maps from %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j);
- other_mapserver_count++;
+ chrif->other_mapserver_count++;
return 0;
}
@@ -381,7 +379,7 @@ int chrif_removemap(int fd) {
for(i = 10, j = 0; i < RFIFOW(fd, 2); i += 4, j++)
iMap->eraseipport(RFIFOW(fd, i), ip, port);
- other_mapserver_count--;
+ chrif->other_mapserver_count--;
if(battle_config.etc_log)
ShowStatus("remove map of server %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j);
@@ -391,15 +389,15 @@ int chrif_removemap(int fd) {
// received after a character has been "final saved" on the char-server
static void chrif_save_ack(int fd) {
- chrif_auth_delete(RFIFOL(fd,2), RFIFOL(fd,6), ST_LOGOUT);
- chrif_check_shutdown();
+ chrif->auth_delete(RFIFOL(fd,2), RFIFOL(fd,6), ST_LOGOUT);
+ chrif->check_shutdown();
}
// request to move a character between mapservers
int chrif_changemapserver(struct map_session_data* sd, uint32 ip, uint16 port) {
nullpo_retr(-1, sd);
- if (other_mapserver_count < 1) {//No other map servers are online!
+ if (chrif->other_mapserver_count < 1) {//No other map servers are online!
clif->authfail_fd(sd->fd, 0);
return -1;
}
@@ -430,7 +428,7 @@ int chrif_changemapserver(struct map_session_data* sd, uint32 ip, uint16 port) {
int chrif_changemapserverack(int account_id, int login_id1, int login_id2, int char_id, short map_index, short x, short y, uint32 ip, uint16 port) {
struct auth_node *node;
- if ( !( node = chrif_auth_check(account_id, char_id, ST_MAPCHANGE) ) )
+ if ( !( node = chrif->auth_check(account_id, char_id, ST_MAPCHANGE) ) )
return -1;
if ( !login_id1 ) {
@@ -440,7 +438,7 @@ int chrif_changemapserverack(int account_id, int login_id1, int login_id2, int c
clif->changemapserver(node->sd, map_index, x, y, ntohl(ip), ntohs(port));
//Player has been saved already, remove him from memory. [Skotlex]
- chrif_auth_delete(account_id, char_id, ST_MAPCHANGE);
+ chrif->auth_delete(account_id, char_id, ST_MAPCHANGE);
return 0;
}
@@ -458,7 +456,7 @@ int chrif_connectack(int fd) {
ShowStatus("Successfully logged on to Char Server (Connection: '"CL_WHITE"%d"CL_RESET"').\n",fd);
chrif_state = 1;
- chrif_connected = 1;
+ chrif->chrif_connected = 1;
chrif_sendmap(fd);
@@ -470,7 +468,7 @@ int chrif_connectack(int fd) {
}
socket_datasync(fd, true);
- chrif_skillid2idx(fd);
+ chrif->skillid2idx(fd);
return 0;
}
@@ -485,13 +483,13 @@ static int chrif_reconnect(DBKey key, DBData *data, va_list ap) {
case ST_LOGIN:
if ( node->sd && node->char_dat == NULL ) {//Since there is no way to request the char auth, make it fail.
pc->authfail(node->sd);
- chrif_char_offline(node->sd);
- chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
+ chrif->char_offline(node->sd);
+ chrif->auth_delete(node->account_id, node->char_id, ST_LOGIN);
}
break;
case ST_LOGOUT:
//Re-send final save
- chrif_save(node->sd, 1);
+ chrif->save(node->sd, 1);
break;
case ST_MAPCHANGE: { //Re-send map-change request.
struct map_session_data *sd = node->sd;
@@ -499,7 +497,7 @@ static int chrif_reconnect(DBKey key, DBData *data, va_list ap) {
uint16 port;
if( iMap->mapname2ipport(sd->mapindex,&ip,&port) == 0 )
- chrif_changemapserver(sd, ip, port);
+ chrif->changemapserver(sd, ip, port);
else //too much lag/timeout is the closest explanation for this error.
clif->authfail_fd(sd->fd, 3);
@@ -517,16 +515,16 @@ void chrif_on_ready(void) {
chrif_state = 2;
- chrif_check_shutdown();
+ chrif->check_shutdown();
//If there are players online, send them to the char-server. [Skotlex]
- send_users_tochar();
+ chrif->send_users_tochar();
//Auth db reconnect handling
auth_db->foreach(auth_db,chrif_reconnect);
//Re-save any storages that were modified in the disconnection time. [Skotlex]
- do_reconnect_storage();
+ storage->reconnect();
//Re-save any guild castles that were modified in the disconnection time.
guild->castle_reconnect(-1, 0, 0);
@@ -572,9 +570,9 @@ int chrif_scdata_request(int account_id, int char_id) {
* Request auth confirmation
*------------------------------------------*/
void chrif_authreq(struct map_session_data *sd) {
- struct auth_node *node= chrif_search(sd->bl.id);
+ struct auth_node *node= chrif->search(sd->bl.id);
- if( node != NULL || !chrif_isconnected() ) {
+ if( node != NULL || !chrif->isconnected() ) {
set_eof(sd->fd);
return;
}
@@ -622,7 +620,7 @@ void chrif_authok(int fd) {
if ( ( sd = iMap->id2sd(account_id) ) != NULL )
return;
- if ( ( node = chrif_search(account_id) ) == NULL )
+ if ( ( node = chrif->search(account_id) ) == NULL )
return; // should not happen
if ( node->state != ST_LOGIN )
@@ -632,7 +630,7 @@ void chrif_authok(int fd) {
/*
//When we receive double login info and the client has not connected yet,
//discard the older one and keep the new one.
- chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN);
+ chrif->auth_delete(node->account_id, node->char_id, ST_LOGIN);
*/
return; // should not happen
}
@@ -651,8 +649,8 @@ void chrif_authok(int fd) {
pc->authfail(sd);
}
- chrif_char_offline(sd); //Set him offline, the char server likely has it set as online already.
- chrif_auth_delete(account_id, char_id, ST_LOGIN);
+ chrif->char_offline(sd); //Set him offline, the char server likely has it set as online already.
+ chrif->auth_delete(account_id, char_id, ST_LOGIN);
}
// client authentication failed
@@ -667,7 +665,7 @@ void chrif_authfail(int fd) {/* HELLO WORLD. ip in RFIFOL 15 is not being used (
login_id1 = RFIFOL(fd,10);
sex = RFIFOB(fd,14);
- node = chrif_search(account_id);
+ node = chrif->search(account_id);
if( node != NULL &&
node->account_id == account_id &&
@@ -677,7 +675,7 @@ void chrif_authfail(int fd) {/* HELLO WORLD. ip in RFIFOL 15 is not being used (
node->state == ST_LOGIN )
{// found a match
clif->authfail_fd(node->fd, 0);
- chrif_auth_delete(account_id, char_id, ST_LOGIN);
+ chrif->auth_delete(account_id, char_id, ST_LOGIN);
}
}
@@ -695,13 +693,13 @@ int auth_db_cleanup_sub(DBKey key, DBData *data, va_list ap) {
case ST_LOGOUT:
//Re-save attempt (->sd should never be null here).
node->node_created = iTimer->gettick(); //Refresh tick (avoid char-server load if connection is really bad)
- chrif_save(node->sd, 1);
+ chrif->save(node->sd, 1);
break;
default:
//Clear data. any connected players should have timed out by now.
ShowInfo("auth_db: Node (state %s) timed out for %d:%d\n", states[node->state], node->account_id, node->char_id);
- chrif_char_offline_nsd(node->account_id, node->char_id);
- chrif_auth_delete(node->account_id, node->char_id, node->state);
+ chrif->char_offline_nsd(node->account_id, node->char_id);
+ chrif->auth_delete(node->account_id, node->char_id, node->state);
break;
}
return 1;
@@ -825,7 +823,7 @@ int chrif_changesex(struct map_session_data *sd) {
/*==========================================
* R 2b0f <accid>.l <name>.24B <type>.w <answer>.w
- * Processing a reply to chrif_char_ask_name() (request to modify an account).
+ * 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
* type of answer:
@@ -1037,9 +1035,9 @@ int chrif_disconnectplayer(int fd) {
sd = iMap->id2sd(account_id);
if( sd == NULL ) {
- struct auth_node* auth = chrif_search(account_id);
+ struct auth_node* auth = chrif->search(account_id);
- if( auth != NULL && chrif_auth_delete(account_id, auth->char_id, ST_LOGIN) )
+ if( auth != NULL && chrif->auth_delete(account_id, auth->char_id, ST_LOGIN) )
return 0;
return -1;
@@ -1333,11 +1331,11 @@ int chrif_char_online(struct map_session_data *sd) {
/// Called when the connection to Char Server is disconnected.
void chrif_on_disconnect(void) {
- if( chrif_connected != 1 )
+ if( chrif->chrif_connected != 1 )
ShowWarning("Connection to Char Server lost.\n\n");
- chrif_connected = 0;
+ chrif->chrif_connected = 0;
- other_mapserver_count = 0; //Reset counter. We receive ALL maps from all map-servers on reconnect.
+ chrif->other_mapserver_count = 0; //Reset counter. We receive ALL maps from all map-servers on reconnect.
iMap->eraseallipport();
//Attempt to reconnect in a second. [Skotlex]
@@ -1447,7 +1445,7 @@ int chrif_parse(int fd) {
switch(cmd) {
case 0x2af9: chrif_connectack(fd); break;
case 0x2afb: chrif_sendmapack(fd); break;
- case 0x2afd: chrif_authok(fd); break;
+ case 0x2afd: chrif->authok(fd); break;
case 0x2b00: iMap->setusers(RFIFOL(fd,2)); chrif_keepalive(fd); break;
case 0x2b03: clif->charselectok(RFIFOL(fd,2), RFIFOB(fd,6)); break;
case 0x2b04: chrif_recvmap(fd); break;
@@ -1546,15 +1544,15 @@ static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_
realloc_fifo(char_fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
chrif_connect(char_fd);
- chrif_connected = (chrif_state == 2);
+ chrif->chrif_connected = (chrif_state == 2);
srvinfo = 0;
} else {
if (srvinfo == 0) {
- chrif_ragsrvinfo(battle_config.base_exp_rate, battle_config.job_exp_rate, battle_config.item_rate_common);
+ chrif->ragsrvinfo(battle_config.base_exp_rate, battle_config.job_exp_rate, battle_config.item_rate_common);
srvinfo = 1;
}
}
- if ( chrif_isconnected() )
+ if ( chrif->isconnected() )
displayed = 0;
return 0;
}
@@ -1648,3 +1646,65 @@ int do_init_chrif(void) {
return 0;
}
+
+/*=====================================
+* Default Functions : chrif.h
+* Generated by HerculesInterfaceMaker
+* created by Susu
+*-------------------------------------*/
+void chrif_defaults(void) {
+ chrif = &chrif_s;
+
+ /* vars */
+
+ chrif->chrif_connected = 0;
+ chrif->other_mapserver_count = 0;
+
+ /* funcs */
+
+ chrif->setuserid = chrif_setuserid;
+ chrif->setpasswd = chrif_setpasswd;
+ chrif->checkdefaultlogin = chrif_checkdefaultlogin;
+ chrif->setip = chrif_setip;
+ chrif->setport = chrif_setport;
+
+ chrif->isconnected = chrif_isconnected;
+ chrif->check_shutdown = chrif_check_shutdown;
+
+ chrif->search = chrif_search;
+ chrif->auth_check = chrif_auth_check;
+ chrif->auth_delete = chrif_auth_delete;
+ chrif->auth_finished = chrif_auth_finished;
+
+ chrif->authreq = chrif_authreq;
+ chrif->authok = chrif_authok;
+ chrif->scdata_request = chrif_scdata_request;
+ chrif->save = chrif_save;
+ chrif->charselectreq = chrif_charselectreq;
+ chrif->changemapserver = chrif_changemapserver;
+
+ chrif->searchcharid = chrif_searchcharid;
+ chrif->changeemail = chrif_changeemail;
+ chrif->char_ask_name = chrif_char_ask_name;
+ chrif->updatefamelist = chrif_updatefamelist;
+ chrif->buildfamelist = chrif_buildfamelist;
+ chrif->save_scdata = chrif_save_scdata;
+ chrif->ragsrvinfo = chrif_ragsrvinfo;
+ chrif->char_offline = chrif_char_offline;
+ chrif->char_offline_nsd = chrif_char_offline_nsd;
+ chrif->char_reset_offline = chrif_char_reset_offline;
+ chrif->send_users_tochar = send_users_tochar;
+ chrif->char_online = chrif_char_online;
+ chrif->changesex = chrif_changesex;
+ //chrif->chardisconnect = chrif_chardisconnect;
+ chrif->divorce = chrif_divorce;
+
+ chrif->removefriend = chrif_removefriend;
+ chrif->send_report = chrif_send_report;
+
+ chrif->do_final_chrif = do_final_chrif;
+ chrif->do_init_chrif = do_init_chrif;
+
+ chrif->flush_fifo = chrif_flush_fifo;
+ chrif->skillid2idx = chrif_skillid2idx;
+}
diff --git a/src/map/chrif.h b/src/map/chrif.h
index 9c7142905..faabedeed 100644
--- a/src/map/chrif.h
+++ b/src/map/chrif.h
@@ -1,13 +1,10 @@
// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-
#ifndef _CHRIF_H_
#define _CHRIF_H_
-
#include "../common/cbasetypes.h"
#include <time.h>
-
enum sd_state { ST_LOGIN, ST_LOGOUT, ST_MAPCHANGE };
struct auth_node {
int account_id, char_id;
@@ -19,53 +16,72 @@ struct auth_node {
enum sd_state state; //To track whether player was login in/out or changing maps.
};
-void chrif_setuserid(char* id);
-void chrif_setpasswd(char* pwd);
-void chrif_checkdefaultlogin(void);
-int chrif_setip(const char* ip);
-void chrif_setport(uint16 port);
-
-int chrif_isconnected(void);
-void chrif_check_shutdown(void);
-extern int chrif_connected;
-extern int other_mapserver_count;
-struct auth_node* chrif_search(int account_id);
-struct auth_node* chrif_auth_check(int account_id, int char_id, enum sd_state state);
-bool chrif_auth_delete(int account_id, int char_id, enum sd_state state);
-bool chrif_auth_finished(struct map_session_data* sd);
-void chrif_authreq(struct map_session_data* sd);
-void chrif_authok(int fd);
-int chrif_scdata_request(int account_id, int char_id);
-int chrif_save(struct map_session_data* sd, int flag);
-int chrif_charselectreq(struct map_session_data* sd, uint32 s_ip);
-int chrif_changemapserver(struct map_session_data* sd, uint32 ip, uint16 port);
+/*=====================================
+* Interface : chrif.h
+* Generated by HerculesInterfaceMaker
+* created by Susu
+*-------------------------------------*/
+struct chrif_interface {
-int chrif_searchcharid(int char_id);
-int chrif_changeemail(int id, const char *actual_email, const char *new_email);
-int 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);
-int chrif_updatefamelist(struct map_session_data *sd);
-int chrif_buildfamelist(void);
-int chrif_save_scdata(struct map_session_data *sd);
-int chrif_ragsrvinfo(int base_rate,int job_rate, int drop_rate);
-int chrif_char_offline(struct map_session_data *sd);
-int chrif_char_offline_nsd(int account_id, int char_id);
-int chrif_char_reset_offline(void);
-int send_users_tochar(void);
-int chrif_char_online(struct map_session_data *sd);
-int chrif_changesex(struct map_session_data *sd);
-int chrif_chardisconnect(struct map_session_data *sd);
-int chrif_divorce(int partner_id1, int partner_id2);
+ /* vars */
+
+ int chrif_connected;
+ int other_mapserver_count; //Holds count of how many other map servers are online (apart of this instance) [Skotlex]
-int chrif_removefriend(int char_id, int friend_id);
-void chrif_send_report(char* buf, int len);
+ /* funcs */
+
+ void (*setuserid) (char* id);
+ void (*setpasswd) (char* pwd);
+ void (*checkdefaultlogin) (void);
+ int (*setip) (const char* ip);
+ void (*setport) (uint16 port);
+
+ int (*isconnected) (void);
+ void (*check_shutdown) (void);
+
+ struct auth_node* (*search) (int account_id);
+ struct auth_node* (*auth_check) (int account_id, int char_id, enum sd_state state);
+ bool (*auth_delete) (int account_id, int char_id, enum sd_state state);
+ bool (*auth_finished) (struct map_session_data* sd);
+
+ void (*authreq) (struct map_session_data* sd);
+ void (*authok) (int fd);
+ int (*scdata_request) (int account_id, int char_id);
+ int (*save) (struct map_session_data* sd, int flag);
+ int (*charselectreq) (struct map_session_data* sd, uint32 s_ip);
+ int (*changemapserver) (struct map_session_data* sd, uint32 ip, uint16 port);
+
+ int (*searchcharid) (int char_id);
+ int (*changeemail) (int id, const char *actual_email, const char *new_email);
+ int (*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);
+ int (*updatefamelist) (struct map_session_data *sd);
+ int (*buildfamelist) (void);
+ int (*save_scdata) (struct map_session_data *sd);
+ int (*ragsrvinfo) (int base_rate,int job_rate, int drop_rate);
+ int (*char_offline) (struct map_session_data *sd);
+ int (*char_offline_nsd) (int account_id, int char_id);
+ int (*char_reset_offline) (void);
+ int (*send_users_tochar) (void);
+ int (*char_online) (struct map_session_data *sd);
+ int (*changesex) (struct map_session_data *sd);
+ int (*chardisconnect) (struct map_session_data *sd);
+ int (*divorce) (int partner_id1, int partner_id2);
+
+ int (*removefriend) (int char_id, int friend_id);
+ void (*send_report) (char* buf, int len);
+
+ int (*do_final_chrif) (void);
+ int (*do_init_chrif) (void);
+
+ int (*flush_fifo) (void);
+ void (*skillid2idx) (int fd);
+} chrif_s;
-int do_final_chrif(void);
-int do_init_chrif(void);
+struct chrif_interface *chrif;
-int chrif_flush_fifo(void);
-void chrif_skillid2idx(int fd);
+void chrif_defaults(void);
#endif /* _CHRIF_H_ */
diff --git a/src/map/clif.c b/src/map/clif.c
index 73d4b6666..e5132a938 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1759,7 +1759,7 @@ void clif_buylist(struct map_session_data *sd, struct npc_data *nd)
c = 0;
for( i = 0; i < nd->u.shop.count; i++ )
{
- struct item_data* id = itemdb_exists(nd->u.shop.shop_item[i].nameid);
+ struct item_data* id = itemdb->exists(nd->u.shop.shop_item[i].nameid);
int val = nd->u.shop.shop_item[i].value;
if( id == NULL )
continue;
@@ -2497,7 +2497,7 @@ void clif_storagelist(struct map_session_data* sd, struct item* items, int items
{
if( items[i].nameid <= 0 )
continue;
- id = itemdb_search(items[i].nameid);
+ id = itemdb->search(items[i].nameid);
if( !itemdb_isstackable2(id) )
{ //Equippable
WBUFW(bufe,ne*cmd+4)=i+1;
@@ -2577,7 +2577,7 @@ void clif_cartlist(struct map_session_data *sd)
{
if( sd->status.cart[i].nameid <= 0 )
continue;
- id = itemdb_search(sd->status.cart[i].nameid);
+ id = itemdb->search(sd->status.cart[i].nameid);
if( !itemdb_isstackable2(id) )
{ //Equippable
WBUFW(bufe,ne*cmd+4)=i+2;
@@ -5970,7 +5970,7 @@ void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len)
WFIFOW(fd,0) = 0x97;
WFIFOW(fd,2) = mes_len + NAME_LENGTH + 8;
safestrncpy((char*)WFIFOP(fd,4), nick, NAME_LENGTH);
- WFIFOL(fd,28) = (pc->get_group_level(ssd) == 99) ? 1 : 0; // isAdmin; if nonzero, also displays text above char
+ WFIFOL(fd,28) = (ssd && pc->get_group_level(ssd) == 99) ? 1 : 0; // isAdmin; if nonzero, also displays text above char
safestrncpy((char*)WFIFOP(fd,32), mes, mes_len);
WFIFOSET(fd,WFIFOW(fd,2));
#endif
@@ -6416,7 +6416,7 @@ void clif_vendinglist(struct map_session_data* sd, unsigned int id, struct s_ven
for( i = 0; i < count; i++ )
{
int index = vending[i].index;
- struct item_data* data = itemdb_search(vsd->status.cart[index].nameid);
+ struct item_data* data = itemdb->search(vsd->status.cart[index].nameid);
WFIFOL(fd,offset+ 0+i*22) = vending[i].value;
WFIFOW(fd,offset+ 4+i*22) = vending[i].amount;
WFIFOW(fd,offset+ 6+i*22) = vending[i].index + 2;
@@ -6475,7 +6475,7 @@ void clif_openvending(struct map_session_data* sd, int id, struct s_vending* ven
WFIFOL(fd,4) = id;
for( i = 0; i < count; i++ ) {
int index = vending[i].index;
- struct item_data* data = itemdb_search(sd->status.cart[index].nameid);
+ struct item_data* data = itemdb->search(sd->status.cart[index].nameid);
WFIFOL(fd, 8+i*22) = vending[i].value;
WFIFOW(fd,12+i*22) = vending[i].index + 2;
WFIFOW(fd,14+i*22) = vending[i].amount;
@@ -9295,7 +9295,7 @@ void clif_parse_WantToConnection(int fd, struct map_session_data* sd) {
}
if (bl ||
- ((node=chrif_search(account_id)) && //An already existing node is valid only if it is for this login.
+ ((node=chrif->search(account_id)) && //An already existing node is valid only if it is for this login.
!(node->account_id == account_id && node->char_id == char_id && node->state == ST_LOGIN)))
{
clif->authfail_fd(fd, 8); //Still recognizes last connection
@@ -9321,7 +9321,7 @@ void clif_parse_WantToConnection(int fd, struct map_session_data* sd) {
WFIFOSET(fd,packet_len(0x283));
#endif
- chrif_authreq(sd);
+ chrif->authreq(sd);
}
void clif_hercules_chsys_mjoin(struct map_session_data *sd) {
if( !map[sd->bl.m].channel ) {
@@ -9574,7 +9574,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
if( iMap->night_flag && map[sd->bl.m].flag.nightenabled ) { //Display night.
if( !sd->state.night ) {
sd->state.night = 1;
- clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_SKE);
+ clif->status_change(&sd->bl, SI_SKE, 1, 0, 0, 0, 0);
}
} else if( sd->state.night ) { //Clear night display.
sd->state.night = 0;
@@ -9651,6 +9651,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
// Trigger skill effects if you appear standing on them
if(!battle_config.pc_invincible_time)
skill->unit_move(&sd->bl,iTimer->gettick(),1);
+
}
@@ -10333,7 +10334,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) {
if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] &&
(!battle_config.prevent_logout || DIFF_TICK(iTimer->gettick(), sd->canlog_tick) > battle_config.prevent_logout) )
{ //Send to char-server for character selection.
- chrif_charselectreq(sd, session[fd]->client_addr);
+ chrif->charselectreq(sd, session[fd]->client_addr);
} else {
clif->disconnect_ack(sd, 1);
}
@@ -11849,10 +11850,9 @@ void clif_parse_MoveToKafra(int fd, struct map_session_data *sd)
return;
if (sd->state.storage_flag == 1)
- storage_storageadd(sd, item_index, item_amount);
- else
- if (sd->state.storage_flag == 2)
- storage_guild_storageadd(sd, item_index, item_amount);
+ storage->add(sd, item_index, item_amount);
+ else if (sd->state.storage_flag == 2)
+ gstorage->add(sd, item_index, item_amount);
}
@@ -11868,9 +11868,9 @@ void clif_parse_MoveFromKafra(int fd,struct map_session_data *sd)
item_amount = RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[1]);
if (sd->state.storage_flag == 1)
- storage_storageget(sd, item_index, item_amount);
+ storage->get(sd, item_index, item_amount);
else if(sd->state.storage_flag == 2)
- storage_guild_storageget(sd, item_index, item_amount);
+ gstorage->get(sd, item_index, item_amount);
}
@@ -11884,10 +11884,9 @@ void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd)
return;
if (sd->state.storage_flag == 1)
- storage_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4));
- else
- if (sd->state.storage_flag == 2)
- storage_guild_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4));
+ storage->addfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4));
+ else if (sd->state.storage_flag == 2)
+ gstorage->addfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4));
}
@@ -11901,10 +11900,9 @@ void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd)
return;
if (sd->state.storage_flag == 1)
- storage_storagegettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4));
- else
- if (sd->state.storage_flag == 2)
- storage_guild_storagegettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4));
+ storage->gettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4));
+ else if (sd->state.storage_flag == 2)
+ gstorage->gettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4));
}
@@ -11913,9 +11911,9 @@ void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd)
void clif_parse_CloseKafra(int fd, struct map_session_data *sd)
{
if( sd->state.storage_flag == 1 )
- storage_storageclose(sd);
+ storage->close(sd);
else if( sd->state.storage_flag == 2 )
- storage_guild_storageclose(sd);
+ gstorage->close(sd);
}
@@ -13337,7 +13335,7 @@ void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd)
// FIXME: Stackables have a quantity of 20.
// FIXME: Equips are supposed to be unidentified.
- if( itemdb_searchname(monster_item_name) ) {
+ if( itemdb->search_name(monster_item_name) ) {
snprintf(command, sizeof(command)-1, "%citem %s", atcommand->at_symbol, monster_item_name);
atcommand->parse(fd, sd, command, 1);
return;
@@ -13871,7 +13869,7 @@ void clif_parse_FriendsListRemove(int fd, struct map_session_data *sd)
}
} else { //friend not online -- ask char server to delete from his friendlist
- if(chrif_removefriend(char_id,sd->status.char_id)) { // char-server offline, abort
+ if(chrif->removefriend(char_id,sd->status.char_id)) { // char-server offline, abort
clif->message(fd, msg_txt(673)); //"This action can't be performed at the moment. Please try again later."
return;
}
@@ -14512,7 +14510,7 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id)
WFIFOL(fd,72) = 0;
WFIFOL(fd,76) = msg->zeny;
- if( item->nameid && (data = itemdb_exists(item->nameid)) != NULL ) {
+ if( item->nameid && (data = itemdb->exists(item->nameid)) != NULL ) {
WFIFOL(fd,80) = item->amount;
WFIFOW(fd,84) = (data->view_id)?data->view_id:item->nameid;
WFIFOW(fd,86) = data->type;
@@ -14562,7 +14560,7 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd)
int i;
bool fail = false;
- if( !chrif_isconnected() )
+ if( !chrif->isconnected() )
return;
if( mail_id <= 0 )
return;
@@ -14585,7 +14583,7 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd)
struct item_data *data;
unsigned int weight;
- if ((data = itemdb_exists(sd->mail.inbox.msg[i].item.nameid)) == NULL)
+ if ((data = itemdb->exists(sd->mail.inbox.msg[i].item.nameid)) == NULL)
return;
switch( pc->checkadditem(sd, data->nameid, sd->mail.inbox.msg[i].item.amount) ) {
@@ -14623,7 +14621,7 @@ void clif_parse_Mail_delete(int fd, struct map_session_data *sd)
int mail_id = RFIFOL(fd,2);
int i;
- if( !chrif_isconnected() )
+ if( !chrif->isconnected() )
return;
if( mail_id <= 0 )
return;
@@ -14672,7 +14670,7 @@ void clif_parse_Mail_setattach(int fd, struct map_session_data *sd)
int amount = RFIFOL(fd,4);
unsigned char flag;
- if( !chrif_isconnected() )
+ if( !chrif->isconnected() )
return;
if (idx < 0 || amount < 0)
return;
@@ -14706,7 +14704,7 @@ void clif_parse_Mail_send(int fd, struct map_session_data *sd)
struct mail_message msg;
int body_len;
- if( !chrif_isconnected() )
+ if( !chrif->isconnected() )
return;
if( sd->state.trading )
return;
@@ -14803,7 +14801,7 @@ void clif_Auction_results(struct map_session_data *sd, short count, short pages,
WFIFOL(fd,k) = auction.auction_id;
safestrncpy((char*)WFIFOP(fd,4+k), auction.seller_name, NAME_LENGTH);
- if( (item = itemdb_exists(auction.item.nameid)) != NULL && item->view_id > 0 )
+ if( (item = itemdb->exists(auction.item.nameid)) != NULL && item->view_id > 0 )
WFIFOW(fd,28+k) = item->view_id;
else
WFIFOW(fd,28+k) = auction.item.nameid;
@@ -14876,7 +14874,7 @@ void clif_parse_Auction_setitem(int fd, struct map_session_data *sd)
return;
}
- if( (item = itemdb_exists(sd->status.inventory[idx].nameid)) != NULL && !(item->type == IT_ARMOR || item->type == IT_PETARMOR || item->type == IT_WEAPON || item->type == IT_CARD || item->type == IT_ETC) )
+ if( (item = itemdb->exists(sd->status.inventory[idx].nameid)) != NULL && !(item->type == IT_ARMOR || item->type == IT_PETARMOR || item->type == IT_WEAPON || item->type == IT_CARD || item->type == IT_ETC) )
{ // Consumable or pets are not allowed
clif->auction_setitem(sd->fd, idx, true);
return;
@@ -14983,7 +14981,7 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd)
return;
}
- if( (item = itemdb_exists(sd->status.inventory[sd->auction.index].nameid)) == NULL )
+ if( (item = itemdb->exists(sd->status.inventory[sd->auction.index].nameid)) == NULL )
{ // Just in case
clif->auction_message(fd, 2); // The auction has been canceled
return;
@@ -15119,7 +15117,7 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd)
#endif
for( i = 0; i < nd->u.shop.count; i++ ) {
- struct item_data* id = itemdb_search(nd->u.shop.shop_item[i].nameid);
+ struct item_data* id = itemdb->search(nd->u.shop.shop_item[i].nameid);
WFIFOL(fd,offset+0+i*11) = nd->u.shop.shop_item[i].value;
WFIFOL(fd,offset+4+i*11) = nd->u.shop.shop_item[i].value; // Discount Price
WFIFOB(fd,offset+8+i*11) = itemtype(id->type);
@@ -16039,7 +16037,7 @@ void clif_party_show_picker(struct map_session_data * sd, struct item * item_dat
{
#if PACKETVER >= 20071002
unsigned char buf[22];
- struct item_data* id = itemdb_search(item_data->nameid);
+ struct item_data* id = itemdb->search(item_data->nameid);
WBUFW(buf,0) = 0x2b8;
WBUFL(buf,2) = sd->status.account_id;
@@ -17061,12 +17059,12 @@ void clif_cashshop_db(void) {
}
if( name[0] == 'I' && name[1] == 'D' && strlen(name) <= 7 ) {
- if( !( data = itemdb_exists(atoi(name+2))) ) {
+ if( !( data = itemdb->exists(atoi(name+2))) ) {
ShowWarning("cashshop_db: unknown item id '%s' in category '%s'\n", name+2, entry_name);
continue;
}
} else {
- if( !( data = itemdb_searchname(name) ) ) {
+ if( !( data = itemdb->search_name(name) ) ) {
ShowWarning("cashshop_db: unknown item name '%s' in category '%s'\n", name, entry_name);
continue;
}
@@ -17126,7 +17124,6 @@ void clif_monster_hp_bar( struct mob_data* md, struct map_session_data *sd ) {
void __attribute__ ((unused)) clif_parse_dull(int fd,struct map_session_data *sd) {
return;
}
-
void clif_parse_CashShopOpen(int fd, struct map_session_data *sd) {
WFIFOHEAD(fd, 10);
WFIFOW(fd, 0) = 0x845;
@@ -17180,7 +17177,7 @@ void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) {
result = CSBR_SHORTTAGE_CASH;
} else if( (sd->cashPoints+kafra_pay) < (clif->cs.data[tab][j]->price * qty) ) {
result = CSBR_SHORTTAGE_CASH;
- } else if ( !( data = itemdb_exists(clif->cs.data[tab][j]->id) ) ) {
+ } else if ( !( data = itemdb->exists(clif->cs.data[tab][j]->id) ) ) {
result = CSBR_UNKONWN_ITEM;
} else {
struct item item_tmp;
@@ -17308,6 +17305,9 @@ void clif_partytickack(struct map_session_data* sd, bool flag) {
void clif_status_change_end(struct block_list *bl, int tid, enum send_target target, int type) {
struct packet_status_change_end p;
+ if( bl->type == BL_PC && !((TBL_PC*)bl)->state.active )
+ return;
+
p.PacketType = status_change_endType;
p.index = type;
p.AID = tid;
@@ -17400,8 +17400,14 @@ void clif_parse_bgqueue_revoke_req(int fd, struct map_session_data *sd) {
}
void clif_parse_bgqueue_battlebegin_ack(int fd, struct map_session_data *sd) {
- //struct packet_bgqueue_battlebegin_ack *p = P2PTR(fd, bgqueue_checkstateType);
- return;
+ struct packet_bgqueue_battlebegin_ack *p = P2PTR(fd, bgqueue_checkstateType);
+ struct bg_arena *arena;
+ if( !bg->queue_on ) return; /* temp, until feature is complete */
+ if( ( arena = bg->name2arena(p->bg_name) ) ) {
+ bg->queue_ready_ack(arena,sd, ( p->result == 1 ) ? true : false);
+ } else {
+ clif->bgqueue_ack(sd,BGQA_FAIL_BGNAME_INVALID, 0);
+ }
//if ( p->result == 1 )
// bg->queue_pc_ready(sd);
//else
@@ -17442,6 +17448,22 @@ void clif_scriptclear(struct map_session_data *sd, int npcid) {
clif->send(&p,sizeof(p), &sd->bl, SELF);
}
+/* Made Possible Thanks to Yommy! */
+void clif_package_item_announce(struct map_session_data *sd, unsigned short nameid, unsigned short containerid) {
+ struct packet_package_item_announce p;
+
+ p.PacketType = package_item_announceType;
+ p.PacketLength = 11+NAME_LENGTH;
+ p.type = 0x0;
+ p.ItemID = nameid;
+ p.len = NAME_LENGTH;
+ safestrncpy(p.Name, sd->status.name, sizeof(p.Name));
+ p.unknown = 0x2; // some strange byte, IDA shows.. BYTE3(BoxItemIDLength) = 2;
+ p.BoxItemID = containerid;
+
+ clif->send(&p,sizeof(p), &sd->bl, ALL_CLIENT);
+}
+/* */
unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) {
if( sd ) {
sd->cryptKey = (( sd->cryptKey * clif->cryptKey[1] ) + clif->cryptKey[2]) & 0xFFFFFFFF;
@@ -18204,6 +18226,7 @@ void clif_defaults(void) {
clif->user_count = clif_user_count;
clif->noask_sub = clif_noask_sub;
clif->cashshop_load = clif_cashshop_db;
+ clif->package_announce = clif_package_item_announce;
clif->bc_ready = clif_bc_ready;
clif->undisguise_timer = clif_undisguise_timer;
/*------------------------
diff --git a/src/map/clif.h b/src/map/clif.h
index 6e1fa81d3..bea701223 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -501,6 +501,7 @@ struct clif_interface {
void (*item_sub) (unsigned char *buf, int n, struct item *i, struct item_data *id, int equip);
void (*getareachar_item) (struct map_session_data* sd,struct flooritem_data* fitem);
void (*cashshop_load) (void);
+ void (*package_announce) (struct map_session_data *sd, unsigned short nameid, unsigned short containerid);
/* unit-related */
void (*clearunit_single) (int id, clr_type type, int fd);
void (*clearunit_area) (struct block_list* bl, clr_type type);
diff --git a/src/map/guild.c b/src/map/guild.c
index b28c14db7..e093fdf92 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -921,7 +921,7 @@ int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, c
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.
- storage_guild_storageclose(sd);
+ gstorage->close(sd);
guild->send_dot_remove(sd);
if( hChSys.ally ) {
clif->chsys_quitg(sd);
@@ -1752,7 +1752,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)
- storage_guild_storage_quit(sd,1);
+ gstorage->pc_quit(sd,1);
sd->status.guild_id=0;
sd->guild = NULL;
clif->guild_broken(g->member[i].sd,0);
@@ -1762,7 +1762,7 @@ int guild_broken(int guild_id,int flag)
guild_db->foreach(guild_db,guild_broken_sub,guild_id);
castle_db->foreach(castle_db,castle_guild_broken_sub,guild_id);
- guild_storage_delete(guild_id);
+ gstorage->delete(guild_id);
if( hChSys.ally ) {
if( g->channel != NULL ) {
clif->chsys_delete(( struct hChSysCh * )g->channel);
diff --git a/src/map/instance.c b/src/map/instance.c
index 690f14cfe..6b80f5d75 100644
--- a/src/map/instance.c
+++ b/src/map/instance.c
@@ -46,10 +46,11 @@ bool instance_is_valid(int instance_id) {
* On success return instance_id
*--------------------------------------*/
int instance_create(int owner_id, const char *name, enum instance_owner_type type) {
- unsigned short *iptr = NULL, *icptr = NULL;
struct map_session_data *sd = NULL;
+ unsigned short *icptr = NULL;
struct party_data *p = NULL;
struct guild *g = NULL;
+ short *iptr = NULL;
int i, j;
switch ( type ) {
@@ -91,7 +92,7 @@ int instance_create(int owner_id, const char *name, enum instance_owner_type typ
}
ARR_FIND(0, instance->instances, i, instances[i].state == INSTANCE_FREE);
-
+
if( i == instance->instances )
RECREATE(instances, struct instance_data, ++instance->instances);
@@ -109,10 +110,9 @@ int instance_create(int owner_id, const char *name, enum instance_owner_type typ
instances[i].vars = idb_alloc(DB_OPT_RELEASE_DATA);
safestrncpy( instances[i].name, name, sizeof(instances[i].name) );
- instances[i].map = NULL;
if( type != IOT_NONE ) {
- ARR_FIND(0, *icptr, j, iptr[j] == 0);
+ ARR_FIND(0, *icptr, j, iptr[j] == -1);
if( j == *icptr ) {
switch( type ) {
case IOT_CHAR:
@@ -162,8 +162,8 @@ int instance_add_map(const char *name, int instance_id, bool usebasename, const
return -4;
}
- ARR_FIND( instance->start_id, iMap->map_num, i, !map[i].name[0] ); // Searching for a Free Map
-
+ ARR_FIND( instance->start_id, iMap->map_num, i, map[i].name[0] == 0 ); // Searching for a Free Map
+
if( i < iMap->map_num )
im = i; // Unused map found (old instance)
else {
@@ -370,6 +370,7 @@ void instance_del_map(int16 m) {
iMap->removemapdb(&map[m]);
memset(&map[m], 0x00, sizeof(map[0]));
+ map[m].name[0] = 0;
map[m].instance_id = -1;
map[m].mob_delete_timer = INVALID_TIMER;
}
@@ -386,13 +387,14 @@ int instance_destroy_timer(int tid, unsigned int tick, int id, intptr_t data) {
* Removes a instance, all its maps and npcs.
*--------------------------------------*/
void instance_destroy(int instance_id) {
- unsigned short *iptr = NULL, *icptr = NULL;
struct map_session_data *sd = NULL;
+ unsigned short *icptr = NULL;
struct party_data *p = NULL;
struct guild *g = NULL;
- int last = 0, type, j;
+ short *iptr = NULL;
+ int type, j, last = 0;
unsigned int now = (unsigned int)time(NULL);
-
+
if( !instance->valid(instance_id) )
return; // nothing to do
@@ -402,7 +404,7 @@ void instance_destroy(int instance_id) {
type = 2;
else
type = 3;
-
+
clif->instance(instance_id, 5, type); // Report users this instance has been destroyed
switch ( instances[instance_id].owner_type ) {
@@ -430,21 +432,21 @@ void instance_destroy(int instance_id) {
icptr = &g->instances;
break;
default:
- ShowError("instance_destroy: unknown type %d for owner_id %d and name %s.\n", instances[instance_id].owner_type,instances[instance_id].owner_id,instances[instance_id].name);
+ ShowError("instance_destroy: unknown type %d for owner_id %d and name '%s'.\n", instances[instance_id].owner_type,instances[instance_id].owner_id,instances[instance_id].name);
break;
}
if( iptr != NULL ) {
ARR_FIND(0, *icptr, j, iptr[j] == instance_id);
if( j != *icptr )
- iptr[j] = 0;
+ iptr[j] = -1;
}
while( instances[instance_id].num_map && last != instances[instance_id].map[0] ) { // Remove all maps from instance
last = instances[instance_id].map[0];
instance->del_map( instances[instance_id].map[0] );
}
-
+
if( instances[instance_id].vars )
db_destroy(instances[instance_id].vars);
@@ -455,10 +457,12 @@ void instance_destroy(int instance_id) {
instances[instance_id].vars = NULL;
- aFree(instances[instance_id].map);
+ if( instances[instance_id].map )
+ aFree(instances[instance_id].map);
- memset( &instances[instance_id], 0x00, sizeof(struct instance_data) );
-
+ instances[instance_id].map = NULL;
+ instances[instance_id].state = INSTANCE_FREE;
+ instances[instance_id].num_map = 0;
}
/*--------------------------------------
@@ -540,12 +544,15 @@ void instance_check_kick(struct map_session_data *sd) {
void do_final_instance(void) {
int i;
-
+
for(i = 0; i < instance->instances; i++) {
- instance_destroy(i);
+ instance->destroy(i);
}
- aFree(instances);
+ if( instances )
+ aFree(instances);
+
+ instance->instances = 0;
}
void do_init_instance(void) {
diff --git a/src/map/intif.c b/src/map/intif.c
index f3931e79e..294d79656 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -147,7 +147,7 @@ int intif_broadcast(const char* mes, int len, int type)
if (CheckForCharServer())
return 0;
- if (other_mapserver_count < 1)
+ if (chrif->other_mapserver_count < 1)
return 0; //No need to send.
WFIFOHEAD(inter_fd, 16 + lp + len);
@@ -175,7 +175,7 @@ int intif_broadcast2(const char* mes, int len, unsigned long fontColor, short fo
if (CheckForCharServer())
return 0;
- if (other_mapserver_count < 1)
+ if (chrif->other_mapserver_count < 1)
return 0; //No need to send.
WFIFOHEAD(inter_fd, 16 + len);
@@ -219,7 +219,7 @@ int intif_wis_message(struct map_session_data *sd, char *nick, char *mes, int me
if (CheckForCharServer())
return 0;
- if (other_mapserver_count < 1)
+ if (chrif->other_mapserver_count < 1)
{ //Character not found.
clif->wis_end(sd->fd, 1);
return 0;
@@ -502,7 +502,7 @@ int intif_party_message(int party_id,int account_id,const char *mes,int len)
if (CheckForCharServer())
return 0;
- if (other_mapserver_count < 1)
+ if (chrif->other_mapserver_count < 1)
return 0; //No need to send.
WFIFOHEAD(inter_fd,len + 12);
@@ -637,7 +637,7 @@ int intif_guild_message(int guild_id,int account_id,const char *mes,int len)
if (CheckForCharServer())
return 0;
- if (other_mapserver_count < 1)
+ if (chrif->other_mapserver_count < 1)
return 0; //No need to send.
WFIFOHEAD(inter_fd, len + 12);
@@ -950,7 +950,7 @@ int intif_parse_Registers(int fd)
struct global_reg *reg;
int *qty;
int account_id = RFIFOL(fd,4), char_id = RFIFOL(fd,8);
- struct auth_node *node = chrif_auth_check(account_id, char_id, ST_LOGIN);
+ struct auth_node *node = chrif->auth_check(account_id, char_id, ST_LOGIN);
if (node)
sd = node->sd;
else { //Normally registries should arrive for in log-in chars.
@@ -1011,7 +1011,7 @@ int intif_parse_LoadGuildStorage(int fd)
ShowError("intif_parse_LoadGuildStorage: user not found %d\n",RFIFOL(fd,4));
return 1;
}
- gstor=guild2storage(guild_id);
+ gstor=gstorage->id2storage(guild_id);
if(!gstor) {
ShowWarning("intif_parse_LoadGuildStorage: error guild_id %d not exist\n",guild_id);
return 1;
@@ -1031,14 +1031,14 @@ int intif_parse_LoadGuildStorage(int fd)
}
memcpy(gstor,RFIFOP(fd,12),sizeof(struct guild_storage));
- storage_guild_storageopen(sd);
+ gstorage->open(sd);
return 0;
}
// ACK guild_storage saved
int intif_parse_SaveGuildStorage(int fd)
{
- storage_guild_storagesaved(/*RFIFOL(fd,2), */RFIFOL(fd,6));
+ gstorage->saved(/*RFIFOL(fd,2), */RFIFOL(fd,6));
return 0;
}
@@ -1723,7 +1723,7 @@ static void intif_parse_Mail_send(int fd)
{
clif->mail_send(sd->fd, false);
if( iMap->save_settings&16 )
- chrif_save(sd, 0);
+ chrif->save(sd, 0);
}
}
}
@@ -1814,7 +1814,7 @@ static void intif_parse_Auction_register(int fd)
{
clif->auction_message(sd->fd, 1); // Confirmation Packet ??
if( iMap->save_settings&32 )
- chrif_save(sd,0);
+ chrif->save(sd,0);
}
else
{
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 859b19aac..5fae29500 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -8,6 +8,7 @@
#include "../common/showmsg.h"
#include "../common/strlib.h"
#include "../common/utils.h"
+#include "../common/conf.h"
#include "itemdb.h"
#include "map.h"
#include "battle.h" // struct battle_config
@@ -52,14 +53,12 @@ static int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap)
/*==========================================
* Return item data from item name. (lookup)
*------------------------------------------*/
-struct item_data* itemdb_searchname(const char *str)
-{
+struct item_data* itemdb_searchname(const char *str) {
struct item_data* item;
struct item_data* item2=NULL;
int i;
- for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
- {
+ for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i ) {
item = itemdb_array[i];
if( item == NULL )
continue;
@@ -77,6 +76,10 @@ struct item_data* itemdb_searchname(const char *str)
itemdb_other->foreach(itemdb_other,itemdb_searchname_sub,str,&item,&item2);
return item?item:item2;
}
+/* name to item data */
+struct item_data* itemdb_name2id(const char *str) {
+ return strdb_get(itemdb->names,str);
+}
/**
* @see DBMatcher
@@ -98,8 +101,7 @@ static int itemdb_searchname_array_sub(DBKey key, DBData data, va_list ap)
/*==========================================
* Founds up to N matches. Returns number of matches [Skotlex]
*------------------------------------------*/
-int itemdb_searchname_array(struct item_data** data, int size, const char *str)
-{
+int itemdb_searchname_array(struct item_data** data, int size, const char *str) {
struct item_data* item;
int i;
int count=0;
@@ -132,38 +134,130 @@ int itemdb_searchname_array(struct item_data** data, int size, const char *str)
}
return count;
}
-
-
-/*==========================================
- * Return a random item id from group. (takes into account % chance giving/tot group)
- *------------------------------------------*/
-int itemdb_searchrandomid(int group)
-{
- if(group<1 || group>=MAX_ITEMGROUP) {
- ShowError("itemdb_searchrandomid: Invalid group id %d\n", group);
+/* [Ind/Hercules] */
+int itemdb_chain_item(unsigned short chain_id, int *rate) {
+ struct item_chain_entry *entry;
+ int i = 0;
+
+ if( chain_id >= itemdb->chain_count ) {
+ ShowError("itemdb_chain_item: unknown chain id %d\n", chain_id);
return UNKNOWN_ITEM_ID;
}
- if (itemgroup_db[group].qty)
- return itemgroup_db[group].nameid[rnd()%itemgroup_db[group].qty];
- ShowError("itemdb_searchrandomid: No item entries for group id %d\n", group);
- return UNKNOWN_ITEM_ID;
+ entry = &itemdb->chains[chain_id].items[ rnd()%itemdb->chains[chain_id].qty ];
+
+ for( i = 0; i < itemdb->chains[chain_id].qty; i++ ) {
+ if( rnd()%10000 >= entry->rate ) {
+ entry = entry->next;
+ continue;
+ } else {
+ if( rate )
+ rate[0] = entry->rate;
+ return entry->id;
+ }
+ }
+
+ return 0;
}
+/* [Ind/Hercules] */
+void itemdb_package_item(struct map_session_data *sd, struct item_package *package) {
+ int i = 0, get_count, j, flag;
+
+ for( i = 0; i < package->must_qty; i++ ) {
+ struct item it;
+ memset(&it, 0, sizeof(it));
+ it.nameid = package->must_items[i].id;
+ it.identify = 1;
+
+ if( package->must_items[i].hours ) {
+ it.expire_time = (unsigned int)(time(NULL) + ((package->must_items[i].hours*60)*60));
+ }
+
+ if( package->must_items[i].named ) {
+ it.card[0] = CARD0_FORGE;
+ it.card[1] = 0;
+ it.card[2] = GetWord(sd->status.char_id, 0);
+ it.card[3] = GetWord(sd->status.char_id, 1);
+ }
+
+ if( package->must_items[i].announce )
+ clif->package_announce(sd,package->must_items[i].id,package->id);
+
+ get_count = itemdb_isstackable(package->must_items[i].id) ? package->must_items[i].qty : 1;
+
+ it.amount = get_count == 1 ? 1 : get_count;
+
+ for( j = 0; j < package->must_items[i].qty; j += get_count ) {
+ if ( ( flag = pc->additem(sd, &it, get_count, LOG_TYPE_SCRIPT) ) )
+ clif->additem(sd, 0, 0, flag);
+ }
+ }
+
+ if( package->random_qty ) {
+ struct item_package_rand_entry *entry;
+
+ entry = &package->random_list[rnd()%package->random_qty];
+
+ while( 1 ) {
+ if( rnd()%10000 >= entry->rate ) {
+ entry = entry->next;
+ continue;
+ } else {
+ struct item it;
+ memset(&it, 0, sizeof(it));
+
+ it.nameid = entry->id;
+ it.identify = 1;
+
+ if( entry->hours ) {
+ it.expire_time = (unsigned int)(time(NULL) + ((entry->hours*60)*60));
+ }
+
+ if( entry->named ) {
+ it.card[0] = CARD0_FORGE;
+ it.card[1] = 0;
+ it.card[2] = GetWord(sd->status.char_id, 0);
+ it.card[3] = GetWord(sd->status.char_id, 1);
+ }
+
+ if( entry->announce )
+ clif->package_announce(sd,entry->id,package->id);
+
+ get_count = itemdb_isstackable(entry->id) ? entry->qty : 1;
+
+ it.amount = get_count == 1 ? 1 : get_count;
+
+ for( j = 0; j < entry->qty; j += get_count ) {
+ if ( ( flag = pc->additem(sd, &it, get_count, LOG_TYPE_SCRIPT) ) )
+ clif->additem(sd, 0, 0, flag);
+ }
+ break;
+ }
+ }
+ }
+
+ return;
+}
/*==========================================
- * Calculates total item-group related bonuses for the given item
+ * Return a random item id from group. (takes into account % chance giving/tot group)
*------------------------------------------*/
-int itemdb_group_bonus(struct map_session_data* sd, int itemid)
-{
- int bonus = 0, i, j;
- for (i=0; i < MAX_ITEMGROUP; i++) {
- if (!sd->itemgrouphealrate[i])
- continue;
- ARR_FIND( 0, itemgroup_db[i].qty, j, itemgroup_db[i].nameid[j] == itemid );
- if( j < itemgroup_db[i].qty )
- bonus += sd->itemgrouphealrate[i];
- }
- return bonus;
+int itemdb_searchrandomid(struct item_group *group) {
+
+ if (group->qty)
+ return group->nameid[rnd()%group->qty];
+
+ ShowError("itemdb_searchrandomid: No item entries for group id %d\n", group->id);
+ return UNKNOWN_ITEM_ID;
+}
+bool itemdb_in_group(struct item_group *group, int nameid) {
+ int i;
+
+ for( i = 0; i < group->qty; i++ )
+ if( group->nameid[i] == nameid )
+ return true;
+
+ return false;
}
/// Searches for the item_data.
@@ -499,7 +593,7 @@ static bool itemdb_read_itemavail(char* str[], int columns, int current)
nameid = atoi(str[0]);
- if( ( id = itemdb_exists(nameid) ) == NULL )
+ if( ( id = itemdb->exists(nameid) ) == NULL )
{
ShowWarning("itemdb_read_itemavail: Invalid item id %d.\n", nameid);
return false;
@@ -520,82 +614,303 @@ static bool itemdb_read_itemavail(char* str[], int columns, int current)
return true;
}
-/*==========================================
- * read item group data
- *------------------------------------------*/
-static unsigned int itemdb_read_itemgroup_sub(const char* filename) {
- FILE *fp;
- char line[1024];
- int ln=0;
- unsigned int count = 0;
- int groupid,j,k,nameid;
- char *str[3],*p;
- char w1[1024], w2[1024];
-
- if( (fp=fopen(filename,"r"))==NULL ){
- ShowError("can't read %s\n", filename);
- return 0;
- }
+void itemdb_read_groups(void) {
+ config_t item_group_conf;
+ config_setting_t *itg = NULL, *it = NULL;
+#ifdef RENEWAL
+ const char *config_filename = "db/re/item_group.conf"; // FIXME hardcoded name
+#else
+ const char *config_filename = "db/pre-re/item_group.conf"; // FIXME hardcoded name
+#endif
+ const char *itname;
+ int i = 0, count = 0, c;
+ unsigned int *gsize = NULL;
- while(fgets(line, sizeof(line), fp))
- {
- ln++;
- if(line[0]=='/' && line[1]=='/')
+ if (conf_read_file(&item_group_conf, config_filename)) {
+ ShowError("can't read %s\n", config_filename);
+ return;
+ }
+
+ gsize = aMalloc( config_setting_length(item_group_conf.root) * sizeof(unsigned int) );
+
+ for(i = 0; i < config_setting_length(item_group_conf.root); i++)
+ gsize[i] = 0;
+
+ i = 0;
+ while( (itg = config_setting_get_elem(item_group_conf.root,i++)) ) {
+ const char *name = config_setting_name(itg);
+
+ if( !itemdb->name2id(name) ) {
+ ShowWarning("itemdb_read_groups: unknown group item '%s', skipping..\n",name);
+ config_setting_remove(item_group_conf.root, name);
+ --i;
continue;
- if(strstr(line,"import")) {
- if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2 &&
- strcmpi(w1, "import") == 0) {
- count += itemdb_read_itemgroup_sub(w2);
- continue;
- }
}
- memset(str,0,sizeof(str));
- for(j=0,p=line;j<3 && p;j++){
- str[j]=p;
- p=strchr(p,',');
- if(p) *p++=0;
+
+ c = 0;
+ while( (it = config_setting_get_elem(itg,c++)) ) {
+ if( config_setting_is_list(it) )
+ gsize[ i - 1 ] += config_setting_get_int_elem(it,1);
+ else
+ gsize[ i - 1 ] += 1;
}
- if(str[0]==NULL)
- continue;
- if (j<3) {
- if (j>1) //Or else it barks on blank lines...
- ShowWarning("itemdb_read_itemgroup: Insufficient fields for entry at %s:%d\n", filename, ln);
- continue;
+
+ }
+
+ i = 0;
+ CREATE(itemdb->groups, struct item_group, config_setting_length(item_group_conf.root));
+ itemdb->group_count = (unsigned short)config_setting_length(item_group_conf.root);
+
+ while( (itg = config_setting_get_elem(item_group_conf.root,i++)) ) {
+ struct item_data *data = itemdb->name2id(config_setting_name(itg));
+ int ecount = 0;
+
+ data->group = &itemdb->groups[count];
+
+ itemdb->groups[count].id = data->nameid;
+ itemdb->groups[count].qty = config_setting_length(itg);
+
+ CREATE(itemdb->groups[count].nameid, unsigned short, gsize[ count ] + 1);
+
+ c = 0;
+ while( (it = config_setting_get_elem(itg,c++)) ) {
+ int repeat = 1;
+ if( config_setting_is_list(it) ) {
+ itname = config_setting_get_string_elem(it,0);
+ repeat = config_setting_get_int_elem(it,1);
+ } else
+ itname = config_setting_get_string_elem(itg,c - 1);
+
+ if( !( data = itemdb->name2id(itname) ) )
+ ShowWarning("itemdb_read_groups: unknown item '%s' in group '%s'!\n",itname,config_setting_name(itg));
+
+ itemdb->groups[count].nameid[ecount] = data ? data->nameid : 0;
+ if( repeat > 1 ) {
+ //memset would be better? I failed to get the following to work though hu
+ //memset(&itemdb->groups[count].nameid[ecount+1],itemdb->groups[count].nameid[ecount],sizeof(itemdb->groups[count].nameid[0])*repeat);
+ int z;
+ for( z = ecount+1; z < ecount+repeat; z++ )
+ itemdb->groups[count].nameid[z] = itemdb->groups[count].nameid[ecount];
+ }
+ ecount += repeat;
}
- groupid = atoi(str[0]);
- if (groupid < 0 || groupid >= MAX_ITEMGROUP) {
- ShowWarning("itemdb_read_itemgroup: Invalid group %d in %s:%d\n", groupid, filename, ln);
+
+ count++;
+ }
+
+ config_destroy(&item_group_conf);
+ aFree(gsize);
+
+ ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, config_filename);
+}
+
+void itemdb_read_packages(void) {
+ config_t item_packages_conf;
+ config_setting_t *itg = NULL, *it = NULL, *t = NULL;
+#ifdef RENEWAL
+ const char *config_filename = "db/re/item_packages.conf"; // FIXME hardcoded name
+#else
+ const char *config_filename = "db/pre-re/item_packages.conf"; // FIXME hardcoded name
+#endif
+ const char *itname;
+ int i = 0, count = 0, c = 0;
+ unsigned int *must = NULL, *random = NULL;
+
+ if (conf_read_file(&item_packages_conf, config_filename)) {
+ ShowError("can't read %s\n", config_filename);
+ return;
+ }
+
+ must = aMalloc( config_setting_length(item_packages_conf.root) * sizeof(unsigned int) );
+ random = aMalloc( config_setting_length(item_packages_conf.root) * sizeof(unsigned int) );
+
+ for(i = 0; i < config_setting_length(item_packages_conf.root); i++) {
+ must[i] = 0;
+ random[i] = 0;
+ }
+
+ i = 0;
+ while( (itg = config_setting_get_elem(item_packages_conf.root,i++)) ) {
+ const char *name = config_setting_name(itg);
+
+ if( !itemdb->name2id(name) ) {
+ ShowWarning("itemdb_read_packages: unknown package item '%s', skipping..\n",name);
+ config_setting_remove(item_packages_conf.root, name);
+ --i;
continue;
}
- nameid = atoi(str[1]);
- if (!itemdb_exists(nameid)) {
- ShowWarning("itemdb_read_itemgroup: Non-existant item %d in %s:%d\n", nameid, filename, ln);
- continue;
+
+ c = 0;
+ while( (it = config_setting_get_elem(itg,c++)) ) {
+ if( ( t = config_setting_get_member(it, "Random")) && !config_setting_get_bool(t) )
+ must[ i - 1 ] += 1;
+ else
+ random[ i - 1 ] += 1;
}
- k = atoi(str[2]);
- if (itemgroup_db[groupid].qty+k >= MAX_RANDITEM) {
- ShowWarning("itemdb_read_itemgroup: Group %d is full (%d entries) in %s:%d\n", groupid, MAX_RANDITEM, filename, ln);
- continue;
+
+ }
+
+ CREATE(itemdb->packages, struct item_package, config_setting_length(item_packages_conf.root));
+ itemdb->package_count = (unsigned short)config_setting_length(item_packages_conf.root);
+
+ i = 0;
+ while( (itg = config_setting_get_elem(item_packages_conf.root,i++)) ) {
+ struct item_data *data = itemdb->name2id(config_setting_name(itg));
+ struct item_package_rand_entry *prev = NULL;
+ int r = 0, m = 0;
+
+ data->package = &itemdb->packages[count];
+
+ itemdb->packages[count].id = data->nameid;
+ itemdb->packages[count].random_list = NULL;
+ itemdb->packages[count].must_items = NULL;
+ itemdb->packages[count].random_qty = random[ i - 1 ];
+ itemdb->packages[count].must_qty = must[ i - 1 ];
+
+ if( itemdb->packages[count].random_qty )
+ CREATE(itemdb->packages[count].random_list, struct item_package_rand_entry, itemdb->packages[count].random_qty);
+ if( itemdb->packages[count].must_qty )
+ CREATE(itemdb->packages[count].must_items, struct item_package_must_entry, itemdb->packages[count].must_qty);
+
+ c = 0;
+ while( (it = config_setting_get_elem(itg,c++)) ) {
+ int icount = 1, expire = 0, rate = 10000;
+ bool announce = false, named = false;
+
+ itname = config_setting_name(it);
+
+ if( !( data = itemdb->name2id(itname) ) )
+ ShowWarning("itemdb_read_packages: unknown item '%s' in package '%s'!\n",itname,config_setting_name(itg));
+
+ if( ( t = config_setting_get_member(it, "Count")) )
+ icount = config_setting_get_int(t);
+
+ if( ( t = config_setting_get_member(it, "Expire")) )
+ expire = config_setting_get_int(t);
+
+ if( ( t = config_setting_get_member(it, "Rate")) ) {
+ if( (rate = (unsigned short)config_setting_get_int(t)) > 10000 ) {
+ ShowWarning("itemdb_read_packages: invalid rate (%d) for item '%s' in package '%s'!\n",itname,config_setting_name(itg));
+ rate = 10000;
+ }
+ }
+
+ if( ( t = config_setting_get_member(it, "Announce")) && config_setting_get_bool(t) )
+ announce = true;
+
+ if( ( t = config_setting_get_member(it, "Named")) && config_setting_get_bool(t) )
+ named = true;
+
+ if( ( t = config_setting_get_member(it, "Random")) && !config_setting_get_bool(t) ) {
+ itemdb->packages[count].must_items[m].id = data ? data->nameid : 0;
+ itemdb->packages[count].must_items[m].qty = icount;
+ itemdb->packages[count].must_items[m].hours = expire;
+ itemdb->packages[count].must_items[m].announce = announce == true ? 1 : 0;
+ itemdb->packages[count].must_items[m].named = named == true ? 1 : 0;
+ m++;
+ } else {
+ if( prev )
+ prev->next = &itemdb->packages[count].random_list[r];
+
+ itemdb->packages[count].random_list[r].id = data ? data->nameid : 0;
+ itemdb->packages[count].random_list[r].qty = icount;
+ if( (itemdb->packages[count].random_list[r].rate = rate) == 10000 ) {
+ ShowWarning("itemdb_read_packages: item '%s' in '%s' has 100% drop rate!! set this item as 'Random: false' or other items won't drop!!!\n",itname,config_setting_name(itg));
+ }
+ itemdb->packages[count].random_list[r].hours = expire;
+ itemdb->packages[count].random_list[r].announce = announce == true ? 1 : 0;
+ itemdb->packages[count].random_list[r].named = named == true ? 1 : 0;
+
+ prev = &itemdb->packages[count].random_list[r];
+
+ r++;
+ }
+
+ }
+
+ if( prev )
+ prev->next = &itemdb->packages[count].random_list[0];
+
+ if( itemdb->packages[count].random_qty == 1 ) {
+ //item packages dont stop looping until something comes out of them, so if you have only one item in it the drop is guaranteed.
+ ShowWarning("itemdb_read_packages: '%s' has only 1 random option, drop rate will be 100%!\n",itemdb_name(itemdb->packages[count].id));
+ itemdb->packages[count].random_list[0].rate = 10000;
}
- for(j=0;j<k;j++)
- itemgroup_db[groupid].nameid[itemgroup_db[groupid].qty++] = nameid;
+
count++;
}
- fclose(fp);
- return count;
+
+
+ config_destroy(&item_packages_conf);
+ aFree(must);
+ aFree(random);
+
+ ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, config_filename);
}
-static void itemdb_read_itemgroup(void)
-{
- char path[256];
- unsigned int count;
- snprintf(path, 255, "%s/"DBPATH"item_group_db.txt", iMap->db_path);
- memset(&itemgroup_db, 0, sizeof(itemgroup_db));
- count = itemdb_read_itemgroup_sub(path);
- ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, "item_group_db.txt");
- return;
+void itemdb_read_chains(void) {
+ config_t item_chain_conf;
+ config_setting_t *itc = NULL, *entry = NULL;
+#ifdef RENEWAL
+ const char *config_filename = "db/re/item_chain.conf"; // FIXME hardcoded name
+#else
+ const char *config_filename = "db/pre-re/item_chain.conf"; // FIXME hardcoded name
+#endif
+ int i = 0, count = 0;
+
+ if (conf_read_file(&item_chain_conf, config_filename)) {
+ ShowError("can't read %s\n", config_filename);
+ return;
+ }
+
+ CREATE(itemdb->chains, struct item_chain, config_setting_length(item_chain_conf.root));
+ itemdb->chain_count = (unsigned short)config_setting_length(item_chain_conf.root);
+
+ while( (itc = config_setting_get_elem(item_chain_conf.root,i++)) ) {
+ struct item_data *data = NULL;
+ struct item_chain_entry *prev = NULL;
+ const char *name = config_setting_name(itc);
+ int c = 0;
+
+ script->set_constant2(name,i-1,0);
+ itemdb->chains[count].qty = (unsigned short)config_setting_length(itc);
+
+ CREATE(itemdb->chains[count].items, struct item_chain_entry, config_setting_length(itc));
+
+ while( (entry = config_setting_get_elem(itc,c++)) ) {
+ const char *itname = config_setting_name(entry);
+ if( itname[0] == 'I' && itname[1] == 'D' && strlen(itname) < 7 ) {
+ if( !( data = itemdb->exists(atoi(itname+2)) ) )
+ ShowWarning("itemdb_read_chains: unknown item ID '%d' in chain '%s'!\n",atoi(itname+2),name);
+ } else if( !( data = itemdb->name2id(itname) ) )
+ ShowWarning("itemdb_read_chains: unknown item '%s' in chain '%s'!\n",itname,name);
+
+ if( prev )
+ prev->next = &itemdb->chains[count].items[c - 1];
+
+ itemdb->chains[count].items[c - 1].id = data ? data->nameid : 0;
+ itemdb->chains[count].items[c - 1].rate = data ? config_setting_get_int(entry) : 0;
+
+ prev = &itemdb->chains[count].items[c - 1];
+ }
+
+ if( prev )
+ prev->next = &itemdb->chains[count].items[0];
+
+ count++;
+ }
+
+ config_destroy(&item_chain_conf);
+
+ if( !script->get_constant("ITMCHAIN_ORE",&i) )
+ ShowWarning("itemdb_read_chains: failed to find 'ITMCHAIN_ORE' chain to link to cache!\n");
+ else
+ itemdb->chain_cache[ECC_ORE] = i;
+
+ ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, config_filename);
}
+
/*==========================================
* Reads item trade restrictions [Skotlex]
*------------------------------------------*/
@@ -606,7 +921,7 @@ static bool itemdb_read_itemtrade(char* str[], int columns, int current)
nameid = atoi(str[0]);
- if( ( id = itemdb_exists(nameid) ) == NULL )
+ if( ( id = itemdb->exists(nameid) ) == NULL )
{
//ShowWarning("itemdb_read_itemtrade: Invalid item id %d.\n", nameid);
//return false;
@@ -643,7 +958,7 @@ static bool itemdb_read_itemdelay(char* str[], int columns, int current)
nameid = atoi(str[0]);
- if( ( id = itemdb_exists(nameid) ) == NULL )
+ if( ( id = itemdb->exists(nameid) ) == NULL )
{
ShowWarning("itemdb_read_itemdelay: Invalid item id %d.\n", nameid);
return false;
@@ -673,7 +988,7 @@ static bool itemdb_read_stack(char* fields[], int columns, int current)
nameid = (unsigned short)strtoul(fields[0], NULL, 10);
- if( ( id = itemdb_exists(nameid) ) == NULL )
+ if( ( id = itemdb->exists(nameid) ) == NULL )
{
ShowWarning("itemdb_read_stack: Unknown item id '%hu'.\n", nameid);
return false;
@@ -711,7 +1026,7 @@ static bool itemdb_read_buyingstore(char* fields[], int columns, int current)
nameid = atoi(fields[0]);
- if( ( id = itemdb_exists(nameid) ) == NULL )
+ if( ( id = itemdb->exists(nameid) ) == NULL )
{
ShowWarning("itemdb_read_buyingstore: Invalid item id %d.\n", nameid);
return false;
@@ -738,7 +1053,7 @@ static bool itemdb_read_nouse(char* fields[], int columns, int current)
nameid = atoi(fields[0]);
- if( ( id = itemdb_exists(nameid) ) == NULL ) {
+ if( ( id = itemdb->exists(nameid) ) == NULL ) {
ShowWarning("itemdb_read_nouse: Invalid item id %d.\n", nameid);
return false;
}
@@ -847,7 +1162,7 @@ void itemdb_read_combos() {
/* validate */
for(v = 0; v < retcount; v++) {
- if( !itemdb_exists(items[v]) ) {
+ if( !itemdb->exists(items[v]) ) {
ShowError("itemdb_read_combos: line %d of \"%s\" contains unknown item ID %d, skipping.\n", lines, path,items[v]);
break;
}
@@ -856,7 +1171,7 @@ void itemdb_read_combos() {
if( v < retcount )
continue;
- id = itemdb_exists(items[0]);
+ id = itemdb->exists(items[0]);
idx = id->combos_count;
@@ -885,7 +1200,7 @@ void itemdb_read_combos() {
struct item_data * it;
int index;
- it = itemdb_exists(items[v]);
+ it = itemdb->exists(items[v]);
index = it->combos_count;
@@ -1095,6 +1410,7 @@ int itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt)
if (*str[21+offset])
id->unequip_script = parse_script(str[21+offset], source, line, scriptopt);
+ strdb_put(itemdb->names, id->name, id);
return id->nameid;
}
@@ -1321,14 +1637,16 @@ int itemdb_uid_load() {
* read all item-related databases
*------------------------------------*/
static void itemdb_read(void) {
-
if (iMap->db_use_sqldbs)
itemdb_read_sqldb();
else
itemdb_readdb();
itemdb_read_combos();
- itemdb_read_itemgroup();
+ itemdb->read_groups();
+ itemdb->read_chains();
+ itemdb->read_packages();
+
sv->readdb(iMap->db_path, "item_avail.txt", ',', 2, 2, -1, &itemdb_read_itemavail);
sv->readdb(iMap->db_path, DBPATH"item_trade.txt", ',', 3, 3, -1, &itemdb_read_itemtrade);
sv->readdb(iMap->db_path, "item_delay.txt", ',', 2, 2, -1, &itemdb_read_itemdelay);
@@ -1336,6 +1654,9 @@ static void itemdb_read(void) {
sv->readdb(iMap->db_path, DBPATH"item_buyingstore.txt", ',', 1, 1, -1, &itemdb_read_buyingstore);
sv->readdb(iMap->db_path, "item_nouse.txt", ',', 3, 3, -1, &itemdb_read_nouse);
+
+ itemdb->name_constants();
+
itemdb_uid_load();
}
@@ -1388,8 +1709,7 @@ static int itemdb_final_sub(DBKey key, DBData *data, va_list ap)
return 0;
}
-void itemdb_reload(void)
-{
+void itemdb_reload(void) {
struct s_mapiterator* iter;
struct map_session_data* sd;
@@ -1400,9 +1720,46 @@ void itemdb_reload(void)
if( itemdb_array[i] )
destroy_item_data(itemdb_array[i], 1);
+ for( i = 0; i < itemdb->group_count; i++ ) {
+ if( itemdb->groups[i].nameid )
+ aFree(itemdb->groups[i].nameid);
+ }
+
+ if( itemdb->groups )
+ aFree(itemdb->groups);
+
+ itemdb->groups = NULL;
+ itemdb->group_count = 0;
+
+ for( i = 0; i < itemdb->chain_count; i++ ) {
+ if( itemdb->chains[i].items )
+ aFree(itemdb->chains[i].items);
+ }
+
+ if( itemdb->chains )
+ aFree(itemdb->chains);
+
+ itemdb->chains = NULL;
+ itemdb->chain_count = 0;
+
+ for( i = 0; i < itemdb->package_count; i++ ) {
+ if( itemdb->packages[i].random_list )
+ aFree(itemdb->packages[i].random_list);
+ if( itemdb->packages[i].must_items )
+ aFree(itemdb->packages[i].must_items);
+ }
+
+ if( itemdb->packages )
+ aFree(itemdb->packages);
+
+ itemdb->packages = NULL;
+ itemdb->package_count = 0;
+
itemdb_other->clear(itemdb_other, itemdb_final_sub);
-
+
memset(itemdb_array, 0, sizeof(itemdb_array));
+
+ db_clear(itemdb->names);
// read new data
itemdb_read();
@@ -1454,34 +1811,94 @@ void itemdb_reload(void)
}
mapit->free(iter);
}
+void itemdb_name_constants(void) {
+ DBIterator *iter = db_iterator(itemdb->names);
+ struct item_data *data;
+
+ for( data = dbi_first(iter); dbi_exists(iter); data = dbi_next(iter) )
+ script->set_constant2(data->name,data->nameid,0);
-void do_final_itemdb(void)
-{
+ dbi_destroy(iter);
+}
+void do_final_itemdb(void) {
int i;
for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
if( itemdb_array[i] )
destroy_item_data(itemdb_array[i], 1);
+ for( i = 0; i < itemdb->group_count; i++ ) {
+ if( itemdb->groups[i].nameid )
+ aFree(itemdb->groups[i].nameid);
+ }
+
+ if( itemdb->groups )
+ aFree(itemdb->groups);
+
+ for( i = 0; i < itemdb->chain_count; i++ ) {
+ if( itemdb->chains[i].items )
+ aFree(itemdb->chains[i].items);
+ }
+
+ if( itemdb->chains )
+ aFree(itemdb->chains);
+
+ for( i = 0; i < itemdb->package_count; i++ ) {
+ if( itemdb->packages[i].random_list )
+ aFree(itemdb->packages[i].random_list);
+ if( itemdb->packages[i].must_items )
+ aFree(itemdb->packages[i].must_items);
+ }
+
+ if( itemdb->packages )
+ aFree(itemdb->packages);
+
itemdb_other->destroy(itemdb_other, itemdb_final_sub);
destroy_item_data(&dummy_item, 0);
+ db_destroy(itemdb->names);
}
-int do_init_itemdb(void) {
+void do_init_itemdb(void) {
memset(itemdb_array, 0, sizeof(itemdb_array));
itemdb_other = idb_alloc(DB_OPT_BASE);
+ itemdb->names = strdb_alloc(DB_OPT_BASE,ITEM_NAME_LENGTH);
create_dummy_data(); //Dummy data item.
itemdb_read();
clif->cashshop_load();
-
- return 0;
}
/* incomplete */
void itemdb_defaults(void) {
itemdb = &itemdb_s;
- itemdb->reload = itemdb_reload;//incomplet=e
+ itemdb->init = do_init_itemdb;
+ itemdb->final = do_final_itemdb;
+ itemdb->reload = itemdb_reload;//incomplete
+ itemdb->name_constants = itemdb_name_constants;
+ /* */
+ itemdb->groups = NULL;
+ itemdb->group_count = 0;
+ /* */
+ itemdb->chains = NULL;
+ itemdb->chain_count = 0;
+ /* */
+ itemdb->packages = NULL;
+ itemdb->package_count = 0;
+ /* */
+ itemdb->names = NULL;
+ /* */
+ itemdb->read_groups = itemdb_read_groups;
+ itemdb->read_chains = itemdb_read_chains;
+ itemdb->read_packages = itemdb_read_packages;
/* */
+ itemdb->search_name = itemdb_searchname;
+ itemdb->search_name_array = itemdb_searchname_array;
+ itemdb->load = itemdb_load;
+ itemdb->search = itemdb_search;
itemdb->parse_dbrow = itemdb_parse_dbrow;
itemdb->exists = itemdb_exists;//incomplete
+ itemdb->name2id = itemdb_name2id;
+ itemdb->in_group = itemdb_in_group;
+ itemdb->group_item = itemdb_searchrandomid;
+ itemdb->chain_item = itemdb_chain_item;
+ itemdb->package_item = itemdb_package_item;
}
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index 44b455d80..5e870a5f2 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -9,18 +9,29 @@
#include "../common/mmo.h" // ITEM_NAME_LENGTH
#include "map.h"
-// 32k array entries in array (the rest goes to the db)
-#define MAX_ITEMDB 0x8000
+/**
+ * Declarations
+ **/
+struct item_group;
+struct item_package;
-#define MAX_RANDITEM 11000
+/**
+ * Defines
+ **/
+#define MAX_ITEMDB 0x8000 // 32k array entries in array (the rest goes to the db)
+#define MAX_ITEMDELAYS 10 // The maximum number of item delays
+#define MAX_SEARCH 5 //Designed for search functions, species max number of matches to display.
+#define MAX_ITEMS_PER_COMBO 6 /* maximum amount of items a combo may require */
-// The maximum number of item delays
-#define MAX_ITEMDELAYS 10
+#define CARD0_FORGE 0x00FF
+#define CARD0_CREATE 0x00FE
+#define CARD0_PET ((short)0xFF00)
-#define MAX_SEARCH 5 //Designed for search functions, species max number of matches to display.
+//Marks if the card0 given is "special" (non-item id used to mark pets/created items. [Skotlex]
+#define itemdb_isspecial(i) (i == CARD0_FORGE || i == CARD0_CREATE || i == CARD0_PET)
-/* maximum amount of items a combo may require */
-#define MAX_ITEMS_PER_COMBO 6
+//Use apple for unknown items.
+#define UNKNOWN_ITEM_ID 512
enum item_itemid {
ITEMID_HOLY_WATER = 523,
@@ -76,21 +87,12 @@ enum {
NOUSE_SITTING = 0x01,
} item_nouse_list;
-//The only item group required by the code to be known. See const.txt for the full list.
-#define IG_FINDINGORE 6
-#define IG_POTION 37
-//The max. item group count (increase this when needed).
-#define MAX_ITEMGROUP 63
-
-#define CARD0_FORGE 0x00FF
-#define CARD0_CREATE 0x00FE
-#define CARD0_PET ((short)0xFF00)
-
-//Marks if the card0 given is "special" (non-item id used to mark pets/created items. [Skotlex]
-#define itemdb_isspecial(i) (i == CARD0_FORGE || i == CARD0_CREATE || i == CARD0_PET)
-
-//Use apple for unknown items.
-#define UNKNOWN_ITEM_ID 512
+//
+enum e_chain_cache {
+ ECC_ORE,
+ /* */
+ ECC_MAX,
+};
struct item_data {
uint16 nameid;
@@ -152,11 +154,9 @@ struct item_data {
/* bugreport:309 */
struct item_combo **combos;
unsigned char combos_count;
-};
-
-struct item_group {
- int nameid[MAX_RANDITEM];
- int qty; //Counts amount of items in the group.
+ /* TODO add a pointer to some sort of (struct extra) and gather all the not-common vals into it to save memory */
+ struct item_group *group;
+ struct item_package *package;
};
struct item_combo {
@@ -167,29 +167,65 @@ struct item_combo {
bool isRef;/* whether this struct is a reference or the master */
};
-struct item_group itemgroup_db[MAX_ITEMGROUP];
-
-struct item_data* itemdb_searchname(const char *name);
-int itemdb_searchname_array(struct item_data** data, int size, const char *str);
-struct item_data* itemdb_load(int nameid);
-struct item_data* itemdb_search(int nameid);
-struct item_data* itemdb_exists(int nameid);
-#define itemdb_name(n) itemdb_search(n)->name
-#define itemdb_jname(n) itemdb_search(n)->jname
-#define itemdb_type(n) itemdb_search(n)->type
-#define itemdb_atk(n) itemdb_search(n)->atk
-#define itemdb_def(n) itemdb_search(n)->def
-#define itemdb_look(n) itemdb_search(n)->look
-#define itemdb_weight(n) itemdb_search(n)->weight
-#define itemdb_equip(n) itemdb_search(n)->equip
-#define itemdb_usescript(n) itemdb_search(n)->script
-#define itemdb_equipscript(n) itemdb_search(n)->script
-#define itemdb_wlv(n) itemdb_search(n)->wlv
-#define itemdb_range(n) itemdb_search(n)->range
-#define itemdb_slot(n) itemdb_search(n)->slot
-#define itemdb_available(n) (itemdb_search(n)->flag.available)
-#define itemdb_viewid(n) (itemdb_search(n)->view_id)
-#define itemdb_autoequip(n) (itemdb_search(n)->flag.autoequip)
+struct item_group {
+ unsigned short id;
+ unsigned short *nameid;
+ unsigned short qty;
+};
+
+struct item_chain_entry {
+ unsigned short id;
+ unsigned short rate;
+ struct item_chain_entry *next;
+};
+
+struct item_chain {
+ struct item_chain_entry *items;
+ unsigned short qty;
+};
+
+struct item_package_rand_entry {
+ unsigned short id;
+ unsigned short qty;
+ unsigned short rate;
+ unsigned short hours;
+ unsigned int announce : 1;
+ unsigned int named : 1;
+ struct item_package_rand_entry *next;
+};
+
+struct item_package_must_entry {
+ unsigned short id;
+ unsigned short qty;
+ unsigned short hours;
+ unsigned int announce : 1;
+ unsigned int named : 1;
+};
+
+struct item_package {
+ unsigned short id;
+ struct item_package_rand_entry *random_list;
+ struct item_package_must_entry *must_items;
+ unsigned short random_qty;
+ unsigned short must_qty;
+};
+
+#define itemdb_name(n) itemdb->search(n)->name
+#define itemdb_jname(n) itemdb->search(n)->jname
+#define itemdb_type(n) itemdb->search(n)->type
+#define itemdb_atk(n) itemdb->search(n)->atk
+#define itemdb_def(n) itemdb->search(n)->def
+#define itemdb_look(n) itemdb->search(n)->look
+#define itemdb_weight(n) itemdb->search(n)->weight
+#define itemdb_equip(n) itemdb->search(n)->equip
+#define itemdb_usescript(n) itemdb->search(n)->script
+#define itemdb_equipscript(n) itemdb->search(n)->script
+#define itemdb_wlv(n) itemdb->search(n)->wlv
+#define itemdb_range(n) itemdb->search(n)->range
+#define itemdb_slot(n) itemdb->search(n)->slot
+#define itemdb_available(n) (itemdb->search(n)->flag.available)
+#define itemdb_viewid(n) (itemdb->search(n)->view_id)
+#define itemdb_autoequip(n) (itemdb->search(n)->flag.autoequip)
#define itemdb_is_rune(n) (n >= ITEMID_NAUTHIZ && n <= ITEMID_HAGALAZ)
#define itemdb_is_element(n) (n >= 990 && n <= 993)
#define itemdb_is_spellbook(n) (n >= 6188 && n <= 6205)
@@ -200,12 +236,9 @@ struct item_data* itemdb_exists(int nameid);
#define itemdb_is_GNthrowable(n) (n >= 13268 && n <= 13290)
const char* itemdb_typename(int type);
-int itemdb_group_bonus(struct map_session_data* sd, int itemid);
-int itemdb_searchrandomid(int flags);
-
-#define itemdb_value_buy(n) itemdb_search(n)->value_buy
-#define itemdb_value_sell(n) itemdb_search(n)->value_sell
-#define itemdb_canrefine(n) (!itemdb_search(n)->flag.no_refine)
+#define itemdb_value_buy(n) itemdb->search(n)->value_buy
+#define itemdb_value_sell(n) itemdb->search(n)->value_sell
+#define itemdb_canrefine(n) (!itemdb->search(n)->flag.no_refine)
//Item trade restrictions [Skotlex]
int itemdb_isdropable_sub(struct item_data *, int, int);
int itemdb_cantrade_sub(struct item_data*, int, int);
@@ -235,17 +268,40 @@ int itemdb_isstackable(int);
int itemdb_isstackable2(struct item_data *);
uint64 itemdb_unique_id(int8 flag, int64 value); // Unique Item ID
-void itemdb_reload(void);
-
-void do_final_itemdb(void);
-int do_init_itemdb(void);
-
/* incomplete */
struct itemdb_interface {
+ void (*init) (void);
+ void (*final) (void);
void (*reload) (void);
+ void (*name_constants) (void);
+ /* */
+ struct item_group *groups;
+ unsigned short group_count;
+ /* */
+ struct item_chain *chains;
+ unsigned short chain_count;
+ unsigned short chain_cache[ECC_MAX];
+ /* */
+ struct item_package *packages;
+ unsigned short package_count;
+ /* */
+ DBMap *names;
+ /* */
+ void (*read_groups) (void);
+ void (*read_chains) (void);
+ void (*read_packages) (void);
/* */
+ struct item_data* (*name2id) (const char *str);
+ struct item_data* (*search_name) (const char *name);
+ int (*search_name_array) (struct item_data** data, int size, const char *str);
+ struct item_data* (*load)(int nameid);
+ struct item_data* (*search)(int nameid);
int (*parse_dbrow) (char** str, const char* source, int line, int scriptopt);
struct item_data* (*exists) (int nameid);
+ bool (*in_group) (struct item_group *group, int nameid);
+ int (*group_item) (struct item_group *group);
+ int (*chain_item) (unsigned short chain_id, int *rate);
+ void (*package_item) (struct map_session_data *sd, struct item_package *package);
} itemdb_s;
struct itemdb_interface *itemdb;
diff --git a/src/map/log.c b/src/map/log.c
index dfb4c4a61..ae516b84e 100644
--- a/src/map/log.c
+++ b/src/map/log.c
@@ -187,14 +187,14 @@ void log_pick(int id, int16 m, e_log_pick_type type, int amount, struct item* it
/// logs item transactions (players)
void log_pick_pc(struct map_session_data* sd, e_log_pick_type type, int amount, struct item* itm, struct item_data *data) {
nullpo_retv(sd);
- log_pick(sd->status.char_id, sd->bl.m, type, amount, itm, data ? data : itemdb_exists(itm->nameid));
+ log_pick(sd->status.char_id, sd->bl.m, type, amount, itm, data ? data : itemdb->exists(itm->nameid));
}
/// logs item transactions (monsters)
void log_pick_mob(struct mob_data* md, e_log_pick_type type, int amount, struct item* itm, struct item_data *data) {
nullpo_retv(md);
- log_pick(md->class_, md->bl.m, type, amount, itm, data ? data : itemdb_exists(itm->nameid));
+ log_pick(md->class_, md->bl.m, type, amount, itm, data ? data : itemdb->exists(itm->nameid));
}
void log_zeny_sub_sql(struct map_session_data* sd, e_log_pick_type type, struct map_session_data* src_sd, int amount) {
if( SQL_ERROR == SQL->Query(logmysql_handle, LOG_QUERY " INTO `%s` (`time`, `char_id`, `src_id`, `type`, `amount`, `map`) VALUES (NOW(), '%d', '%d', '%c', '%d', '%s')",
diff --git a/src/map/map.c b/src/map/map.c
index 5f86286e9..ee56f140f 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -1566,7 +1566,7 @@ void map_reqnickdb(struct map_session_data * sd, int charid)
CREATE(req, struct charid_request, 1);
req->next = p->requests;
p->requests = req;
- chrif_searchcharid(charid);
+ chrif->searchcharid(charid);
}
/*==========================================
@@ -1629,11 +1629,11 @@ int map_quit(struct map_session_data *sd) {
int i;
if(!sd->state.active) { //Removing a player that is not active.
- struct auth_node *node = chrif_search(sd->status.account_id);
+ struct auth_node *node = chrif->search(sd->status.account_id);
if (node && node->char_id == sd->status.char_id &&
node->state != ST_LOGOUT)
//Except when logging out, clear the auth-connect data immediately.
- chrif_auth_delete(node->account_id, node->char_id, node->state);
+ chrif->auth_delete(node->account_id, node->char_id, node->state);
//Non-active players should not have loaded any data yet (or it was cleared already) so no additional cleanups are needed.
return 0;
}
@@ -1728,7 +1728,7 @@ int map_quit(struct map_session_data *sd) {
party->booking_delete(sd); // Party Booking [Spiria]
pc->makesavestatus(sd);
pc->clean_skilltree(sd);
- chrif_save(sd,1);
+ chrif->save(sd,1);
unit_free_pc(sd);
return 0;
}
@@ -1790,7 +1790,7 @@ const char* map_charid2nick(int charid)
if( *p->nick )
return p->nick;// name in nick_db
- chrif_searchcharid(charid);// request the name
+ chrif->searchcharid(charid);// request the name
return NULL;
}
@@ -3354,13 +3354,13 @@ int map_config_read(char *cfgName) {
if( msg_silent ) // only bother if its actually enabled
ShowInfo("Console Silent Setting: %d\n", atoi(w2));
} else if (strcmpi(w1, "userid")==0)
- chrif_setuserid(w2);
+ chrif->setuserid(w2);
else if (strcmpi(w1, "passwd") == 0)
- chrif_setpasswd(w2);
+ chrif->setpasswd(w2);
else if (strcmpi(w1, "char_ip") == 0)
- char_ip_set = chrif_setip(w2);
+ char_ip_set = chrif->setip(w2);
else if (strcmpi(w1, "char_port") == 0)
- chrif_setport(atoi(w2));
+ chrif->setport(atoi(w2));
else if (strcmpi(w1, "map_ip") == 0)
map_ip_set = clif->setip(w2);
else if (strcmpi(w1, "bind_ip") == 0)
@@ -3842,7 +3842,7 @@ bool map_zone_mf_cache(int m, char *flag, char *params) {
int drop_id = 0, drop_type = 0;
if (!strcmpi(drop_arg1, "random"))
drop_id = -1;
- else if (itemdb_exists((drop_id = atoi(drop_arg1))) == NULL)
+ else if (itemdb->exists((drop_id = atoi(drop_arg1))) == NULL)
drop_id = 0;
if (!strcmpi(drop_arg2, "inventory"))
drop_type = 1;
@@ -4441,11 +4441,11 @@ unsigned short map_zone_str2itemid(const char *name) {
if( !name )
return 0;
if( name[0] == 'I' && name[1] == 'D' && strlen(name) <= 7 ) {
- if( !( data = itemdb_exists(atoi(name+2))) ) {
+ if( !( data = itemdb->exists(atoi(name+2))) ) {
return 0;
}
} else {
- if( !( data = itemdb_searchname(name) ) ) {
+ if( !( data = itemdb->search_name(name) ) ) {
return 0;
}
}
@@ -5006,8 +5006,6 @@ void do_final(void)
iMap->quit(sd);
mapit->free(iter);
- instance->final();
-
/* prepares npcs for a faster shutdown process */
do_clear_npc();
@@ -5020,18 +5018,19 @@ void do_final(void)
ShowStatus("Cleaned up %d maps."CL_CLL"\n", iMap->map_num);
id_db->foreach(id_db,cleanup_db_sub);
- chrif_char_reset_offline();
- chrif_flush_fifo();
+ chrif->char_reset_offline();
+ chrif->flush_fifo();
atcommand->final();
battle->final();
- do_final_chrif();
+ chrif->do_final_chrif();
ircbot->final();/* before clif. */
clif->final();
do_final_npc();
script->final();
- do_final_itemdb();
- do_final_storage();
+ itemdb->final();
+ instance->final();
+ storage->final();
guild->final();
party->do_final_party();
pc->do_final_pc();
@@ -5076,7 +5075,7 @@ void do_final(void)
static int map_abort_sub(struct map_session_data* sd, va_list ap)
{
- chrif_save(sd,1);
+ chrif->save(sd,1);
return 1;
}
@@ -5094,7 +5093,7 @@ void do_abort(void)
return;
}
run = 1;
- if (!chrif_isconnected())
+ if (!chrif->isconnected())
{
if (pc_db->size(pc_db))
ShowFatalError("Server has crashed without a connection to the char-server, %u characters can't be saved!\n", pc_db->size(pc_db));
@@ -5102,7 +5101,7 @@ void do_abort(void)
}
ShowError("Server received crash signal! Attempting to save all online characters!\n");
iMap->map_foreachpc(map_abort_sub);
- chrif_flush_fifo();
+ chrif->flush_fifo();
}
/*======================================================
@@ -5162,7 +5161,7 @@ void do_shutdown(void)
mapit->free(iter);
flush_fifos();
}
- chrif_check_shutdown();
+ chrif->check_shutdown();
}
}
@@ -5234,8 +5233,11 @@ void map_hp_symbols(void) {
HPM->share(bg,"battlegrounds");
HPM->share(buyingstore,"buyingstore");
HPM->share(clif,"clif");
+ HPM->share(chrif,"chrif");
HPM->share(guild,"guild");
+ HPM->share(gstorage,"gstorage");
HPM->share(homun,"homun");
+ HPM->share(iMap,"iMap");
HPM->share(ircbot,"ircbot");
HPM->share(itemdb,"itemdb");
HPM->share(logs,"logs");
@@ -5246,8 +5248,8 @@ void map_hp_symbols(void) {
HPM->share(vending,"vending");
HPM->share(pc,"pc");
HPM->share(party,"party");
+ HPM->share(storage,"storage");
HPM->share(trade,"trade");
- HPM->share(iMap,"iMap");
/* partial */
HPM->share(mapit,"mapit");
/* sql link */
@@ -5265,7 +5267,9 @@ void load_defaults(void) {
battleground_defaults();
buyingstore_defaults();
clif_defaults();
+ chrif_defaults();
guild_defaults();
+ gstorage_defaults();
homunculus_defaults();
instance_defaults();
ircbot_defaults();
@@ -5279,6 +5283,7 @@ void load_defaults(void) {
vending_defaults();
pc_defaults();
party_defaults();
+ storage_defaults();
trade_defaults();
}
int do_init(int argc, char *argv[])
@@ -5395,7 +5400,7 @@ int do_init(int argc, char *argv[])
// loads npcs
iMap->reloadnpc(false);
- chrif_checkdefaultlogin();
+ chrif->checkdefaultlogin();
if (!map_ip_set || !char_ip_set) {
char ip_str[16];
@@ -5413,7 +5418,7 @@ int do_init(int argc, char *argv[])
if (!map_ip_set)
clif->setip(ip_str);
if (!char_ip_set)
- chrif_setip(ip_str);
+ chrif->setip(ip_str);
}
battle->config_read(iMap->BATTLE_CONF_FILENAME);
@@ -5458,11 +5463,11 @@ int do_init(int argc, char *argv[])
atcommand->init();
battle->init();
instance->init();
- do_init_chrif();
+ chrif->do_init_chrif();
clif->init();
ircbot->init();
script->init();
- do_init_itemdb();
+ itemdb->init();
skill->init();
read_map_zone_db();/* read after item and skill initalization */
do_init_mob();
@@ -5470,7 +5475,7 @@ int do_init(int argc, char *argv[])
do_init_status();
party->do_init_party();
guild->init();
- do_init_storage();
+ storage->init();
do_init_pet();
homun->init();
do_init_mercenary();
diff --git a/src/map/map.h b/src/map/map.h
index 3e7c45bc3..3b53b71cc 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -386,7 +386,7 @@ enum _sp {
SP_SUBSIZE, SP_HP_DRAIN_VALUE_RACE, SP_ADD_ITEM_HEAL_RATE, SP_SP_DRAIN_VALUE_RACE, SP_EXP_ADDRACE, // 2026-2030
SP_SP_GAIN_RACE, SP_SUBRACE2, SP_UNBREAKABLE_SHOES, // 2031-2033
SP_UNSTRIPABLE_WEAPON,SP_UNSTRIPABLE_ARMOR,SP_UNSTRIPABLE_HELM,SP_UNSTRIPABLE_SHIELD, // 2034-2037
- SP_INTRAVISION, SP_ADD_MONSTER_DROP_ITEMGROUP, SP_SP_LOSS_RATE, // 2038-2040
+ SP_INTRAVISION, SP_ADD_MONSTER_DROP_CHAINITEM, SP_SP_LOSS_RATE, // 2038-2040
SP_ADD_SKILL_BLOW, SP_SP_VANISH_RATE, SP_MAGIC_SP_GAIN_VALUE, SP_MAGIC_HP_GAIN_VALUE, SP_ADD_CLASS_DROP_ITEM, //2041-2045
SP_EMATK, SP_SP_GAIN_RACE_ATTACK, SP_HP_GAIN_RACE_ATTACK, SP_SKILL_USE_SP_RATE, //2046-2049
SP_SKILL_COOLDOWN,SP_SKILL_FIXEDCAST, SP_SKILL_VARIABLECAST, SP_FIXCASTRATE, SP_VARCASTRATE, //2050-2054
@@ -605,6 +605,7 @@ struct map_data {
unsigned reset :1; // [Daegaladh]
unsigned chsysnolocalaj : 1;
unsigned noknockback : 1;
+ unsigned notomb : 1;
} flag;
struct point save;
struct npc_data *npc[MAX_NPC_PER_MAP];
diff --git a/src/map/mob.c b/src/map/mob.c
index 6bb40478f..93ef81811 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -2330,7 +2330,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
{
if (md->db->dropitem[i].nameid <= 0)
continue;
- if ( !(it = itemdb_exists(md->db->dropitem[i].nameid)) )
+ if ( !(it = itemdb->exists(md->db->dropitem[i].nameid)) )
continue;
drop_rate = md->db->dropitem[i].p;
if (drop_rate <= 0) {
@@ -2394,9 +2394,11 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
}
// Ore Discovery [Celest]
- if (sd == mvp_sd && pc->checkskill(sd,BS_FINDINGORE)>0 && battle_config.finding_ore_rate/10 >= rnd()%10000) {
- ditem = mob_setdropitem(itemdb_searchrandomid(IG_FINDINGORE), 1, NULL);
- mob_item_drop(md, dlist, ditem, 0, battle_config.finding_ore_rate/10, homkillonly);
+ if (sd == mvp_sd && pc->checkskill(sd,BS_FINDINGORE) > 0) {
+ if( (temp = itemdb->chain_item(itemdb->chain_cache[ECC_ORE],&i)) ) {
+ ditem = mob_setdropitem(temp, 1, NULL);
+ mob_item_drop(md, dlist, ditem, 0, i, homkillonly);
+ }
}
if(sd) {
@@ -2424,8 +2426,9 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
if (rnd()%10000 >= drop_rate)
continue;
- itemid = (sd->add_drop[i].id > 0) ? sd->add_drop[i].id : itemdb_searchrandomid(sd->add_drop[i].group);
- mob_item_drop(md, dlist, mob_setdropitem(itemid,1,NULL), 0, drop_rate, homkillonly);
+ itemid = (sd->add_drop[i].id > 0) ? sd->add_drop[i].id : itemdb->chain_item(sd->add_drop[i].group,&drop_rate);
+ if( itemid )
+ mob_item_drop(md, dlist, mob_setdropitem(itemid,1,NULL), 0, drop_rate, homkillonly);
}
}
@@ -2504,7 +2507,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
struct item_data *data;
if(mdrop_id[i] <= 0)
continue;
- if(! (data = itemdb_exists(mdrop_id[i])) )
+ if(! (data = itemdb->exists(mdrop_id[i])) )
continue;
temp = mdrop_p[i];
@@ -2626,7 +2629,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
return 5; // Note: Actually, it's 4. Oh well...
// MvP tomb [GreenBox]
- if (battle_config.mvp_tomb_enabled && md->spawn->state.boss)
+ if (battle_config.mvp_tomb_enabled && md->spawn->state.boss && map[md->bl.m].flag.notomb != 1)
mvptomb_create(md, mvp_sd ? mvp_sd->status.name : NULL, time(NULL));
if( !rebirth ) {
@@ -3785,7 +3788,7 @@ static bool mob_parse_dbrow(char** str)
//calculate and store Max available drop chance of the MVP item
if (db->mvpitem[i].p) {
struct item_data *id;
- id = itemdb_search(db->mvpitem[i].nameid);
+ id = itemdb->search(db->mvpitem[i].nameid);
if (id->maxchance == -1 || (id->maxchance < db->mvpitem[i].p/10 + 1) ) {
//item has bigger drop chance or sold in shops
id->maxchance = db->mvpitem[i].p/10 + 1; //reduce MVP drop info to not spoil common drop rate
@@ -3803,7 +3806,7 @@ static bool mob_parse_dbrow(char** str)
db->dropitem[i].p = 0; //No drop.
continue;
}
- id = itemdb_search(db->dropitem[i].nameid);
+ id = itemdb->search(db->dropitem[i].nameid);
type = id->type;
rate = atoi(str[k+1]);
if( (class_ >= 1324 && class_ <= 1363) || (class_ >= 1938 && class_ <= 1946) )
@@ -4560,7 +4563,7 @@ static bool mob_readdb_itemratio(char* str[], int columns, int current)
int nameid, ratio, i;
nameid = atoi(str[0]);
- if( itemdb_exists(nameid) == NULL )
+ if( itemdb->exists(nameid) == NULL )
{
ShowWarning("itemdb_read_itemratio: Invalid item id %d.\n", nameid);
return false;
diff --git a/src/map/npc.c b/src/map/npc.c
index 46e6d0fd2..77758bc00 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -610,18 +610,14 @@ int npc_timerevent_start(struct npc_data* nd, int rid)
ShowError("npc_timerevent_start: Attached player not found!\n");
return 1;
}
-
// Check if timer is already started.
- if( sd )
- {
+ if( sd ) {
if( sd->npc_timer_id != INVALID_TIMER )
return 0;
- }
- else if( nd->u.scr.timerid != INVALID_TIMER || nd->u.scr.timertick )
+ } else if( nd->u.scr.timerid != INVALID_TIMER || nd->u.scr.timertick )
return 0;
- if (j < nd->u.scr.timeramount)
- {
+ if (j < nd->u.scr.timeramount) {
int next;
struct timer_event_data *ted;
// Arrange for the next event
@@ -640,10 +636,10 @@ int npc_timerevent_start(struct npc_data* nd, int rid)
nd->u.scr.timertick = tick; // Set when timer is started
nd->u.scr.timerid = iTimer->add_timer(tick+next,npc_timerevent,nd->bl.id,(intptr_t)ted);
}
- }
- else if (!sd)
- {
+
+ } else if (!sd) {
nd->u.scr.timertick = tick;
+
}
return 0;
@@ -664,7 +660,6 @@ int npc_timerevent_stop(struct npc_data* nd)
ShowError("npc_timerevent_stop: Attached player not found!\n");
return 1;
}
-
tid = sd?&sd->npc_timer_id:&nd->u.scr.timerid;
if( *tid == INVALID_TIMER && (sd || !nd->u.scr.timertick) ) // Nothing to stop
return 0;
@@ -785,7 +780,7 @@ int npc_settimerevent_tick(struct npc_data* nd, int newtimer)
nd->u.scr.rid = 0;
// Check if timer is started
- flag = (nd->u.scr.timerid != INVALID_TIMER);
+ flag = (nd->u.scr.timerid != INVALID_TIMER || nd->u.scr.timertick);
if( flag ) npc_timerevent_stop(nd);
nd->u.scr.timer = newtimer;
@@ -1322,7 +1317,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
nameid = item_list[i*2+1];
amount = item_list[i*2+0];
- if( !itemdb_exists(nameid) || amount <= 0 )
+ if( !itemdb->exists(nameid) || amount <= 0 )
return 5;
ARR_FIND(0,nd->u.shop.count,j,nd->u.shop.shop_item[j].nameid == nameid);
@@ -1427,7 +1422,7 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
if( sd->state.trading )
return 4;
- if( (item = itemdb_exists(nameid)) == NULL )
+ if( (item = itemdb->exists(nameid)) == NULL )
return 5; // Invalid Item
ARR_FIND(0, nd->u.shop.count, i, nd->u.shop.shop_item[i].nameid == nameid);
@@ -1526,7 +1521,7 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list)
nameid = item_list[i*2+1] = nd->u.shop.shop_item[j].nameid; //item_avail replacement
value = nd->u.shop.shop_item[j].value;
- if( !itemdb_exists(nameid) )
+ if( !itemdb->exists(nameid) )
return 3; // item no longer in itemdb
if( !itemdb_isstackable(nameid) && amount > 1 ) {
@@ -2211,7 +2206,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
break;
}
- if( (id = itemdb_exists(nameid)) == NULL )
+ if( (id = itemdb->exists(nameid)) == NULL )
{
ShowWarning("npc_parse_shop: Invalid sell item in file '%s', line '%d' (id '%d').\n", filepath, strline(buffer,start-buffer), nameid);
p = strchr(p+1,',');
@@ -3230,7 +3225,7 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
int drop_id = 0, drop_type = 0;
if (!strcmpi(drop_arg1, "random"))
drop_id = -1;
- else if (itemdb_exists((drop_id = atoi(drop_arg1))) == NULL)
+ else if (itemdb->exists((drop_id = atoi(drop_arg1))) == NULL)
drop_id = 0;
if (!strcmpi(drop_arg2, "inventory"))
drop_type = 1;
@@ -3377,6 +3372,8 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
map[m].flag.guildlock=state;
else if (!strcmpi(w3,"reset"))
map[m].flag.reset=state;
+ else if (!strcmpi(w3,"notomb"))
+ map[m].flag.notomb=state;
else if (!strcmpi(w3,"adjust_unit_duration")) {
int skill_id, k;
char skill_name[MAP_ZONE_MAPFLAG_LENGTH], modifier[MAP_ZONE_MAPFLAG_LENGTH];
@@ -3415,8 +3412,8 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
if( map[m].units[k] == NULL )
continue;
- memmove(&map[m].units[cursor], &map[m].units[k], sizeof(struct mapflag_skill_adjust));
-
+ map[m].units[cursor] = map[m].units[k];
+
cursor++;
}
if( !( map[m].unit_count = cursor ) ) {
@@ -3455,7 +3452,7 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
ShowWarning("npc_parse_mapflag: Invalid modifier '%d' for skill '%s' for 'adjust_skill_damage' flag! removing flag from %s (file '%s', line '%d').\n", atoi(modifier), skill_name, map[m].name, filepath, strline(buffer,start-buffer));
} else {
int idx = map[m].skill_count;
-
+
ARR_FIND(0, idx, k, map[m].skills[k]->skill_id == skill_id);
if( k < idx ) {
@@ -3469,8 +3466,8 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
if( map[m].skills[k] == NULL )
continue;
- memmove(&map[m].skills[cursor], &map[m].skills[k], sizeof(struct mapflag_skill_adjust));
-
+ map[m].skills[cursor] = map[m].skills[k];
+
cursor++;
}
if( !( map[m].skill_count = cursor ) ) {
@@ -3843,8 +3840,10 @@ int npc_reload(void) {
"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n"
"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
-
- instance->final();
+
+ for(i = 0; i < instance->instances; i++) {
+ instance->destroy(i);
+ }
iMap->zone_init();
diff --git a/src/map/packets.h b/src/map/packets.h
index c467090dd..f90c3b29d 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -2025,8 +2025,6 @@ packet(0x020d,-1);
packet(0x08E5,41,clif->pPartyBookingRegisterReq,2,4);
packet(0x08d2,10);
packet(0x0916,26,clif->pGuildInvite2,2);
- packetKeys(0x1540e48,0x13041224,0x31247924);
-
#endif
#ifndef PACKETVER_RE
@@ -2065,10 +2063,36 @@ packet(0x020d,-1);
packet(0x0886,2,clif->pReqCloseBuyingStore,0);
#endif
-//2012-07-16aRagExe (special thanks to Yommy!)
+//2012-07-16aRagExe (special thanks to Yommy/Frost!)
#if PACKETVER >= 20120716
+ packet(0x0879,18,clif->pPartyBookingRegisterReq,2,4,6);
+ packet(0x023B,26,clif->pFriendsListAdd,2);
+ packet(0x0361,5,clif->pHomMenu,2,4);
+ packet(0x0819,36,clif->pStoragePassword,0);
+ packet(0x0802,26,clif->pPartyInvite2,2);
+ packet(0x022D,19,clif->pWantToConnection,2,6,10,14,18);
+ packet(0x0369,7,clif->pActionRequest,2,6);
+ packet(0x083C,10,clif->pUseSkillToId,2,4,6);
+ packet(0x0439,8,clif->pUseItem,2,4);
+ packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8);
+ packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89);
+ packet(0x0817,2,clif->pReqCloseBuyingStore,0);
+ packet(0x0360,6,clif->pReqClickBuyingStore,2);
+ packet(0x0940,-1,clif->pReqTradeBuyingStore,2,4,8,12);
+ packet(0x0811,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15);
+ packet(0x0835,2,clif->pSearchStoreInfoNextPage,0);
+ packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10);
+ packet(0x0437,5,clif->pWalkToXY,2);
+ packet(0x035F,6,clif->pTickSend,2);
+ packet(0x0202,5,clif->pChangeDir,2,4);
+ packet(0x07E4,6,clif->pTakeItem,2);
+ packet(0x0362,6,clif->pDropItem,2,4);
+ packet(0x07EC,8,clif->pMoveToKafra,2,4);
packet(0x0364,8,clif->pMoveFromKafra,2,4);
- packetKeys(0x76052205, 0x22052205, 0x22052205);
+ packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8);
+ packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10);
+ packet(0x096A,6,clif->pGetCharNameRequest,2);
+ packet(0x0368,6,clif->pSolveCharName,2);
#endif
//2013-03-20Ragexe (Judas + Yommy)
@@ -2103,7 +2127,6 @@ packet(0x020d,-1);
packet(0x086F,26,clif->pFriendsListAdd,2);
packet(0x093F,5,clif->pHomMenu,2,4);
packet(0x0947,36,clif->pStoragePassword,0);
- packetKeys(0x3F094C49, 0x55F86C1E, 0x58AA359A);
// Shuffle End
// New Packets
@@ -2249,8 +2272,186 @@ packet(0x020d,-1);
packet(0x0883,36,clif->pStoragePassword,0);
#endif
+/* PacketKeys: http://hercules.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */
+#if PACKETVER >= 20110817
+ packetKeys(0x053D5CED,0x3DED6DED,0x6DED6DED); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20110824
+ packetKeys(0x35C91401,0x262A5556,0x28FA03AA); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20110831
+ packetKeys(0x3AD67ED0,0x44703C69,0x6F876809); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20110906
+ packetKeys(0x3AD67ED0,0x44703C69,0x6F876809); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20111005
+ packetKeys(0x291E6762,0x77CD391A,0x60AC2F16); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20111012
+ packetKeys(0x7F3C2D29,0x59B01DE6,0x1DBB44CA); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20111021
+ packetKeys(0x357D55DC,0x5A8D759F,0x245C30F5); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20111025
+ packetKeys(0x50AE1A63,0x3CE579B5,0x29C10406); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20111102
+ packetKeys(0x5324329D,0x5D545D52,0x06137269); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20111109
+ packetKeys(0x0B642BDA,0x6ECB1D1C,0x61C7454B); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20111122
+ packetKeys(0x3B550F07,0x1F666C7C,0x60304EF5); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20111207
+ packetKeys(0x2A610886,0x3E09165E,0x57C11888); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20111214
+ packetKeys(0x5151306B,0x7AE32886,0x53060628); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20111220
+ packetKeys(0x05D53871,0x7D0027B4,0x29975333); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20111228
+ packetKeys(0x0FF87E93,0x6CFF7860,0x3A3D1DEC); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120104
+ packetKeys(0x262034A1,0x674542A5,0x73A50BA5); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120111
+ packetKeys(0x2B412AFC,0x4FF94487,0x6705339D); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120120
+ packetKeys(0x504345D0,0x3D427B1B,0x794C2DCC); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120202
+ packetKeys(0x2CFC0A71,0x2BA91D8D,0x087E39E0); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120207
+ packetKeys(0x1D373F5D,0x5ACD604D,0x1C4D7C4D); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120214
+ packetKeys(0x7A255EFA,0x30977276,0x2D4A0448); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120229
+ packetKeys(0x520B4C64,0x2800407D,0x47651458); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120307
+ packetKeys(0x382A6DEF,0x5CBE7202,0x61F46637); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120314
+ packetKeys(0x689C1729,0x11812639,0x60F82967); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120321
+ packetKeys(0x21F9683F,0x710C5CA5,0x1FD910E9); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120328
+ packetKeys(0x75B8553B,0x37F20B12,0x385C2B40); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120404
+ packetKeys(0x0036310C,0x2DCD0BED,0x1EE62A78); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120410
+ packetKeys(0x01581359,0x452D6FFA,0x6AFB6E2E); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120418
+ packetKeys(0x01540E48,0x13041224,0x31247924); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120424
+ packetKeys(0x411D1DBB,0x4CBA4848,0x1A432FC4); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120509
+ packetKeys(0x16CF3301,0x1F472B9B,0x0B4A3CD2); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120515
+ packetKeys(0x4A715EF9,0x79103E4F,0x405C1238); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120525
+ packetKeys(0x70EB4CCB,0x0487713C,0x398D4B08); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120605
+ packetKeys(0x68CA3080,0x31B74BDD,0x505208F1); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120612
+ packetKeys(0x32E45D64,0x35643564,0x35643564); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120618
+ packetKeys(0x261F261F,0x261F261F,0x261F261F); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120702
+ packetKeys(0x25733B31,0x53486CFD,0x398649BD); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20120716
+ packetKeys(0x76052205,0x22052205,0x22052205); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20130320
+ packetKeys(0x3F094C49,0x55F86C1E,0x58AA359A); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20130514
+ packetKeys(0x75794A38,0x58A96BC1,0x296E6FB8); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20130522
+ packetKeys(0x6948050B,0x06511D9D,0x725D4DF1); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20130529
+ packetKeys(0x023A6C87,0x14BF1F1E,0x5CC70CC9); /* Thanks to Shakto */
+#endif
+
+#if PACKETVER >= 20130605
+ packetKeys(0x646E08D9,0x5F153AB5,0x61B509B5); /* Thanks to Shakto */
+#endif
+
#if PACKETVER >= 20130612
- packetKeys(0x6D166F66, 0x3C000FCF, 0x295B0FCB); /* Thanks to Shakto */
+ packetKeys(0x6D166F66,0x3C000FCF,0x295B0FCB); /* Thanks to Shakto */
#endif
+#if PACKETVER >= 20130618
+ packetKeys(0x434115DE,0x34A10FE9,0x6791428E); /* Thanks to Shakto */
+#endif
+
+
#endif /* _PACKETS_H_ */
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 083c00e31..d77784dc5 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -73,6 +73,7 @@ enum packet_headers {
authokType = 0x2eb,
#endif
script_clearType = 0x8d6,
+ package_item_announceType = 0x7fd,
#if PACKETVER < 4
unit_walkingType = 0x7b,
#elif PACKETVER < 7
@@ -458,7 +459,17 @@ struct packet_script_clear {
short PacketType;
unsigned int NpcID;
} __attribute__((packed));
-
+/* made possible thanks to Yommy!! */
+struct packet_package_item_announce {
+ short PacketType;
+ short PacketLength;
+ unsigned char type;
+ unsigned short ItemID;
+ char len;
+ char Name[NAME_LENGTH];
+ char unknown;
+ unsigned short BoxItemID;
+} __attribute__((packed));
#pragma pack(pop)
diff --git a/src/map/party.c b/src/map/party.c
index adcb35c5a..154f84207 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -319,10 +319,12 @@ int party_recv_info(struct party* sp, int char_id)
clif->party_option(p,sd,0x100);
clif->party_info(p,NULL);
for( j = 0; j < p->instances; j++ ) {
- if( instances[p->instance[j]].idle_timer == INVALID_TIMER && instances[p->instance[j]].progress_timer == INVALID_TIMER )
- continue;
- clif->instance_join(sd->fd, p->instance[j]);
- break;
+ if( p->instance[j] >= 0 ) {
+ if( instances[p->instance[j]].idle_timer == INVALID_TIMER && instances[p->instance[j]].progress_timer == INVALID_TIMER )
+ continue;
+ clif->instance_join(sd->fd, p->instance[j]);
+ break;
+ }
}
}
if( char_id != 0 )// requester
@@ -441,10 +443,12 @@ void party_member_joined(struct map_session_data *sd)
int j;
p->data[i].sd = sd;
for( j = 0; j < p->instances; j++ ) {
- if( instances[p->instance[j]].idle_timer == INVALID_TIMER && instances[p->instance[j]].progress_timer == INVALID_TIMER )
- continue;
- clif->instance_join(sd->fd, p->instance[j]);
- break;
+ if( p->instance[j] >= 0 ) {
+ if( instances[p->instance[j]].idle_timer == INVALID_TIMER && instances[p->instance[j]].progress_timer == INVALID_TIMER )
+ continue;
+ clif->instance_join(sd->fd, p->instance[j]);
+ break;
+ }
}
} else
sd->status.party_id = 0; //He does not belongs to the party really?
@@ -502,10 +506,12 @@ int party_member_added(int party_id,int account_id,int char_id, int flag)
clif->charnameupdate(sd); //Update char name's display [Skotlex]
for( j = 0; j < p->instances; j++ ) {
- if( instances[p->instance[j]].idle_timer == INVALID_TIMER && instances[p->instance[j]].progress_timer == INVALID_TIMER )
- continue;
- clif->instance_join(sd->fd, p->instance[j]);
- break;
+ if( p->instance[j] >= 0 ) {
+ if( instances[p->instance[j]].idle_timer == INVALID_TIMER && instances[p->instance[j]].progress_timer == INVALID_TIMER )
+ continue;
+ clif->instance_join(sd->fd, p->instance[j]);
+ break;
+ }
}
return 0;
@@ -579,7 +585,12 @@ int party_member_withdraw(int party_id, int account_id, int char_id)
if( p->instances )
instance->check_kick(sd);
}
-
+ if (sd && sd->sc.data[SC_DANCING]) {
+ status_change_end(&sd->bl, SC_DANCING, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_DRUMBATTLE, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_NIBELUNGEN, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_SIEGFRIED, INVALID_TIMER);
+ }
return 0;
}
@@ -594,8 +605,10 @@ int party_broken(int party_id)
return 0;
for( j = 0; j < p->instances; j++ ) {
- instance->destroy( p->instance[j] );
- instances[p->instance[j]].owner_id = 0;
+ if( p->instance[j] >= 0 ) {
+ instance->destroy( p->instance[j] );
+ instances[p->instance[j]].owner_id = 0;
+ }
}
for( i = 0; i < MAX_PARTY; i++ ) {
diff --git a/src/map/party.h b/src/map/party.h
index e1f2d3a3b..f215baa56 100644
--- a/src/map/party.h
+++ b/src/map/party.h
@@ -24,7 +24,7 @@ struct party_data {
struct party party;
struct party_member_data data[MAX_PARTY];
uint8 itemc; //For item distribution, position of last picker in party
- unsigned short *instance;
+ short *instance;
unsigned short instances;
struct {
unsigned monk : 1; //There's at least one monk in party?
diff --git a/src/map/pc.c b/src/map/pc.c
index b7644f2fb..3e823bb97 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -12,11 +12,13 @@
#include "../common/strlib.h" // safestrncpy()
#include "../common/timer.h"
#include "../common/utils.h"
+#include "../common/conf.h"
#include "../common/mmo.h" //NAME_LENGTH
#include "atcommand.h" // get_atcommand_level()
#include "battle.h" // battle_config
#include "battleground.h"
+#include "chat.h"
#include "chrif.h"
#include "clif.h"
#include "date.h" // is_day_of_*()
@@ -359,7 +361,7 @@ void pc_addfame(struct map_session_data *sd,int count)
clif->fame_taekwon(sd,count);
break;
}
- chrif_updatefamelist(sd);
+ chrif->updatefamelist(sd);
}
// Check whether a player ID is in the fame rankers' list of its job, returns his/her position if so, 0 else
@@ -618,7 +620,7 @@ int pc_setinventorydata(struct map_session_data *sd)
for(i=0;i<MAX_INVENTORY;i++) {
id = sd->status.inventory[i].nameid;
- sd->inventory_data[i] = id?itemdb_search(id):NULL;
+ sd->inventory_data[i] = id?itemdb->search(id):NULL;
}
return 0;
}
@@ -719,7 +721,7 @@ int pc_setequipindex(struct map_session_data *sd)
// if( item->card[MAX_SLOTS - 1] && s < MAX_SLOTS - 1 )
// s = MAX_SLOTS - 1;
//
-// ARR_FIND( 0, s, i, item->card[i] && (data = itemdb_exists(item->card[i])) != NULL && data->flag.no_equip&flag );
+// ARR_FIND( 0, s, i, item->card[i] && (data = itemdb->exists(item->card[i])) != NULL && data->flag.no_equip&flag );
// return( i < s ) ? 0 : 1;
//}
@@ -985,6 +987,8 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
sd->cansendmail_tick = tick;
sd->hchsysch_tick = tick;
+ sd->idletime = last_tick;
+
for(i = 0; i < MAX_SPIRITBALL; i++)
sd->spirit_timer[i] = INVALID_TIMER;
for(i = 0; i < ARRAYLENGTH(sd->autobonus); i++)
@@ -1235,13 +1239,13 @@ int pc_reg_received(struct map_session_data *sd)
iMap->addiddb(&sd->bl);
iMap->delnickdb(sd->status.char_id, sd->status.name);
- if (!chrif_auth_finished(sd))
+ if (!chrif->auth_finished(sd))
ShowError("pc_reg_received: Failed to properly remove player %d:%d from logging db!\n", sd->status.account_id, sd->status.char_id);
pc->load_combo(sd);
status_calc_pc(sd,1);
- chrif_scdata_request(sd->status.account_id, sd->status.char_id);
+ chrif->scdata_request(sd->status.account_id, sd->status.char_id);
intif_Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox
intif_request_questlog(sd);
@@ -1689,6 +1693,13 @@ int pc_disguise(struct map_session_data *sd, int class_) {
clif->cartlist(sd);
clif->updatestatus(sd,SP_CARTINFO);
}
+ if (sd->chatID) {
+ struct chat_data* cd;
+ nullpo_retr(1, sd);
+ cd = (struct chat_data*)iMap->id2bl(sd->chatID);
+ if( cd != NULL || (struct block_list*)sd == cd->owner )
+ clif->dispchat(cd,0);
+ }
}
return 1;
}
@@ -1806,9 +1817,9 @@ static int pc_bonus_addeff_onskill(struct s_addeffectonskill* effect, int max, e
return 1;
}
-static int pc_bonus_item_drop(struct s_add_drop *drop, const short max, short id, short group, int race, int rate)
-{
+static int pc_bonus_item_drop(struct s_add_drop *drop, const short max, short id, short group, int race, int rate) {
int i;
+
//Apply config rate adjustment settings.
if (rate >= 0) { //Absolute drop.
if (battle_config.item_rate_adddrop != 100)
@@ -2635,6 +2646,10 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
break;
#endif
+ case SP_ADD_MONSTER_DROP_CHAINITEM:
+ if (sd->state.lr_flag != 2)
+ pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), 0, val, (1<<RC_BOSS)|(1<<RC_NONBOSS), 10000);
+ break;
default:
ShowWarning("pc_bonus: unknown type %d %d !\n",type,val);
break;
@@ -2652,593 +2667,589 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
nullpo_ret(sd);
switch(type){
- case SP_ADDELE:
- if(type2 >= ELE_MAX) {
- ShowError("pc_bonus2: SP_ADDELE: Invalid element %d\n", type2);
+ case SP_ADDELE:
+ if(type2 >= ELE_MAX) {
+ 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;
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;
- 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;
- break;
- case SP_ADDSIZE:
- if(!sd->state.lr_flag)
- sd->right_weapon.addsize[type2]+=val;
- else if(sd->state.lr_flag == 1)
- sd->left_weapon.addsize[type2]+=val;
- else if(sd->state.lr_flag == 2)
- sd->arrow_addsize[type2]+=val;
- break;
- case SP_SUBELE:
- if(type2 >= ELE_MAX) {
- ShowError("pc_bonus2: SP_SUBELE: Invalid element %d\n", type2);
+ 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;
break;
- }
- if(sd->state.lr_flag != 2)
- sd->subele[type2]+=val;
- break;
- case SP_SUBRACE:
- if(sd->state.lr_flag != 2)
- sd->subrace[type2]+=val;
- break;
- case SP_ADDEFF:
- if (type2 > SC_MAX) {
- ShowWarning("pc_bonus2 (Add Effect): %d is not supported.\n", type2);
+ case SP_ADDSIZE:
+ if(!sd->state.lr_flag)
+ sd->right_weapon.addsize[type2]+=val;
+ else if(sd->state.lr_flag == 1)
+ sd->left_weapon.addsize[type2]+=val;
+ else if(sd->state.lr_flag == 2)
+ sd->arrow_addsize[type2]+=val;
break;
- }
- pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
- sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, 0);
- break;
- case SP_ADDEFF2:
- if (type2 > SC_MAX) {
- ShowWarning("pc_bonus2 (Add Effect2): %d is not supported.\n", type2);
+ case SP_SUBELE:
+ if(type2 >= ELE_MAX) {
+ ShowError("pc_bonus2: SP_SUBELE: Invalid element %d\n", type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2)
+ sd->subele[type2]+=val;
break;
- }
- pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
- sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, ATF_SELF);
- break;
- case SP_RESEFF:
- if (type2 < SC_COMMON_MIN || type2 > SC_COMMON_MAX) {
- ShowWarning("pc_bonus2 (Resist Effect): %d is not supported.\n", type2);
+ case SP_SUBRACE:
+ if(sd->state.lr_flag != 2)
+ sd->subrace[type2]+=val;
break;
- }
- if(sd->state.lr_flag == 2)
+ case SP_ADDEFF:
+ if (type2 > SC_MAX) {
+ ShowWarning("pc_bonus2 (Add Effect): %d is not supported.\n", type2);
+ break;
+ }
+ pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
+ sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, 0);
break;
- i = sd->reseff[type2-SC_COMMON_MIN]+val;
- sd->reseff[type2-SC_COMMON_MIN]= cap_value(i, 0, 10000);
- break;
- case SP_MAGIC_ADDELE:
- if(type2 >= ELE_MAX) {
- ShowError("pc_bonus2: SP_MAGIC_ADDELE: Invalid element %d\n", type2);
+ case SP_ADDEFF2:
+ if (type2 > SC_MAX) {
+ ShowWarning("pc_bonus2 (Add Effect2): %d is not supported.\n", type2);
+ break;
+ }
+ pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
+ sd->state.lr_flag!=2?val:0, sd->state.lr_flag==2?val:0, ATF_SELF);
break;
- }
- if(sd->state.lr_flag != 2)
- sd->magic_addele[type2]+=val;
- break;
- case SP_MAGIC_ADDRACE:
- if(sd->state.lr_flag != 2)
- 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;
- break;
- case SP_ADD_DAMAGE_CLASS:
- switch (sd->state.lr_flag) {
- case 0: //Right hand
- ARR_FIND(0, ARRAYLENGTH(sd->right_weapon.add_dmg), i, sd->right_weapon.add_dmg[i].rate == 0 || sd->right_weapon.add_dmg[i].class_ == type2);
- if (i == ARRAYLENGTH(sd->right_weapon.add_dmg))
- {
- ShowWarning("pc_bonus2: Reached max (%d) number of add Class dmg bonuses per character!\n", ARRAYLENGTH(sd->right_weapon.add_dmg));
+ case SP_RESEFF:
+ if (type2 < SC_COMMON_MIN || type2 > SC_COMMON_MAX) {
+ ShowWarning("pc_bonus2 (Resist Effect): %d is not supported.\n", type2);
+ break;
+ }
+ if(sd->state.lr_flag == 2)
+ break;
+ i = sd->reseff[type2-SC_COMMON_MIN]+val;
+ sd->reseff[type2-SC_COMMON_MIN]= cap_value(i, 0, 10000);
+ break;
+ case SP_MAGIC_ADDELE:
+ if(type2 >= ELE_MAX) {
+ ShowError("pc_bonus2: SP_MAGIC_ADDELE: Invalid element %d\n", type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2)
+ sd->magic_addele[type2]+=val;
+ break;
+ case SP_MAGIC_ADDRACE:
+ if(sd->state.lr_flag != 2)
+ 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;
+ break;
+ case SP_ADD_DAMAGE_CLASS:
+ switch (sd->state.lr_flag) {
+ case 0: //Right hand
+ ARR_FIND(0, ARRAYLENGTH(sd->right_weapon.add_dmg), i, sd->right_weapon.add_dmg[i].rate == 0 || sd->right_weapon.add_dmg[i].class_ == type2);
+ if (i == ARRAYLENGTH(sd->right_weapon.add_dmg))
+ {
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class dmg bonuses per character!\n", ARRAYLENGTH(sd->right_weapon.add_dmg));
+ break;
+ }
+ sd->right_weapon.add_dmg[i].class_ = type2;
+ sd->right_weapon.add_dmg[i].rate += val;
+ if (!sd->right_weapon.add_dmg[i].rate) //Shift the rest of elements up.
+ memmove(&sd->right_weapon.add_dmg[i], &sd->right_weapon.add_dmg[i+1], sizeof(sd->right_weapon.add_dmg) - (i+1)*sizeof(sd->right_weapon.add_dmg[0]));
+ break;
+ case 1: //Left hand
+ ARR_FIND(0, ARRAYLENGTH(sd->left_weapon.add_dmg), i, sd->left_weapon.add_dmg[i].rate == 0 || sd->left_weapon.add_dmg[i].class_ == type2);
+ if (i == ARRAYLENGTH(sd->left_weapon.add_dmg))
+ {
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class dmg bonuses per character!\n", ARRAYLENGTH(sd->left_weapon.add_dmg));
+ break;
+ }
+ sd->left_weapon.add_dmg[i].class_ = type2;
+ sd->left_weapon.add_dmg[i].rate += val;
+ if (!sd->left_weapon.add_dmg[i].rate) //Shift the rest of elements up.
+ memmove(&sd->left_weapon.add_dmg[i], &sd->left_weapon.add_dmg[i+1], sizeof(sd->left_weapon.add_dmg) - (i+1)*sizeof(sd->left_weapon.add_dmg[0]));
break;
}
- sd->right_weapon.add_dmg[i].class_ = type2;
- sd->right_weapon.add_dmg[i].rate += val;
- if (!sd->right_weapon.add_dmg[i].rate) //Shift the rest of elements up.
- memmove(&sd->right_weapon.add_dmg[i], &sd->right_weapon.add_dmg[i+1], sizeof(sd->right_weapon.add_dmg) - (i+1)*sizeof(sd->right_weapon.add_dmg[0]));
break;
- case 1: //Left hand
- ARR_FIND(0, ARRAYLENGTH(sd->left_weapon.add_dmg), i, sd->left_weapon.add_dmg[i].rate == 0 || sd->left_weapon.add_dmg[i].class_ == type2);
- if (i == ARRAYLENGTH(sd->left_weapon.add_dmg))
+ case SP_ADD_MAGIC_DAMAGE_CLASS:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->add_mdmg), i, sd->add_mdmg[i].rate == 0 || sd->add_mdmg[i].class_ == type2);
+ if (i == ARRAYLENGTH(sd->add_mdmg))
{
- ShowWarning("pc_bonus2: Reached max (%d) number of add Class dmg bonuses per character!\n", ARRAYLENGTH(sd->left_weapon.add_dmg));
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class magic dmg bonuses per character!\n", ARRAYLENGTH(sd->add_mdmg));
break;
}
- sd->left_weapon.add_dmg[i].class_ = type2;
- sd->left_weapon.add_dmg[i].rate += val;
- if (!sd->left_weapon.add_dmg[i].rate) //Shift the rest of elements up.
- memmove(&sd->left_weapon.add_dmg[i], &sd->left_weapon.add_dmg[i+1], sizeof(sd->left_weapon.add_dmg) - (i+1)*sizeof(sd->left_weapon.add_dmg[0]));
+ sd->add_mdmg[i].class_ = type2;
+ sd->add_mdmg[i].rate += val;
+ if (!sd->add_mdmg[i].rate) //Shift the rest of elements up.
+ memmove(&sd->add_mdmg[i], &sd->add_mdmg[i+1], sizeof(sd->add_mdmg) - (i+1)*sizeof(sd->add_mdmg[0]));
break;
- }
- break;
- case SP_ADD_MAGIC_DAMAGE_CLASS:
- if(sd->state.lr_flag == 2)
+ case SP_ADD_DEF_CLASS:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->add_def), i, sd->add_def[i].rate == 0 || sd->add_def[i].class_ == type2);
+ if (i == ARRAYLENGTH(sd->add_def))
+ {
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class def bonuses per character!\n", ARRAYLENGTH(sd->add_def));
+ break;
+ }
+ sd->add_def[i].class_ = type2;
+ sd->add_def[i].rate += val;
+ if (!sd->add_def[i].rate) //Shift the rest of elements up.
+ memmove(&sd->add_def[i], &sd->add_def[i+1], sizeof(sd->add_def) - (i+1)*sizeof(sd->add_def[0]));
break;
- ARR_FIND(0, ARRAYLENGTH(sd->add_mdmg), i, sd->add_mdmg[i].rate == 0 || sd->add_mdmg[i].class_ == type2);
- if (i == ARRAYLENGTH(sd->add_mdmg))
- {
- ShowWarning("pc_bonus2: Reached max (%d) number of add Class magic dmg bonuses per character!\n", ARRAYLENGTH(sd->add_mdmg));
+ case SP_ADD_MDEF_CLASS:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->add_mdef), i, sd->add_mdef[i].rate == 0 || sd->add_mdef[i].class_ == type2);
+ if (i == ARRAYLENGTH(sd->add_mdef))
+ {
+ ShowWarning("pc_bonus2: Reached max (%d) number of add Class mdef bonuses per character!\n", ARRAYLENGTH(sd->add_mdef));
+ break;
+ }
+ sd->add_mdef[i].class_ = type2;
+ sd->add_mdef[i].rate += val;
+ if (!sd->add_mdef[i].rate) //Shift the rest of elements up.
+ memmove(&sd->add_mdef[i], &sd->add_mdef[i+1], sizeof(sd->add_mdef) - (i+1)*sizeof(sd->add_mdef[0]));
break;
- }
- sd->add_mdmg[i].class_ = type2;
- sd->add_mdmg[i].rate += val;
- if (!sd->add_mdmg[i].rate) //Shift the rest of elements up.
- memmove(&sd->add_mdmg[i], &sd->add_mdmg[i+1], sizeof(sd->add_mdmg) - (i+1)*sizeof(sd->add_mdmg[0]));
- break;
- case SP_ADD_DEF_CLASS:
- if(sd->state.lr_flag == 2)
+ case SP_HP_DRAIN_RATE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.hp_drain[RC_NONBOSS].rate += type2;
+ sd->right_weapon.hp_drain[RC_NONBOSS].per += val;
+ sd->right_weapon.hp_drain[RC_BOSS].rate += type2;
+ sd->right_weapon.hp_drain[RC_BOSS].per += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.hp_drain[RC_NONBOSS].rate += type2;
+ sd->left_weapon.hp_drain[RC_NONBOSS].per += val;
+ sd->left_weapon.hp_drain[RC_BOSS].rate += type2;
+ sd->left_weapon.hp_drain[RC_BOSS].per += val;
+ }
break;
- ARR_FIND(0, ARRAYLENGTH(sd->add_def), i, sd->add_def[i].rate == 0 || sd->add_def[i].class_ == type2);
- if (i == ARRAYLENGTH(sd->add_def))
- {
- ShowWarning("pc_bonus2: Reached max (%d) number of add Class def bonuses per character!\n", ARRAYLENGTH(sd->add_def));
+ case SP_HP_DRAIN_VALUE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.hp_drain[RC_NONBOSS].value += type2;
+ sd->right_weapon.hp_drain[RC_NONBOSS].type = val;
+ sd->right_weapon.hp_drain[RC_BOSS].value += type2;
+ sd->right_weapon.hp_drain[RC_BOSS].type = val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.hp_drain[RC_NONBOSS].value += type2;
+ sd->left_weapon.hp_drain[RC_NONBOSS].type = val;
+ sd->left_weapon.hp_drain[RC_BOSS].value += type2;
+ sd->left_weapon.hp_drain[RC_BOSS].type = val;
+ }
break;
- }
- sd->add_def[i].class_ = type2;
- sd->add_def[i].rate += val;
- if (!sd->add_def[i].rate) //Shift the rest of elements up.
- memmove(&sd->add_def[i], &sd->add_def[i+1], sizeof(sd->add_def) - (i+1)*sizeof(sd->add_def[0]));
- break;
- case SP_ADD_MDEF_CLASS:
- if(sd->state.lr_flag == 2)
+ case SP_SP_DRAIN_RATE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[RC_NONBOSS].rate += type2;
+ sd->right_weapon.sp_drain[RC_NONBOSS].per += val;
+ sd->right_weapon.sp_drain[RC_BOSS].rate += type2;
+ sd->right_weapon.sp_drain[RC_BOSS].per += val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[RC_NONBOSS].rate += type2;
+ sd->left_weapon.sp_drain[RC_NONBOSS].per += val;
+ sd->left_weapon.sp_drain[RC_BOSS].rate += type2;
+ sd->left_weapon.sp_drain[RC_BOSS].per += val;
+ }
break;
- ARR_FIND(0, ARRAYLENGTH(sd->add_mdef), i, sd->add_mdef[i].rate == 0 || sd->add_mdef[i].class_ == type2);
- if (i == ARRAYLENGTH(sd->add_mdef))
- {
- ShowWarning("pc_bonus2: Reached max (%d) number of add Class mdef bonuses per character!\n", ARRAYLENGTH(sd->add_mdef));
+ case SP_SP_DRAIN_VALUE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[RC_NONBOSS].value += type2;
+ sd->right_weapon.sp_drain[RC_NONBOSS].type = val;
+ sd->right_weapon.sp_drain[RC_BOSS].value += type2;
+ sd->right_weapon.sp_drain[RC_BOSS].type = val;
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[RC_NONBOSS].value += type2;
+ sd->left_weapon.sp_drain[RC_NONBOSS].type = val;
+ sd->left_weapon.sp_drain[RC_BOSS].value += type2;
+ sd->left_weapon.sp_drain[RC_BOSS].type = val;
+ }
break;
- }
- sd->add_mdef[i].class_ = type2;
- sd->add_mdef[i].rate += val;
- if (!sd->add_mdef[i].rate) //Shift the rest of elements up.
- memmove(&sd->add_mdef[i], &sd->add_mdef[i+1], sizeof(sd->add_mdef) - (i+1)*sizeof(sd->add_mdef[0]));
- break;
- case SP_HP_DRAIN_RATE:
- if(!sd->state.lr_flag) {
- sd->right_weapon.hp_drain[RC_NONBOSS].rate += type2;
- sd->right_weapon.hp_drain[RC_NONBOSS].per += val;
- sd->right_weapon.hp_drain[RC_BOSS].rate += type2;
- sd->right_weapon.hp_drain[RC_BOSS].per += val;
- }
- else if(sd->state.lr_flag == 1) {
- sd->left_weapon.hp_drain[RC_NONBOSS].rate += type2;
- sd->left_weapon.hp_drain[RC_NONBOSS].per += val;
- sd->left_weapon.hp_drain[RC_BOSS].rate += type2;
- sd->left_weapon.hp_drain[RC_BOSS].per += val;
- }
- break;
- case SP_HP_DRAIN_VALUE:
- if(!sd->state.lr_flag) {
- sd->right_weapon.hp_drain[RC_NONBOSS].value += type2;
- sd->right_weapon.hp_drain[RC_NONBOSS].type = val;
- sd->right_weapon.hp_drain[RC_BOSS].value += type2;
- sd->right_weapon.hp_drain[RC_BOSS].type = val;
- }
- else if(sd->state.lr_flag == 1) {
- sd->left_weapon.hp_drain[RC_NONBOSS].value += type2;
- sd->left_weapon.hp_drain[RC_NONBOSS].type = val;
- sd->left_weapon.hp_drain[RC_BOSS].value += type2;
- sd->left_weapon.hp_drain[RC_BOSS].type = val;
- }
- break;
- case SP_SP_DRAIN_RATE:
- if(!sd->state.lr_flag) {
- sd->right_weapon.sp_drain[RC_NONBOSS].rate += type2;
- sd->right_weapon.sp_drain[RC_NONBOSS].per += val;
- sd->right_weapon.sp_drain[RC_BOSS].rate += type2;
- sd->right_weapon.sp_drain[RC_BOSS].per += val;
- }
- else if(sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain[RC_NONBOSS].rate += type2;
- sd->left_weapon.sp_drain[RC_NONBOSS].per += val;
- sd->left_weapon.sp_drain[RC_BOSS].rate += type2;
- sd->left_weapon.sp_drain[RC_BOSS].per += val;
- }
- break;
- case SP_SP_DRAIN_VALUE:
- if(!sd->state.lr_flag) {
- sd->right_weapon.sp_drain[RC_NONBOSS].value += type2;
- sd->right_weapon.sp_drain[RC_NONBOSS].type = val;
- sd->right_weapon.sp_drain[RC_BOSS].value += type2;
- sd->right_weapon.sp_drain[RC_BOSS].type = val;
- }
- else if(sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain[RC_NONBOSS].value += type2;
- sd->left_weapon.sp_drain[RC_NONBOSS].type = val;
- sd->left_weapon.sp_drain[RC_BOSS].value += type2;
- sd->left_weapon.sp_drain[RC_BOSS].type = val;
- }
- break;
- case SP_SP_VANISH_RATE:
- if(sd->state.lr_flag != 2) {
- sd->bonus.sp_vanish_rate += type2;
- sd->bonus.sp_vanish_per += val;
- }
- break;
- case SP_GET_ZENY_NUM:
- if(sd->state.lr_flag != 2 && sd->bonus.get_zeny_rate < val) {
- sd->bonus.get_zeny_rate = val;
- sd->bonus.get_zeny_num = type2;
- }
- break;
- case SP_ADD_GET_ZENY_NUM:
- if(sd->state.lr_flag != 2) {
- sd->bonus.get_zeny_rate += val;
- sd->bonus.get_zeny_num += type2;
- }
- break;
- case SP_WEAPON_COMA_ELE:
- if(type2 >= ELE_MAX) {
- ShowError("pc_bonus2: SP_WEAPON_COMA_ELE: Invalid element %d\n", type2);
+ case SP_SP_VANISH_RATE:
+ if(sd->state.lr_flag != 2) {
+ sd->bonus.sp_vanish_rate += type2;
+ sd->bonus.sp_vanish_per += val;
+ }
break;
- }
- if(sd->state.lr_flag == 2)
+ case SP_GET_ZENY_NUM:
+ if(sd->state.lr_flag != 2 && sd->bonus.get_zeny_rate < val) {
+ sd->bonus.get_zeny_rate = val;
+ sd->bonus.get_zeny_num = type2;
+ }
break;
- sd->weapon_coma_ele[type2] += val;
- sd->special_state.bonus_coma = 1;
- break;
- case SP_WEAPON_COMA_RACE:
- if(sd->state.lr_flag == 2)
+ case SP_ADD_GET_ZENY_NUM:
+ if(sd->state.lr_flag != 2) {
+ sd->bonus.get_zeny_rate += val;
+ sd->bonus.get_zeny_num += type2;
+ }
break;
- sd->weapon_coma_race[type2] += val;
- sd->special_state.bonus_coma = 1;
- break;
- case SP_WEAPON_ATK:
- if(sd->state.lr_flag != 2)
- sd->weapon_atk[type2]+=val;
- break;
- case SP_WEAPON_ATK_RATE:
- if(sd->state.lr_flag != 2)
- sd->weapon_atk_rate[type2]+=val;
- break;
- case SP_CRITICAL_ADDRACE:
- if(sd->state.lr_flag != 2)
- sd->critaddrace[type2] += val*10;
- break;
- case SP_ADDEFF_WHENHIT:
- if (type2 > SC_MAX) {
- ShowWarning("pc_bonus2 (Add Effect when hit): %d is not supported.\n", type2);
+ case SP_WEAPON_COMA_ELE:
+ if(type2 >= ELE_MAX) {
+ 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;
+ sd->special_state.bonus_coma = 1;
break;
- }
- if(sd->state.lr_flag != 2)
- pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, val, 0, 0);
- break;
- case SP_SKILL_ATK:
- if(sd->state.lr_flag == 2)
+ case SP_WEAPON_COMA_RACE:
+ if(sd->state.lr_flag == 2)
+ break;
+ sd->weapon_coma_race[type2] += val;
+ sd->special_state.bonus_coma = 1;
break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillatk), i, sd->skillatk[i].id == 0 || sd->skillatk[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillatk))
- { //Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("run_script: bonus2 bSkillAtk reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillatk), type2, val);
+ case SP_WEAPON_ATK:
+ if(sd->state.lr_flag != 2)
+ sd->weapon_atk[type2]+=val;
break;
- }
- if (sd->skillatk[i].id == type2)
- sd->skillatk[i].val += val;
- else {
- sd->skillatk[i].id = type2;
- sd->skillatk[i].val = val;
- }
- break;
- case SP_SKILL_HEAL:
- if(sd->state.lr_flag == 2)
+ case SP_WEAPON_ATK_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->weapon_atk_rate[type2]+=val;
break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == 0 || sd->skillheal[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillheal))
- { // Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("run_script: bonus2 bSkillHeal reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillheal), type2, val);
+ case SP_CRITICAL_ADDRACE:
+ if(sd->state.lr_flag != 2)
+ sd->critaddrace[type2] += val*10;
break;
- }
- if (sd->skillheal[i].id == type2)
- sd->skillheal[i].val += val;
- else {
- sd->skillheal[i].id = type2;
- sd->skillheal[i].val = val;
- }
- break;
- case SP_SKILL_HEAL2:
- if(sd->state.lr_flag == 2)
+ case SP_ADDEFF_WHENHIT:
+ if (type2 > SC_MAX) {
+ ShowWarning("pc_bonus2 (Add Effect when hit): %d is not supported.\n", type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2)
+ pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, val, 0, 0);
break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == 0 || sd->skillheal2[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillheal2))
- { // Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("run_script: bonus2 bSkillHeal2 reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillheal2), type2, val);
+ case SP_SKILL_ATK:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillatk), i, sd->skillatk[i].id == 0 || sd->skillatk[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillatk))
+ { //Better mention this so the array length can be updated. [Skotlex]
+ ShowDebug("run_script: bonus2 bSkillAtk reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillatk), type2, val);
+ break;
+ }
+ if (sd->skillatk[i].id == type2)
+ sd->skillatk[i].val += val;
+ else {
+ sd->skillatk[i].id = type2;
+ sd->skillatk[i].val = val;
+ }
break;
- }
- if (sd->skillheal2[i].id == type2)
- sd->skillheal2[i].val += val;
- else {
- sd->skillheal2[i].id = type2;
- sd->skillheal2[i].val = val;
- }
- break;
- case SP_ADD_SKILL_BLOW:
- if(sd->state.lr_flag == 2)
+ case SP_SKILL_HEAL:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == 0 || sd->skillheal[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillheal))
+ { // Better mention this so the array length can be updated. [Skotlex]
+ ShowDebug("run_script: bonus2 bSkillHeal reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillheal), type2, val);
+ break;
+ }
+ if (sd->skillheal[i].id == type2)
+ sd->skillheal[i].val += val;
+ else {
+ sd->skillheal[i].id = type2;
+ sd->skillheal[i].val = val;
+ }
break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillblown), i, sd->skillblown[i].id == 0 || sd->skillblown[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillblown))
- { //Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("run_script: bonus2 bSkillBlown reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillblown), type2, val);
+ case SP_SKILL_HEAL2:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == 0 || sd->skillheal2[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillheal2))
+ { // Better mention this so the array length can be updated. [Skotlex]
+ ShowDebug("run_script: bonus2 bSkillHeal2 reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillheal2), type2, val);
+ break;
+ }
+ if (sd->skillheal2[i].id == type2)
+ sd->skillheal2[i].val += val;
+ else {
+ sd->skillheal2[i].id = type2;
+ sd->skillheal2[i].val = val;
+ }
break;
- }
- if(sd->skillblown[i].id == type2)
- sd->skillblown[i].val += val;
- else {
- sd->skillblown[i].id = type2;
- sd->skillblown[i].val = val;
- }
- break;
-#ifndef RENEWAL_CAST
- case SP_VARCASTRATE:
-#endif
- case SP_CASTRATE:
- if(sd->state.lr_flag == 2)
+ case SP_ADD_SKILL_BLOW:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillblown), i, sd->skillblown[i].id == 0 || sd->skillblown[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillblown))
+ { //Better mention this so the array length can be updated. [Skotlex]
+ ShowDebug("run_script: bonus2 bSkillBlown reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillblown), type2, val);
+ break;
+ }
+ if(sd->skillblown[i].id == type2)
+ sd->skillblown[i].val += val;
+ else {
+ sd->skillblown[i].id = type2;
+ sd->skillblown[i].val = val;
+ }
break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillcast))
- { //Better mention this so the array length can be updated. [Skotlex]
- ShowDebug("run_script: bonus2 %s reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
+ #ifndef RENEWAL_CAST
+ case SP_VARCASTRATE:
+ #endif
+ case SP_CASTRATE:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillcast))
+ { //Better mention this so the array length can be updated. [Skotlex]
+ ShowDebug("run_script: bonus2 %s reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",
-#ifndef RENEWAL_CAST
- "bCastRate",
-#else
- "bVariableCastrate",
-#endif
+ #ifndef RENEWAL_CAST
+ "bCastRate",
+ #else
+ "bVariableCastrate",
+ #endif
- ARRAYLENGTH(sd->skillcast), type2, val);
+ ARRAYLENGTH(sd->skillcast), type2, val);
+ break;
+ }
+ if(sd->skillcast[i].id == type2)
+ sd->skillcast[i].val += val;
+ else {
+ sd->skillcast[i].id = type2;
+ sd->skillcast[i].val = val;
+ }
break;
- }
- if(sd->skillcast[i].id == type2)
- sd->skillcast[i].val += val;
- else {
- sd->skillcast[i].id = type2;
- sd->skillcast[i].val = val;
- }
- break;
- case SP_FIXCASTRATE:
- if(sd->state.lr_flag == 2)
- break;
+ case SP_FIXCASTRATE:
+ if(sd->state.lr_flag == 2)
+ break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillfixcastrate), i, sd->skillfixcastrate[i].id == 0 || sd->skillfixcastrate[i].id == type2);
+ ARR_FIND(0, ARRAYLENGTH(sd->skillfixcastrate), i, sd->skillfixcastrate[i].id == 0 || sd->skillfixcastrate[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillfixcastrate))
+ if (i == ARRAYLENGTH(sd->skillfixcastrate))
- {
+ {
- ShowDebug("run_script: bonus2 bFixedCastrate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillfixcastrate), type2, val);
- break;
- }
+ ShowDebug("run_script: bonus2 bFixedCastrate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillfixcastrate), type2, val);
+ break;
+ }
- if(sd->skillfixcastrate[i].id == type2)
- sd->skillfixcastrate[i].val += val;
+ if(sd->skillfixcastrate[i].id == type2)
+ sd->skillfixcastrate[i].val += val;
- else {
- sd->skillfixcastrate[i].id = type2;
- sd->skillfixcastrate[i].val = val;
- }
+ else {
+ sd->skillfixcastrate[i].id = type2;
+ sd->skillfixcastrate[i].val = val;
+ }
- break;
+ break;
- case SP_HP_LOSS_RATE:
- if(sd->state.lr_flag != 2) {
- sd->hp_loss.value = type2;
- sd->hp_loss.rate = val;
- }
- break;
- case SP_HP_REGEN_RATE:
- if(sd->state.lr_flag != 2) {
- sd->hp_regen.value = type2;
- sd->hp_regen.rate = val;
- }
- break;
- case SP_ADDRACE2:
- if (!(type2 > RC2_NONE && type2 < RC2_MAX))
+ case SP_HP_LOSS_RATE:
+ if(sd->state.lr_flag != 2) {
+ sd->hp_loss.value = type2;
+ sd->hp_loss.rate = val;
+ }
break;
- if(sd->state.lr_flag != 2)
- sd->right_weapon.addrace2[type2] += val;
- else
- sd->left_weapon.addrace2[type2] += val;
- break;
- case SP_SUBSIZE:
- if(sd->state.lr_flag != 2)
- sd->subsize[type2]+=val;
- break;
- case SP_SUBRACE2:
- if (!(type2 > RC2_NONE && type2 < RC2_MAX))
+ case SP_HP_REGEN_RATE:
+ if(sd->state.lr_flag != 2) {
+ sd->hp_regen.value = type2;
+ sd->hp_regen.rate = val;
+ }
break;
- if(sd->state.lr_flag != 2)
- sd->subrace2[type2]+=val;
- break;
- case SP_ADD_ITEM_HEAL_RATE:
- if(sd->state.lr_flag == 2)
+ case SP_ADDRACE2:
+ if (!(type2 > RC2_NONE && type2 < RC2_MAX))
+ break;
+ if(sd->state.lr_flag != 2)
+ sd->right_weapon.addrace2[type2] += val;
+ else
+ sd->left_weapon.addrace2[type2] += val;
break;
- if (type2 < MAX_ITEMGROUP) { //Group bonus
- sd->itemgrouphealrate[type2] += val;
+ case SP_SUBSIZE:
+ if(sd->state.lr_flag != 2)
+ sd->subsize[type2]+=val;
break;
- }
- //Standard item bonus.
- for(i=0; i < ARRAYLENGTH(sd->itemhealrate) && sd->itemhealrate[i].nameid && sd->itemhealrate[i].nameid != type2; i++);
- if(i == ARRAYLENGTH(sd->itemhealrate)) {
- ShowWarning("pc_bonus2: Reached max (%d) number of item heal bonuses per character!\n", ARRAYLENGTH(sd->itemhealrate));
+ case SP_SUBRACE2:
+ if (!(type2 > RC2_NONE && type2 < RC2_MAX))
+ break;
+ if(sd->state.lr_flag != 2)
+ sd->subrace2[type2]+=val;
break;
- }
- sd->itemhealrate[i].nameid = type2;
- sd->itemhealrate[i].rate += val;
- break;
- case SP_EXP_ADDRACE:
- if(sd->state.lr_flag != 2)
- sd->expaddrace[type2]+=val;
- break;
- case SP_SP_GAIN_RACE:
- if(sd->state.lr_flag != 2)
- sd->sp_gain_race[type2]+=val;
- break;
- case SP_ADD_MONSTER_DROP_ITEM:
- if (sd->state.lr_flag != 2)
- pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, (1<<RC_BOSS)|(1<<RC_NONBOSS), val);
- break;
- case SP_ADD_MONSTER_DROP_ITEMGROUP:
- if (sd->state.lr_flag != 2)
- pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), 0, type2, (1<<RC_BOSS)|(1<<RC_NONBOSS), val);
- break;
- case SP_SP_LOSS_RATE:
- if(sd->state.lr_flag != 2) {
- sd->sp_loss.value = type2;
- sd->sp_loss.rate = val;
- }
- break;
- case SP_SP_REGEN_RATE:
- if(sd->state.lr_flag != 2) {
- sd->sp_regen.value = type2;
- sd->sp_regen.rate = val;
- }
- break;
- case SP_HP_DRAIN_VALUE_RACE:
- 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;
- }
- else if(sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain[type2].value += val;
- }
- break;
- case SP_IGNORE_MDEF_RATE:
- if(sd->state.lr_flag != 2)
- sd->ignore_mdef[type2] += val;
- break;
- case SP_IGNORE_DEF_RATE:
- if(sd->state.lr_flag != 2)
- 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);
- 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);
- break;
- case SP_SKILL_USE_SP_RATE: //bonus2 bSkillUseSPrate,n,x;
- if(sd->state.lr_flag == 2)
+ case SP_ADD_ITEM_HEAL_RATE:
+ if(sd->state.lr_flag == 2)
+ break;
+ //Standard item bonus.
+ for(i=0; i < ARRAYLENGTH(sd->itemhealrate) && sd->itemhealrate[i].nameid && sd->itemhealrate[i].nameid != type2; i++);
+ if(i == ARRAYLENGTH(sd->itemhealrate)) {
+ ShowWarning("pc_bonus2: Reached max (%d) number of item heal bonuses per character!\n", ARRAYLENGTH(sd->itemhealrate));
+ break;
+ }
+ sd->itemhealrate[i].nameid = type2;
+ sd->itemhealrate[i].rate += val;
break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillusesprate), i, sd->skillusesprate[i].id == 0 || sd->skillusesprate[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillusesprate)) {
- ShowDebug("run_script: bonus2 bSkillUseSPrate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillusesprate), type2, val);
+ case SP_EXP_ADDRACE:
+ if(sd->state.lr_flag != 2)
+ sd->expaddrace[type2]+=val;
break;
- }
- if (sd->skillusesprate[i].id == type2)
- sd->skillusesprate[i].val += val;
- else {
- sd->skillusesprate[i].id = type2;
- sd->skillusesprate[i].val = val;
- }
- break;
- case SP_SKILL_COOLDOWN:
- if(sd->state.lr_flag == 2)
+ case SP_SP_GAIN_RACE:
+ if(sd->state.lr_flag != 2)
+ sd->sp_gain_race[type2]+=val;
break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillcooldown), i, sd->skillcooldown[i].id == 0 || sd->skillcooldown[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillcooldown))
- {
- ShowDebug("run_script: bonus2 bSkillCoolDown reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillcooldown), type2, val);
+ case SP_ADD_MONSTER_DROP_ITEM:
+ if (sd->state.lr_flag != 2)
+ pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, (1<<RC_BOSS)|(1<<RC_NONBOSS), val);
break;
- }
- if (sd->skillcooldown[i].id == type2)
- sd->skillcooldown[i].val += val;
- else {
- sd->skillcooldown[i].id = type2;
- sd->skillcooldown[i].val = val;
- }
- break;
- case SP_SKILL_FIXEDCAST:
- if(sd->state.lr_flag == 2)
+ case SP_SP_LOSS_RATE:
+ if(sd->state.lr_flag != 2) {
+ sd->sp_loss.value = type2;
+ sd->sp_loss.rate = val;
+ }
break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillfixcast), i, sd->skillfixcast[i].id == 0 || sd->skillfixcast[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillfixcast))
- {
- ShowDebug("run_script: bonus2 bSkillFixedCast reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillfixcast), type2, val);
+ case SP_SP_REGEN_RATE:
+ if(sd->state.lr_flag != 2) {
+ sd->sp_regen.value = type2;
+ sd->sp_regen.rate = val;
+ }
break;
- }
- if (sd->skillfixcast[i].id == type2)
- sd->skillfixcast[i].val += val;
- else {
- sd->skillfixcast[i].id = type2;
- sd->skillfixcast[i].val = val;
- }
- break;
- case SP_SKILL_VARIABLECAST:
- if(sd->state.lr_flag == 2)
+ case SP_HP_DRAIN_VALUE_RACE:
+ 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;
- ARR_FIND(0, ARRAYLENGTH(sd->skillvarcast), i, sd->skillvarcast[i].id == 0 || sd->skillvarcast[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillvarcast))
- {
- ShowDebug("run_script: bonus2 bSkillVariableCast reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillvarcast), type2, val);
+ case SP_SP_DRAIN_VALUE_RACE:
+ 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;
- }
- if (sd->skillvarcast[i].id == type2)
- sd->skillvarcast[i].val += val;
- else {
- sd->skillvarcast[i].id = type2;
- sd->skillvarcast[i].val = val;
- }
- break;
-#ifdef RENEWAL_CAST
- case SP_VARCASTRATE:
- if(sd->state.lr_flag == 2)
+ case SP_IGNORE_MDEF_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->ignore_mdef[type2] += val;
break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillcast))
- {
- ShowDebug("run_script: bonus2 bVariableCastrate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",ARRAYLENGTH(sd->skillcast), type2, val);
+ case SP_IGNORE_DEF_RATE:
+ if(sd->state.lr_flag != 2)
+ sd->ignore_def[type2] += val;
break;
- }
- if(sd->skillcast[i].id == type2)
- sd->skillcast[i].val -= val;
- else {
- sd->skillcast[i].id = type2;
- sd->skillcast[i].val -= val;
- }
- break;
-#endif
- case SP_SKILL_USE_SP: //bonus2 bSkillUseSP,n,x;
- if(sd->state.lr_flag == 2)
+ 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);
break;
- ARR_FIND(0, ARRAYLENGTH(sd->skillusesp), i, sd->skillusesp[i].id == 0 || sd->skillusesp[i].id == type2);
- if (i == ARRAYLENGTH(sd->skillusesp)) {
- ShowDebug("run_script: bonus2 bSkillUseSP reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillusesp), type2, val);
+ 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);
+ break;
+ case SP_SKILL_USE_SP_RATE: //bonus2 bSkillUseSPrate,n,x;
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillusesprate), i, sd->skillusesprate[i].id == 0 || sd->skillusesprate[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillusesprate)) {
+ ShowDebug("run_script: bonus2 bSkillUseSPrate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillusesprate), type2, val);
+ break;
+ }
+ if (sd->skillusesprate[i].id == type2)
+ sd->skillusesprate[i].val += val;
+ else {
+ sd->skillusesprate[i].id = type2;
+ sd->skillusesprate[i].val = val;
+ }
+ break;
+ case SP_SKILL_COOLDOWN:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillcooldown), i, sd->skillcooldown[i].id == 0 || sd->skillcooldown[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillcooldown))
+ {
+ ShowDebug("run_script: bonus2 bSkillCoolDown reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillcooldown), type2, val);
+ break;
+ }
+ if (sd->skillcooldown[i].id == type2)
+ sd->skillcooldown[i].val += val;
+ else {
+ sd->skillcooldown[i].id = type2;
+ sd->skillcooldown[i].val = val;
+ }
+ break;
+ case SP_SKILL_FIXEDCAST:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillfixcast), i, sd->skillfixcast[i].id == 0 || sd->skillfixcast[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillfixcast))
+ {
+ ShowDebug("run_script: bonus2 bSkillFixedCast reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillfixcast), type2, val);
+ break;
+ }
+ if (sd->skillfixcast[i].id == type2)
+ sd->skillfixcast[i].val += val;
+ else {
+ sd->skillfixcast[i].id = type2;
+ sd->skillfixcast[i].val = val;
+ }
+ break;
+ case SP_SKILL_VARIABLECAST:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillvarcast), i, sd->skillvarcast[i].id == 0 || sd->skillvarcast[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillvarcast))
+ {
+ ShowDebug("run_script: bonus2 bSkillVariableCast reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillvarcast), type2, val);
+ break;
+ }
+ if (sd->skillvarcast[i].id == type2)
+ sd->skillvarcast[i].val += val;
+ else {
+ sd->skillvarcast[i].id = type2;
+ sd->skillvarcast[i].val = val;
+ }
+ break;
+ #ifdef RENEWAL_CAST
+ case SP_VARCASTRATE:
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillcast), i, sd->skillcast[i].id == 0 || sd->skillcast[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillcast))
+ {
+ ShowDebug("run_script: bonus2 bVariableCastrate reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n",ARRAYLENGTH(sd->skillcast), type2, val);
+ break;
+ }
+ if(sd->skillcast[i].id == type2)
+ sd->skillcast[i].val -= val;
+ else {
+ sd->skillcast[i].id = type2;
+ sd->skillcast[i].val -= val;
+ }
+ break;
+ #endif
+ case SP_SKILL_USE_SP: //bonus2 bSkillUseSP,n,x;
+ if(sd->state.lr_flag == 2)
+ break;
+ ARR_FIND(0, ARRAYLENGTH(sd->skillusesp), i, sd->skillusesp[i].id == 0 || sd->skillusesp[i].id == type2);
+ if (i == ARRAYLENGTH(sd->skillusesp)) {
+ ShowDebug("run_script: bonus2 bSkillUseSP reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillusesp), type2, val);
+ break;
+ }
+ if (sd->skillusesp[i].id == type2)
+ sd->skillusesp[i].val += val;
+ else {
+ sd->skillusesp[i].id = type2;
+ sd->skillusesp[i].val = val;
+ }
+ break;
+ case SP_ADD_MONSTER_DROP_CHAINITEM:
+ if (sd->state.lr_flag != 2)
+ pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), 0, val, 1<<type2, 10000);
+ break;
+ default:
+ ShowWarning("pc_bonus2: unknown type %d %d %d!\n",type,type2,val);
break;
- }
- if (sd->skillusesp[i].id == type2)
- sd->skillusesp[i].val += val;
- else {
- sd->skillusesp[i].id = type2;
- sd->skillusesp[i].val = val;
- }
- break;
- default:
- ShowWarning("pc_bonus2: unknown type %d %d %d!\n",type,type2,val);
- break;
}
return 0;
}
@@ -3248,124 +3259,119 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
nullpo_ret(sd);
switch(type){
- case SP_ADD_MONSTER_DROP_ITEM:
- if(sd->state.lr_flag != 2)
- pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, 1<<type3, val);
- break;
- case SP_ADD_CLASS_DROP_ITEM:
- if(sd->state.lr_flag != 2)
- pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, -type3, val);
- break;
- case SP_AUTOSPELL:
- if(sd->state.lr_flag != 2)
- {
- int target = skill->get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
- target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill->get_inf2(type2)&INF2_NO_TARGET_SELF));
- pc_bonus_autospell(sd->autospell, ARRAYLENGTH(sd->autospell),
- target?-type2:type2, type3, val, 0, current_equip_card_id);
- }
- break;
- case SP_AUTOSPELL_WHENHIT:
- if(sd->state.lr_flag != 2)
- {
- int target = skill->get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
- target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill->get_inf2(type2)&INF2_NO_TARGET_SELF));
- pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2),
- target?-type2:type2, type3, val, BF_NORMAL|BF_SKILL, current_equip_card_id);
- }
- break;
- case SP_SP_DRAIN_RATE:
- if(!sd->state.lr_flag) {
- sd->right_weapon.sp_drain[RC_NONBOSS].rate += type2;
- sd->right_weapon.sp_drain[RC_NONBOSS].per += type3;
- sd->right_weapon.sp_drain[RC_NONBOSS].type = val;
- sd->right_weapon.sp_drain[RC_BOSS].rate += type2;
- sd->right_weapon.sp_drain[RC_BOSS].per += type3;
- sd->right_weapon.sp_drain[RC_BOSS].type = val;
-
- }
- else if(sd->state.lr_flag == 1) {
- sd->left_weapon.sp_drain[RC_NONBOSS].rate += type2;
- sd->left_weapon.sp_drain[RC_NONBOSS].per += type3;
- sd->left_weapon.sp_drain[RC_NONBOSS].type = val;
- sd->left_weapon.sp_drain[RC_BOSS].rate += type2;
- sd->left_weapon.sp_drain[RC_BOSS].per += type3;
- sd->left_weapon.sp_drain[RC_BOSS].type = 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;
- }
- 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;
- }
- 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_ADD_MONSTER_DROP_ITEMGROUP:
- if (sd->state.lr_flag != 2)
- pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), 0, type2, 1<<type3, val);
- break;
+ case SP_ADD_MONSTER_DROP_ITEM:
+ if(sd->state.lr_flag != 2)
+ pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, 1<<type3, val);
+ break;
+ case SP_ADD_CLASS_DROP_ITEM:
+ if(sd->state.lr_flag != 2)
+ pc_bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, -type3, val);
+ break;
+ case SP_AUTOSPELL:
+ if(sd->state.lr_flag != 2)
+ {
+ int target = skill->get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
+ target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill->get_inf2(type2)&INF2_NO_TARGET_SELF));
+ pc_bonus_autospell(sd->autospell, ARRAYLENGTH(sd->autospell),
+ target?-type2:type2, type3, val, 0, current_equip_card_id);
+ }
+ break;
+ case SP_AUTOSPELL_WHENHIT:
+ if(sd->state.lr_flag != 2)
+ {
+ int target = skill->get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
+ target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !(skill->get_inf2(type2)&INF2_NO_TARGET_SELF));
+ pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2),
+ target?-type2:type2, type3, val, BF_NORMAL|BF_SKILL, current_equip_card_id);
+ }
+ break;
+ case SP_SP_DRAIN_RATE:
+ if(!sd->state.lr_flag) {
+ sd->right_weapon.sp_drain[RC_NONBOSS].rate += type2;
+ sd->right_weapon.sp_drain[RC_NONBOSS].per += type3;
+ sd->right_weapon.sp_drain[RC_NONBOSS].type = val;
+ sd->right_weapon.sp_drain[RC_BOSS].rate += type2;
+ sd->right_weapon.sp_drain[RC_BOSS].per += type3;
+ sd->right_weapon.sp_drain[RC_BOSS].type = val;
- case SP_ADDEFF:
- if (type2 > SC_MAX) {
- ShowWarning("pc_bonus3 (Add Effect): %d is not supported.\n", type2);
+ }
+ else if(sd->state.lr_flag == 1) {
+ sd->left_weapon.sp_drain[RC_NONBOSS].rate += type2;
+ sd->left_weapon.sp_drain[RC_NONBOSS].per += type3;
+ sd->left_weapon.sp_drain[RC_NONBOSS].type = val;
+ sd->left_weapon.sp_drain[RC_BOSS].rate += type2;
+ sd->left_weapon.sp_drain[RC_BOSS].per += type3;
+ sd->left_weapon.sp_drain[RC_BOSS].type = 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;
+ }
+ 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;
+ }
+ 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:
+ if (type2 > SC_MAX) {
+ ShowWarning("pc_bonus3 (Add Effect): %d is not supported.\n", type2);
+ break;
+ }
+ pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
+ sd->state.lr_flag!=2?type3:0, sd->state.lr_flag==2?type3:0, val);
break;
- }
- pc_bonus_addeff(sd->addeff, ARRAYLENGTH(sd->addeff), (sc_type)type2,
- sd->state.lr_flag!=2?type3:0, sd->state.lr_flag==2?type3:0, val);
- break;
- case SP_ADDEFF_WHENHIT:
- if (type2 > SC_MAX) {
- ShowWarning("pc_bonus3 (Add Effect when hit): %d is not supported.\n", type2);
+ case SP_ADDEFF_WHENHIT:
+ if (type2 > SC_MAX) {
+ ShowWarning("pc_bonus3 (Add Effect when hit): %d is not supported.\n", type2);
+ break;
+ }
+ if(sd->state.lr_flag != 2)
+ pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, type3, 0, val);
break;
- }
- if(sd->state.lr_flag != 2)
- pc_bonus_addeff(sd->addeff2, ARRAYLENGTH(sd->addeff2), (sc_type)type2, type3, 0, val);
- break;
- case SP_ADDEFF_ONSKILL:
- if( type3 > SC_MAX ) {
- ShowWarning("pc_bonus3 (Add Effect on skill): %d is not supported.\n", type3);
+ case SP_ADDEFF_ONSKILL:
+ if( type3 > SC_MAX ) {
+ ShowWarning("pc_bonus3 (Add Effect on skill): %d is not supported.\n", type3);
+ break;
+ }
+ if( sd->state.lr_flag != 2 )
+ pc_bonus_addeff_onskill(sd->addeff3, ARRAYLENGTH(sd->addeff3), (sc_type)type3, val, type2, ATF_TARGET);
break;
- }
- if( sd->state.lr_flag != 2 )
- pc_bonus_addeff_onskill(sd->addeff3, ARRAYLENGTH(sd->addeff3), (sc_type)type3, val, type2, ATF_TARGET);
- break;
- case SP_ADDELE:
- if (type2 > ELE_MAX) {
- ShowWarning("pc_bonus3 (SP_ADDELE): element %d is out of range.\n", type2);
+ case SP_ADDELE:
+ if (type2 > ELE_MAX) {
+ ShowWarning("pc_bonus3 (SP_ADDELE): element %d is out of range.\n", type2);
+ break;
+ }
+ if (sd->state.lr_flag != 2)
+ pc_bonus_addele(sd, (unsigned char)type2, type3, val);
break;
- }
- if (sd->state.lr_flag != 2)
- 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);
+ case SP_SUBELE:
+ if (type2 > ELE_MAX) {
+ ShowWarning("pc_bonus3 (SP_SUBELE): element %d is out of range.\n", type2);
+ break;
+ }
+ if (sd->state.lr_flag != 2)
+ pc_bonus_subele(sd, (unsigned char)type2, type3, val);
break;
- }
- if (sd->state.lr_flag != 2)
- pc_bonus_subele(sd, (unsigned char)type2, type3, val);
- break;
- default:
- ShowWarning("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val);
- break;
+ default:
+ ShowWarning("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val);
+ break;
}
return 0;
@@ -3418,24 +3424,24 @@ int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4
nullpo_ret(sd);
switch(type){
- case SP_AUTOSPELL:
- if(sd->state.lr_flag != 2)
- pc_bonus_autospell(sd->autospell, ARRAYLENGTH(sd->autospell), (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id);
- break;
+ case SP_AUTOSPELL:
+ if(sd->state.lr_flag != 2)
+ pc_bonus_autospell(sd->autospell, ARRAYLENGTH(sd->autospell), (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id);
+ break;
- case SP_AUTOSPELL_WHENHIT:
- if(sd->state.lr_flag != 2)
- pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2), (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id);
- break;
+ case SP_AUTOSPELL_WHENHIT:
+ if(sd->state.lr_flag != 2)
+ pc_bonus_autospell(sd->autospell2, ARRAYLENGTH(sd->autospell2), (val&1?type2:-type2), (val&2?-type3:type3), type4, type5, current_equip_card_id);
+ break;
- case SP_AUTOSPELL_ONSKILL:
- if(sd->state.lr_flag != 2)
- pc_bonus_autospell_onskill(sd->autospell3, ARRAYLENGTH(sd->autospell3), type2, (val&1?-type3:type3), (val&2?-type4:type4), type5, current_equip_card_id);
- break;
+ case SP_AUTOSPELL_ONSKILL:
+ if(sd->state.lr_flag != 2)
+ pc_bonus_autospell_onskill(sd->autospell3, ARRAYLENGTH(sd->autospell3), type2, (val&1?-type3:type3), (val&2?-type4:type4), type5, current_equip_card_id);
+ break;
- default:
- ShowWarning("pc_bonus5: unknown type %d %d %d %d %d %d!\n",type,type2,type3,type4,type5,val);
- break;
+ default:
+ ShowWarning("pc_bonus5: unknown type %d %d %d %d %d %d!\n",type,type2,type3,type4,type5,val);
+ break;
}
return 0;
@@ -3625,7 +3631,7 @@ int pc_checkadditem(struct map_session_data *sd,int nameid,int amount)
if(amount > MAX_AMOUNT)
return ADDITEM_OVERAMOUNT;
- data = itemdb_search(nameid);
+ data = itemdb->search(nameid);
if(!itemdb_isstackable2(data))
return ADDITEM_NEW;
@@ -3860,7 +3866,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
if( amount > MAX_AMOUNT )
return 5;
- data = itemdb_search(item_data->nameid);
+ data = itemdb->search(item_data->nameid);
if( data->stack.inventory && amount > data->stack.amount )
{// item stack limitation
@@ -4247,11 +4253,10 @@ int pc_isUseitem(struct map_session_data *sd,int n)
* 0 = fail
* 1 = success
*------------------------------------------*/
-int pc_useitem(struct map_session_data *sd,int n)
-{
+int pc_useitem(struct map_session_data *sd,int n) {
unsigned int tick = iTimer->gettick();
int amount, nameid, i;
- struct script_code *script;
+ struct script_code *item_script;
nullpo_ret(sd);
@@ -4354,7 +4359,7 @@ int pc_useitem(struct map_session_data *sd,int n)
sd->catch_target_class = -1;
amount = sd->status.inventory[n].amount;
- script = sd->inventory_data[n]->script;
+ item_script = sd->inventory_data[n]->script;
//Check if the item is to be consumed immediately [Skotlex]
if( sd->inventory_data[n]->flag.delay_consume )
clif->useitemack(sd,n,amount,true);
@@ -4377,9 +4382,14 @@ int pc_useitem(struct map_session_data *sd,int n)
sd->canuseitem_tick = tick + battle_config.item_use_interval;
if( itemdb_iscashfood(nameid) )
sd->canusecashfood_tick = tick + battle_config.cashfood_use_interval;
-
- run_script(script,0,sd->bl.id,fake_nd->bl.id);
+
+ script->current_item_id = nameid;
+
+ run_script(item_script,0,sd->bl.id,fake_nd->bl.id);
+
+ script->current_item_id = 0;
potion_flag = 0;
+
return 1;
}
@@ -4399,7 +4409,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
if(item_data->nameid <= 0 || amount <= 0)
return 1;
- data = itemdb_search(item_data->nameid);
+ data = itemdb->search(item_data->nameid);
if( data->stack.cart && amount > data->stack.amount )
{// item stack limitation
@@ -4462,7 +4472,7 @@ int pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type,e_log_
struct item_data * data;
nullpo_retr(1, sd);
- if( sd->status.cart[n].nameid == 0 || sd->status.cart[n].amount < amount || !(data = itemdb_exists(sd->status.cart[n].nameid)) )
+ if( sd->status.cart[n].nameid == 0 || sd->status.cart[n].amount < amount || !(data = itemdb->exists(sd->status.cart[n].nameid)) )
return 1;
logs->pick_pc(sd, log_type, -amount, &sd->status.cart[n],data);
@@ -4567,7 +4577,7 @@ int pc_show_steal(struct block_list *bl,va_list ap)
sd=va_arg(ap,struct map_session_data *);
itemid=va_arg(ap,int);
- if((item=itemdb_exists(itemid))==NULL)
+ if((item=itemdb->exists(itemid))==NULL)
sprintf(output,"%s stole an Unknown Item (id: %i).",sd->status.name, itemid);
else
sprintf(output,"%s stole %s.",sd->status.name,item->jname);
@@ -4620,7 +4630,7 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skil
// Try dropping one item, in the order from first to last possible slot.
// Droprate is affected by the skill success rate.
for( i = 0; i < MAX_STEAL_DROP; i++ )
- if( md->db->dropitem[i].nameid > 0 && (data = itemdb_exists(md->db->dropitem[i].nameid)) && rnd() % 10000 < md->db->dropitem[i].p * rate/100. )
+ if( md->db->dropitem[i].nameid > 0 && (data = itemdb->exists(md->db->dropitem[i].nameid)) && rnd() % 10000 < md->db->dropitem[i].p * rate/100. )
break;
if( i == MAX_STEAL_DROP )
return 0;
@@ -4702,7 +4712,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
nullpo_ret(sd);
- if( !mapindex || !mapindex_id2name(mapindex) ) {
+ if( !mapindex || !mapindex_id2name(mapindex) || ( m = iMap->mapindex2mapid(mapindex) ) == -1 ) {
ShowDebug("pc_setpos: Passed mapindex(%d) is invalid!\n", mapindex);
return 1;
}
@@ -4711,7 +4721,6 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
pc->setstand(sd);
pc->setrestartvalue(sd,1);
}
- m = iMap->mapindex2mapid(mapindex);
if( map[m].flag.src4instance ) {
struct party_data *p;
@@ -4720,9 +4729,11 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
if( sd->instances ) {
for( i = 0; i < sd->instances; i++ ) {
- ARR_FIND(0, instances[sd->instance[i]].num_map, j, map[instances[sd->instance[i]].map[j]].instance_src_map == m && !map[instances[sd->instance[i]].map[j]].cName);
- if( j != instances[sd->instance[i]].num_map )
- break;
+ if( sd->instance[i] >= 0 ) {
+ ARR_FIND(0, instances[sd->instance[i]].num_map, j, map[instances[sd->instance[i]].map[j]].instance_src_map == m && !map[instances[sd->instance[i]].map[j]].cName);
+ if( j != instances[sd->instance[i]].num_map )
+ break;
+ }
}
if( i != sd->instances ) {
m = instances[sd->instance[i]].map[j];
@@ -4732,9 +4743,11 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
}
if ( !stop && sd->status.party_id && (p = party->search(sd->status.party_id)) && p->instances ) {
for( i = 0; i < p->instances; i++ ) {
- ARR_FIND(0, instances[p->instance[i]].num_map, j, map[instances[p->instance[i]].map[j]].instance_src_map == m && !map[instances[p->instance[i]].map[j]].cName);
- if( j != instances[p->instance[i]].num_map )
- break;
+ if( p->instance[i] >= 0 ) {
+ ARR_FIND(0, instances[p->instance[i]].num_map, j, map[instances[p->instance[i]].map[j]].instance_src_map == m && !map[instances[p->instance[i]].map[j]].cName);
+ if( j != instances[p->instance[i]].num_map )
+ break;
+ }
}
if( i != p->instances ) {
m = instances[p->instance[i]].map[j];
@@ -4744,9 +4757,11 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
}
if ( !stop && sd->status.guild_id && sd->guild && sd->guild->instances ) {
for( i = 0; i < sd->guild->instances; i++ ) {
- ARR_FIND(0, instances[sd->guild->instance[i]].num_map, j, map[instances[sd->guild->instance[i]].map[j]].instance_src_map == m && !map[instances[sd->guild->instance[i]].map[j]].cName);
- if( j != instances[sd->guild->instance[i]].num_map )
- break;
+ if( sd->guild->instance[i] >= 0 ) {
+ ARR_FIND(0, instances[sd->guild->instance[i]].num_map, j, map[instances[sd->guild->instance[i]].map[j]].instance_src_map == m && !map[instances[sd->guild->instance[i]].map[j]].cName);
+ if( j != instances[sd->guild->instance[i]].num_map )
+ break;
+ }
}
if( i != sd->guild->instances ) {
m = instances[sd->guild->instance[i]].map[j];
@@ -4831,8 +4846,8 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
sd->bl.x=x;
sd->bl.y=y;
pc->clean_skilltree(sd);
- chrif_save(sd,2);
- chrif_changemapserver(sd, ip, (short)port);
+ chrif->save(sd,2);
+ chrif->changemapserver(sd, ip, (short)port);
//Free session data from this map server [Kevin]
unit_free_pc(sd);
@@ -5041,6 +5056,7 @@ int pc_checkallowskill(struct map_session_data *sd)
SC_DANCING,
SC_GS_GATLINGFEVER,
#ifdef RENEWAL
+ SC_LKCONCENTRATION,
SC_EDP,
#endif
SC_FEARBREEZE
@@ -7301,12 +7317,10 @@ int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp)
bonus += bonus*(potion_flag-1)*50/100;
//All item bonuses.
bonus += sd->bonus.itemhealrate2;
- //Item Group bonuses
- bonus += bonus*itemdb_group_bonus(sd, itemid)/100;
//Individual item bonuses.
- for(i = 0; i < ARRAYLENGTH(sd->itemhealrate) && sd->itemhealrate[i].nameid; i++)
- {
- if (sd->itemhealrate[i].nameid == itemid) {
+ for(i = 0; i < ARRAYLENGTH(sd->itemhealrate) && sd->itemhealrate[i].nameid; i++) {
+ struct item_data *it = itemdb->exists(sd->itemhealrate[i].nameid);
+ if (sd->itemhealrate[i].nameid == itemid || (it && it->group && itemdb->in_group(it->group,itemid))) {
bonus += bonus*sd->itemhealrate[i].rate/100;
break;
}
@@ -7574,16 +7588,16 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
//if you were previously famous, not anymore.
if (fame_flag) {
- chrif_save(sd,0);
- chrif_buildfamelist();
+ chrif->save(sd,0);
+ chrif->buildfamelist();
} else if (sd->status.fame > 0) {
//It may be that now they are famous?
switch (sd->class_&MAPID_UPPERMASK) {
case MAPID_BLACKSMITH:
case MAPID_ALCHEMIST:
case MAPID_TAEKWON:
- chrif_save(sd,0);
- chrif_buildfamelist();
+ chrif->save(sd,0);
+ chrif->buildfamelist();
break;
}
}
@@ -8474,7 +8488,7 @@ int pc_load_combo(struct map_session_data *sd) {
for( j = 0; j < id->slot; j++ ) {
if (!sd->status.inventory[idx].card[j])
continue;
- if ( ( data = itemdb_exists(sd->status.inventory[idx].card[j]) ) != NULL ) {
+ if ( ( data = itemdb->exists(sd->status.inventory[idx].card[j]) ) != NULL ) {
if( data->combos_count )
ret += pc_checkcombo(sd,data);
}
@@ -8658,7 +8672,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
struct item_data *data;
if (!sd->status.inventory[n].card[i])
continue;
- if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) {
+ if ( ( data = itemdb->exists(sd->status.inventory[n].card[i]) ) != NULL ) {
if( data->combos_count )
pc_checkcombo(sd,data);
}
@@ -8681,7 +8695,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
struct item_data *data;
if (!sd->status.inventory[n].card[i])
continue;
- if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) {
+ if ( ( data = itemdb->exists(sd->status.inventory[n].card[i]) ) != NULL ) {
if( data->equip_script )
run_script(data->equip_script,0,sd->bl.id,fake_nd->bl.id);
}
@@ -8819,7 +8833,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
struct item_data *data;
if (!sd->status.inventory[n].card[i])
continue;
- if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) {
+ if ( ( data = itemdb->exists(sd->status.inventory[n].card[i]) ) != NULL ) {
if( data->combos_count ) {
if( pc_removecombo(sd,data) )
status_cacl = true;
@@ -8849,7 +8863,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
if (!sd->status.inventory[n].card[i])
continue;
- if ( ( data = itemdb_exists(sd->status.inventory[n].card[i]) ) != NULL ) {
+ if ( ( data = itemdb->exists(sd->status.inventory[n].card[i]) ) != NULL ) {
if( data->unequip_script )
run_script(data->unequip_script,0,sd->bl.id,fake_nd->bl.id);
}
@@ -9027,7 +9041,7 @@ int pc_divorce(struct map_session_data *sd)
if( (p_sd = iMap->charid2sd(sd->status.partner_id)) == NULL )
{ // Lets char server do the divorce
- if( chrif_divorce(sd->status.char_id, sd->status.partner_id) )
+ if( chrif->divorce(sd->status.char_id, sd->status.partner_id) )
return -1; // No char server connected
return 0;
@@ -9205,7 +9219,7 @@ int pc_autosave(int tid, unsigned int tick, int id, intptr_t data)
last_save_id = sd->bl.id;
save_flag = 2;
- chrif_save(sd,0);
+ chrif->save(sd,0);
break;
}
mapit->free(iter);
@@ -9516,55 +9530,260 @@ int pc_split_atoui(char* str, unsigned int* val, char sep, int max)
val[j] = 0;
return i;
}
+/* [Ind/Hercules] */
+void pc_read_skill_tree(void) {
+ config_t skill_tree_conf;
+ config_setting_t *skt = NULL, *inherit = NULL, *skills = NULL, *sk = NULL;
+#ifdef RENEWAL
+ const char *config_filename = "db/re/skill_tree.conf"; // FIXME hardcoded name
+#else
+ const char *config_filename = "db/pre-re/skill_tree.conf"; // FIXME hardcoded name
+#endif
+ int i = 0, jnamelen = 0;
+ struct {
+ const char *name;
+ int id;
+ } jnames[] = {
+ { "Novice", JOB_NOVICE },
+ { "Swordsman", JOB_SWORDMAN },
+ { "Magician", JOB_MAGE },
+ { "Archer", JOB_ARCHER },
+ { "Acolyte", JOB_ACOLYTE },
+ { "Merchant", JOB_MERCHANT },
+ { "Thief", JOB_THIEF },
+ { "Knight", JOB_KNIGHT },
+ { "Priest", JOB_PRIEST },
+ { "Wizard", JOB_WIZARD },
+ { "Blacksmith", JOB_BLACKSMITH },
+ { "Hunter", JOB_HUNTER },
+ { "Assassin", JOB_ASSASSIN },
+ { "Crusader", JOB_CRUSADER },
+ { "Monk", JOB_MONK },
+ { "Sage", JOB_SAGE },
+ { "Rogue", JOB_ROGUE },
+ { "Alchemist", JOB_ALCHEMIST },
+ { "Bard", JOB_BARD },
+ { "Dancer", JOB_DANCER },
+ { "Super_Novice", JOB_SUPER_NOVICE },
+ { "Gunslinger", JOB_GUNSLINGER },
+ { "Ninja", JOB_NINJA },
+ { "Novice_High", JOB_NOVICE_HIGH },
+ { "Swordsman_High", JOB_SWORDMAN_HIGH },
+ { "Magician_High", JOB_MAGE_HIGH },
+ { "Archer_High", JOB_ARCHER_HIGH },
+ { "Acolyte_High", JOB_ACOLYTE_HIGH },
+ { "Merchant_High", JOB_MERCHANT_HIGH },
+ { "Thief_High", JOB_THIEF_HIGH },
+ { "Lord_Knight", JOB_LORD_KNIGHT },
+ { "High_Priest", JOB_HIGH_PRIEST },
+ { "High_Wizard", JOB_HIGH_WIZARD },
+ { "Whitesmith", JOB_WHITESMITH },
+ { "Sniper", JOB_SNIPER },
+ { "Assassin_Cross", JOB_ASSASSIN_CROSS },
+ { "Paladin", JOB_PALADIN },
+ { "Champion", JOB_CHAMPION },
+ { "Professor", JOB_PROFESSOR },
+ { "Stalker", JOB_STALKER },
+ { "Creator", JOB_CREATOR },
+ { "Clown", JOB_CLOWN },
+ { "Gypsy", JOB_GYPSY },
+ { "Baby_Novice", JOB_BABY },
+ { "Baby_Swordsman", JOB_BABY_SWORDMAN },
+ { "Baby_Magician", JOB_BABY_MAGE },
+ { "Baby_Archer", JOB_BABY_ARCHER },
+ { "Baby_Acolyte", JOB_BABY_ACOLYTE },
+ { "Baby_Merchant", JOB_BABY_MERCHANT },
+ { "Baby_Thief", JOB_BABY_THIEF },
+ { "Baby_Knight", JOB_BABY_KNIGHT },
+ { "Baby_Priest", JOB_BABY_PRIEST },
+ { "Baby_Wizard", JOB_BABY_WIZARD },
+ { "Baby_Blacksmith", JOB_BABY_BLACKSMITH },
+ { "Baby_Hunter", JOB_BABY_HUNTER },
+ { "Baby_Assassin", JOB_BABY_ASSASSIN },
+ { "Baby_Crusader", JOB_BABY_CRUSADER },
+ { "Baby_Monk", JOB_BABY_MONK },
+ { "Baby_Sage", JOB_BABY_SAGE },
+ { "Baby_Rogue", JOB_BABY_ROGUE },
+ { "Baby_Alchemist", JOB_BABY_ALCHEMIST },
+ { "Baby_Bard", JOB_BABY_BARD },
+ { "Baby_Dancer", JOB_BABY_DANCER },
+ { "Super_Baby", JOB_SUPER_BABY },
+ { "Taekwon", JOB_TAEKWON },
+ { "Star_Gladiator", JOB_STAR_GLADIATOR },
+ { "Soul_Linker", JOB_SOUL_LINKER },
+ { "Gangsi", JOB_GANGSI },
+ { "Death_Knight", JOB_DEATH_KNIGHT },
+ { "Dark_Collector", JOB_DARK_COLLECTOR },
+ { "Rune_Knight", JOB_RUNE_KNIGHT },
+ { "Warlock", JOB_WARLOCK },
+ { "Ranger", JOB_RANGER },
+ { "Arch_Bishop", JOB_ARCH_BISHOP },
+ { "Mechanic", JOB_MECHANIC },
+ { "Guillotine_Cross", JOB_GUILLOTINE_CROSS },
+ { "Rune_Knight_Trans", JOB_RUNE_KNIGHT_T },
+ { "Warlock_Trans", JOB_WARLOCK_T },
+ { "Ranger_Trans", JOB_RANGER_T },
+ { "Arch_Bishop_Trans", JOB_ARCH_BISHOP_T },
+ { "Mechanic_Trans", JOB_MECHANIC_T },
+ { "Guillotine_Cross_Trans", JOB_GUILLOTINE_CROSS_T },
+ { "Royal_Guard", JOB_ROYAL_GUARD },
+ { "Sorcerer", JOB_SORCERER },
+ { "Minstrel", JOB_MINSTREL },
+ { "Wanderer", JOB_WANDERER },
+ { "Sura", JOB_SURA },
+ { "Genetic", JOB_GENETIC },
+ { "Shadow_Chaser", JOB_SHADOW_CHASER },
+ { "Royal_Guard_Trans", JOB_ROYAL_GUARD_T },
+ { "Sorcerer_Trans", JOB_SORCERER_T },
+ { "Minstrel_Trans", JOB_MINSTREL_T },
+ { "Wanderer_Trans", JOB_WANDERER_T },
+ { "Sura_Trans", JOB_SURA_T },
+ { "Genetic_Trans", JOB_GENETIC_T },
+ { "Shadow_Chaser_Trans", JOB_SHADOW_CHASER_T },
+ { "Baby_Rune_Knight", JOB_BABY_RUNE },
+ { "Baby_Warlock", JOB_BABY_WARLOCK },
+ { "Baby_Ranger", JOB_BABY_RANGER },
+ { "Baby_Arch_Bishop", JOB_BABY_BISHOP },
+ { "Baby_Mechanic", JOB_BABY_MECHANIC },
+ { "Baby_Guillotine_Cross", JOB_BABY_CROSS },
+ { "Baby_Royal_Guard", JOB_BABY_GUARD },
+ { "Baby_Sorcerer", JOB_BABY_SORCERER },
+ { "Baby_Minstrel", JOB_BABY_MINSTREL },
+ { "Baby_Wanderer", JOB_BABY_WANDERER },
+ { "Baby_Sura", JOB_BABY_SURA },
+ { "Baby_Genetic", JOB_BABY_GENETIC },
+ { "Baby_Shadow_Chaser", JOB_BABY_CHASER },
+ { "Expanded_Super_Novice", JOB_SUPER_NOVICE_E },
+ { "Expanded_Super_Baby", JOB_SUPER_BABY_E },
+ { "Kagerou", JOB_KAGEROU },
+ { "Oboro", JOB_OBORO },
+ };
+
+ if (conf_read_file(&skill_tree_conf, config_filename)) {
+ ShowError("can't read %s\n", config_filename);
+ return;
+ }
+
+ jnamelen = ARRAYLENGTH(jnames);
+
+ while( (skt = config_setting_get_elem(skill_tree_conf.root,i++)) ) {
+ int k, idx;
+ const char *name = config_setting_name(skt);
+
+ ARR_FIND(0, jnamelen, k, strcmpi(jnames[k].name,name) == 0 );
+
+ if( k == jnamelen ) {
+ ShowWarning("pc_read_skill_tree: '%s' unknown job name!\n",name);
+ continue;
+ }
+
+
+ if( ( skills = config_setting_get_member(skt,"skills") ) ) {
+ int c = 0;
+
+ idx = pc->class2idx(jnames[k].id);
+
+ while( ( sk = config_setting_get_elem(skills,c++) ) ) {
+ const char *sk_name = config_setting_name(sk);
+ int skill_id;
+
+ if( ( skill_id = skill->name2id(sk_name) ) ) {
+ int skidx, offset = 0, h = 0, rlen = 0, rskid = 0;
+
+ ARR_FIND( 0, MAX_SKILL_TREE, skidx, skill_tree[idx][skidx].id == 0 || skill_tree[idx][skidx].id == skill_id );
+ if( skidx == MAX_SKILL_TREE ) {
+ ShowWarning("pc_read_skill_tree: Unable to load skill %hu (%s) into '%s's tree. Maximum number of skills per class has been reached.\n", skill_id, sk_name, name);
+ continue;
+ } else if(skill_tree[idx][skidx].id) {
+ ShowNotice("pc_read_skill_tree: Overwriting %hu for '%s' (%d)\n", skill_id, name, jnames[k].id);
+ }
+
+ skill_tree[idx][skidx].id = skill_id;
+ skill_tree[idx][skidx].idx = skill->get_index(skill_id);
+
+ if( config_setting_is_group(sk) ) {
+ int max = 0, jlevel = 0;
+ config_setting_lookup_int(sk, "MaxLevel", &max);
+ config_setting_lookup_int(sk, "MinJobLevel", &jlevel);
+ skill_tree[idx][skidx].max = (unsigned char)max;
+ skill_tree[idx][skidx].joblv = (unsigned char)jlevel;
+ rlen = config_setting_length(sk);
+ offset += jlevel ? 2 : 1;
+ } else {
+ skill_tree[idx][skidx].max = (unsigned char)config_setting_get_int(sk);
+ skill_tree[idx][skidx].joblv = 0;
+ }
+
+ for( h = offset; h < rlen && h < MAX_PC_SKILL_REQUIRE; h++ ) {
+ config_setting_t *rsk = config_setting_get_elem(sk,h);
+ if( rsk && ( rskid = skill->name2id(config_setting_name(rsk)) ) ) {
+ skill_tree[idx][skidx].need[h].id = rskid;
+ skill_tree[idx][skidx].need[h].idx = skill->get_index(rskid);
+ skill_tree[idx][skidx].need[h].lv = (unsigned char)config_setting_get_int(rsk);
+ } else if( rsk ) {
+ ShowWarning("pc_read_skill_tree: unknown requirement '%s' for '%s' in '%s'\n",config_setting_name(rsk),sk_name,name);
+ } else {
+ ShowWarning("pc_read_skill_tree: error for '%s' in '%s'\n",sk_name,name);
+ }
+ }
+
+ } else {
+ ShowWarning("pc_read_skill_tree: unknown skill '%s' in '%s'\n",sk_name,name);
+ }
+ }
+ }
+ }
+
+ i = 0;
+ while( (skt = config_setting_get_elem(skill_tree_conf.root,i++)) ) {
+ int k, idx, v = 0;
+ const char *name = config_setting_name(skt);
+ const char *iname;
-/*==========================================
- * sub DB reading.
- * Function used to read skill_tree.txt
- *------------------------------------------*/
-static bool pc_readdb_skilltree(char* fields[], int columns, int current)
-{
- unsigned char joblv = 0, skill_lv;
- uint16 skill_id;
- int idx, class_;
- unsigned int i, offset = 3, skill_idx;
+
+ ARR_FIND(0, jnamelen, k, strcmpi(jnames[k].name,name) == 0 );
+
+ if( k == jnamelen ) {
+ ShowWarning("pc_read_skill_tree: '%s' unknown job name!\n",name);
+ continue;
+ }
+ idx = pc->class2idx(jnames[k].id);
- class_ = atoi(fields[0]);
- skill_id = (uint16)atoi(fields[1]);
- skill_lv = (unsigned char)atoi(fields[2]);
+ if( ( inherit = config_setting_get_member(skt,"inherit") ) ) {
+ while( ( iname = config_setting_get_string_elem(inherit, v++) ) ) {
+ int b = 0, a, d, f, fidx;
- if(columns==4+MAX_PC_SKILL_REQUIRE*2)
- {// job level requirement extra column
- joblv = (unsigned char)atoi(fields[3]);
- offset++;
- }
+ ARR_FIND(0, jnamelen, b, strcmpi(jnames[b].name,iname) == 0 );
+
+ if( b == jnamelen ) {
+ ShowWarning("pc_read_skill_tree: '%s' trying to inherit unknown '%s'!\n",name,iname);
+ continue;
+ }
+
+ fidx = pc->class2idx(jnames[b].id);
+
+ ARR_FIND( 0, MAX_SKILL_TREE, d, skill_tree[fidx][d].id == 0 );
- if(!pcdb_checkid(class_))
- {
- ShowWarning("pc_readdb_skilltree: Invalid job class %d specified.\n", class_);
- return false;
- }
- idx = pc->class2idx(class_);
+ for( f = 0; f < d; f++ ) {
+
+ ARR_FIND( 0, MAX_SKILL_TREE, a, skill_tree[idx][a].id == 0 || skill_tree[idx][a].id == skill_tree[fidx][f].id );
- //This is to avoid adding two lines for the same skill. [Skotlex]
- ARR_FIND( 0, MAX_SKILL_TREE, skill_idx, skill_tree[idx][skill_idx].id == 0 || skill_tree[idx][skill_idx].id == skill_id );
- if( skill_idx == MAX_SKILL_TREE ) {
- ShowWarning("pc_readdb_skilltree: Unable to load skill %hu into job %d's tree. Maximum number of skills per class has been reached.\n", skill_id, class_);
- return false;
- } else if(skill_tree[idx][skill_idx].id) {
- ShowNotice("pc_readdb_skilltree: Overwriting skill %hu for job class %d.\n", skill_id, class_);
+ if( a == MAX_SKILL_TREE ) {
+ ShowWarning("pc_read_skill_tree: '%s' can't inherit '%s', skill tree is full!\n", name,iname);
+ break;
+ } else if ( skill_tree[idx][a].id || ( skill_tree[idx][a].id == NV_TRICKDEAD && ((pc->jobid2mapid(jnames[k].id)&MAPID_UPPERMASK)!=MAPID_NOVICE) ) ) /* we skip trickdead for non-novices */
+ continue;/* skip */
+
+ memcpy(&skill_tree[idx][a],&skill_tree[fidx][f],sizeof(skill_tree[fidx][f]));
+ }
+
+ }
+ }
+
}
+
+ config_destroy(&skill_tree_conf);
- skill_tree[idx][skill_idx].id = skill_id;
- skill_tree[idx][skill_idx].idx = skill->get_index(skill_id);
- skill_tree[idx][skill_idx].max = skill_lv;
- skill_tree[idx][skill_idx].joblv = joblv;
-
- for(i = 0; i < MAX_PC_SKILL_REQUIRE; i++) {
- skill_tree[idx][skill_idx].need[i].id = atoi(fields[i*2+offset]);
- skill_tree[idx][skill_idx].need[i].idx = skill->get_index(atoi(fields[i*2+offset]));
- skill_tree[idx][skill_idx].need[i].lv = atoi(fields[i*2+offset+1]);
- }
- return true;
}
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
static bool pc_readdb_levelpenalty(char* fields[], int columns, int current)
@@ -9696,8 +9915,7 @@ int pc_readdb(void)
count = 0;
// Reset and read skilltree
memset(skill_tree,0,sizeof(skill_tree));
- sv->readdb(iMap->db_path, DBPATH"skill_tree.txt", ',', 3+MAX_PC_SKILL_REQUIRE*2, 4+MAX_PC_SKILL_REQUIRE*2, -1, &pc_readdb_skilltree);
-
+ pc_read_skill_tree();
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
sv->readdb(iMap->db_path, "re/level_penalty.txt", ',', 4, 4, -1, &pc_readdb_levelpenalty);
for( k=1; k < 3; k++ ){ // fill in the blanks
diff --git a/src/map/pc.h b/src/map/pc.h
index 43d5d40c7..442b55965 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -10,7 +10,7 @@
#include "battle.h" // battle_config
#include "battleground.h"
#include "buyingstore.h" // struct s_buyingstore
-#include "itemdb.h" // MAX_ITEMGROUP
+#include "itemdb.h"
#include "map.h" // RC_MAX
#include "script.h" // struct script_reg, struct script_regstr
#include "searchstore.h" // struct s_search_store_info
@@ -256,7 +256,6 @@ struct map_session_data {
int expaddrace[RC_MAX];
int ignore_mdef[RC_MAX];
int ignore_def[RC_MAX];
- int itemgrouphealrate[MAX_ITEMGROUP];
short sp_gain_race[RC_MAX];
short sp_gain_race_attack[RC_MAX];
short hp_gain_race_attack[RC_MAX];
@@ -483,7 +482,7 @@ struct map_session_data {
struct sc_display_entry **sc_display;
unsigned char sc_display_count;
- unsigned short *instance;
+ short *instance;
unsigned short instances;
/* Possible Thanks to Yommy~! */
diff --git a/src/map/pet.c b/src/map/pet.c
index 00402f9d4..e6ef0a488 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -408,7 +408,7 @@ int pet_birth_process(struct map_session_data *sd, struct s_pet *pet)
intif_save_petdata(sd->status.account_id,pet);
if (iMap->save_settings&8)
- chrif_save(sd,0); //is it REALLY Needed to save the char for hatching a pet? [Skotlex]
+ chrif->save(sd,0); //is it REALLY Needed to save the char for hatching a pet? [Skotlex]
if(sd->bl.prev != NULL) {
iMap->addblock(&sd->pd->bl);
@@ -592,7 +592,7 @@ int pet_menu(struct map_session_data *sd,int menunum)
if(!sd->status.pet_id || sd->pd->pet.intimate <= 0 || sd->pd->pet.incuvate)
return 1;
- egg_id = itemdb_exists(sd->pd->petDB->EggID);
+ egg_id = itemdb->exists(sd->pd->petDB->EggID);
if (egg_id) {
if ((egg_id->flag.trade_restriction&0x01) && !pc->inventoryblank(sd)) {
clif->message(sd->fd, msg_txt(451)); // You can't return your pet because your inventory is full.
diff --git a/src/map/quest.c b/src/map/quest.c
index b56088886..3776d603f 100644
--- a/src/map/quest.c
+++ b/src/map/quest.c
@@ -100,7 +100,7 @@ int quest_add(TBL_PC * sd, int quest_id)
clif->quest_add(sd, &sd->quest_log[i], sd->quest_index[i]);
if( iMap->save_settings&64 )
- chrif_save(sd,0);
+ chrif->save(sd,0);
return 0;
}
@@ -148,7 +148,7 @@ int quest_change(TBL_PC * sd, int qid1, int qid2)
clif->quest_add(sd, &sd->quest_log[i], sd->quest_index[i]);
if( iMap->save_settings&64 )
- chrif_save(sd,0);
+ chrif->save(sd,0);
return 0;
}
@@ -179,7 +179,7 @@ int quest_delete(TBL_PC * sd, int quest_id)
clif->quest_delete(sd, quest_id);
if( iMap->save_settings&64 )
- chrif_save(sd,0);
+ chrif->save(sd,0);
return 0;
}
@@ -250,7 +250,7 @@ int quest_update_status(TBL_PC * sd, int quest_id, quest_state status) {
clif->quest_delete(sd, quest_id);
if( iMap->save_settings&64 )
- chrif_save(sd,0);
+ chrif->save(sd,0);
return 0;
}
diff --git a/src/map/script.c b/src/map/script.c
index 682faa42b..4ceb32991 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -238,7 +238,8 @@ enum {
MF_MONSTER_NOTELEPORT,
MF_PVP_NOCALCRANK, //50
MF_BATTLEGROUND,
- MF_RESET
+ MF_RESET,
+ MF_NOTOMB
};
const char* script_op2name(int op)
@@ -1397,7 +1398,7 @@ const char* parse_syntax(const char* p)
v = p2-p; // length of word at p2
memcpy(label,p,v);
label[v]='\0';
- if( !script_get_constant(label, &v) )
+ if( !script->get_constant(label, &v) )
disp_error_message("parse_syntax: 'case' label is not an integer",p);
p = skip_word(p);
} else { //Numeric value
@@ -1951,25 +1952,31 @@ bool script_get_constant(const char* name, int* value)
}
/// Creates new constant or parameter with given value.
-void script_set_constant(const char* name, int value, bool isparameter)
-{
+void script_set_constant(const char* name, int value, bool isparameter) {
int n = add_str(name);
- if( script->str_data[n].type == C_NOP )
- {// new
+ if( script->str_data[n].type == C_NOP ) {// new
script->str_data[n].type = isparameter ? C_PARAM : C_INT;
script->str_data[n].val = value;
- }
- else if( script->str_data[n].type == C_PARAM || script->str_data[n].type == C_INT )
- {// existing parameter or constant
+ } else if( script->str_data[n].type == C_PARAM || script->str_data[n].type == C_INT ) {// existing parameter or constant
ShowError("script_set_constant: Attempted to overwrite existing %s '%s' (old value=%d, new value=%d).\n", ( script->str_data[n].type == C_PARAM ) ? "parameter" : "constant", name, script->str_data[n].val, value);
- }
- else
- {// existing name
+ } else {// existing name
ShowError("script_set_constant: Invalid name for %s '%s' (already defined as %s).\n", isparameter ? "parameter" : "constant", name, script_op2name(script->str_data[n].type));
}
}
+/* will override if necessary */
+void script_set_constant2(const char *name, int value, bool isparameter) {
+ int n = add_str(name);
+
+ if( script->str_data[n].type != C_NOP ) {
+ script->str_data[n].func = NULL;
+ script->str_data[n].backpatch = -1;
+ script->str_data[n].label = -1;
+ }
+ script->str_data[n].type = isparameter ? C_PARAM : C_INT;
+ script->str_data[n].val = value;
+}
/*==========================================
* Reading constant databases
* const.txt
@@ -2776,28 +2783,31 @@ struct script_state* script_alloc_state(struct script_code* rootscript, int pos,
/// Frees a script state.
///
/// @param st Script state
-void script_free_state(struct script_state* st)
-{
- if(st->bk_st) {// backup was not restored
- ShowDebug("script_free_state: Previous script state lost (rid=%d, oid=%d, state=%d, bk_npcid=%d).\n", st->bk_st->rid, st->bk_st->oid, st->bk_st->state, st->bk_npcid);
- }
+void script_free_state(struct script_state* st) {
+ if( idb_exists(script->st_db,st->id) ) {
+ if(st->bk_st) {// backup was not restored
+ ShowDebug("script_free_state: Previous script state lost (rid=%d, oid=%d, state=%d, bk_npcid=%d).\n", st->bk_st->rid, st->bk_st->oid, st->bk_st->state, st->bk_npcid);
+ }
- if( st->sleep.timer != INVALID_TIMER )
- iTimer->delete_timer(st->sleep.timer, run_script_timer);
- script_free_vars(st->stack->var_function);
- script->pop_stack(st, 0, st->stack->sp);
- aFree(st->stack->stack_data);
- ers_free(script->stack_ers, st->stack);
- if( st->script && st->script->script_vars && !db_size(st->script->script_vars) ) {
- script_free_vars(st->script->script_vars);
- st->script->script_vars = NULL;
- }
- st->stack = NULL;
- st->pos = -1;
- idb_remove(script->st_db, st->id);
- ers_free(script->st_ers, st);
- if( --script->active_scripts == 0 ) {
- script->next_id = 0;
+ if( st->sleep.timer != INVALID_TIMER )
+ iTimer->delete_timer(st->sleep.timer, run_script_timer);
+ if( st->stack ) {
+ script_free_vars(st->stack->var_function);
+ script->pop_stack(st, 0, st->stack->sp);
+ aFree(st->stack->stack_data);
+ ers_free(script->stack_ers, st->stack);
+ st->stack = NULL;
+ }
+ if( st->script && st->script->script_vars && !db_size(st->script->script_vars) ) {
+ script_free_vars(st->script->script_vars);
+ st->script->script_vars = NULL;
+ }
+ st->pos = -1;
+ idb_remove(script->st_db, st->id);
+ ers_free(script->st_ers, st);
+ if( --script->active_scripts == 0 ) {
+ script->next_id = 0;
+ }
}
}
@@ -5564,11 +5574,11 @@ BUILDIN(countitem)
if( data_isstring(data) )
{// item name
- id = itemdb_searchname(script->conv_str(st, data));
+ id = itemdb->search_name(script->conv_str(st, data));
}
else
{// item id
- id = itemdb_exists(script->conv_num(st, data));
+ id = itemdb->exists(script->conv_num(st, data));
}
if( id == NULL )
@@ -5611,11 +5621,11 @@ BUILDIN(countitem2)
if( data_isstring(data) )
{// item name
- id = itemdb_searchname(script->conv_str(st, data));
+ id = itemdb->search_name(script->conv_str(st, data));
}
else
{// item id
- id = itemdb_exists(script->conv_num(st, data));
+ id = itemdb->exists(script->conv_num(st, data));
}
if( id == NULL )
@@ -5678,9 +5688,9 @@ BUILDIN(checkweight)
data = script_getdata(st,i);
script->get_val(st, data); // convert into value in case of a variable
if( data_isstring(data) ){// item name
- id = itemdb_searchname(script->conv_str(st, data));
+ id = itemdb->search_name(script->conv_str(st, data));
} else {// item id
- id = itemdb_exists(script->conv_num(st, data));
+ id = itemdb->exists(script->conv_num(st, data));
}
if( id == NULL ) {
ShowError("buildin_checkweight: Invalid item '%s'.\n", script_getstr(st,i)); // returns string, regardless of what it was
@@ -5794,7 +5804,7 @@ BUILDIN(checkweight2)
script_removetop(st, -1, 0);
if(fail) continue; //cpntonie to depop rest
- if(itemdb_exists(nameid) == NULL ){
+ if(itemdb->exists(nameid) == NULL ){
ShowError("buildin_checkweight2: Invalid item '%d'.\n", nameid);
fail=1;
continue;
@@ -5852,7 +5862,7 @@ BUILDIN(getitem)
if( data_isstring(data) )
{// "<item name>"
const char *name=script->conv_str(st,data);
- if( (item_data = itemdb_searchname(name)) == NULL ){
+ if( (item_data = itemdb->search_name(name)) == NULL ){
ShowError("buildin_getitem: Nonexistant item %s requested.\n", name);
return false; //No item created.
}
@@ -5864,7 +5874,7 @@ BUILDIN(getitem)
nameid = -nameid;
flag = 1;
}
- if( nameid <= 0 || !(item_data = itemdb_exists(nameid)) ){
+ if( nameid <= 0 || !(item_data = itemdb->exists(nameid)) ){
ShowError("buildin_getitem: Nonexistant item %d requested.\n", nameid);
return false; //No item created.
}
@@ -5939,7 +5949,7 @@ BUILDIN(getitem2)
script->get_val(st,data);
if( data_isstring(data) ){
const char *name=script->conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
+ struct item_data *item_data = itemdb->search_name(name);
if( item_data )
nameid=item_data->nameid;
else
@@ -5963,7 +5973,7 @@ BUILDIN(getitem2)
if(nameid > 0) {
memset(&item_tmp,0,sizeof(item_tmp));
- item_data=itemdb_exists(nameid);
+ item_data=itemdb->exists(nameid);
if (item_data == NULL)
return -1;
if(item_data->type==IT_WEAPON || item_data->type==IT_ARMOR){
@@ -6035,7 +6045,7 @@ BUILDIN(rentitem)
if( data_isstring(data) )
{
const char *name = script->conv_str(st,data);
- struct item_data *itd = itemdb_searchname(name);
+ struct item_data *itd = itemdb->search_name(name);
if( itd == NULL )
{
ShowError("buildin_rentitem: Nonexistant item %s requested.\n", name);
@@ -6046,7 +6056,7 @@ BUILDIN(rentitem)
else if( data_isint(data) )
{
nameid = script->conv_num(st,data);
- if( nameid <= 0 || !itemdb_exists(nameid) )
+ if( nameid <= 0 || !itemdb->exists(nameid) )
{
ShowError("buildin_rentitem: Nonexistant item %d requested.\n", nameid);
return false;
@@ -6097,7 +6107,7 @@ BUILDIN(getnameditem)
script->get_val(st,data);
if( data_isstring(data) ){
const char *name=script->conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
+ struct item_data *item_data = itemdb->search_name(name);
if( item_data == NULL)
{ //Failed
script_pushint(st,0);
@@ -6107,7 +6117,7 @@ BUILDIN(getnameditem)
}else
nameid = script->conv_num(st,data);
- if(!itemdb_exists(nameid)/* || itemdb_isstackable(nameid)*/)
+ if(!itemdb->exists(nameid)/* || itemdb_isstackable(nameid)*/)
{ //Even though named stackable items "could" be risky, they are required for certain quests.
script_pushint(st,0);
return true;
@@ -6146,12 +6156,30 @@ BUILDIN(getnameditem)
* gets a random item ID from an item group [Skotlex]
* groupranditem group_num
*------------------------------------------*/
-BUILDIN(grouprandomitem)
-{
- int group;
+BUILDIN(grouprandomitem) {
+ struct item_data *data;
+ int nameid;
+
+ if( script_hasdata(st, 2) )
+ nameid = script_getnum(st, 2);
+ else if ( script->current_item_id )
+ nameid = script->current_item_id;
+ else {
+ ShowWarning("buildin_grouprandomitem: no item id provided and no item attached\n");
+ script_pushint(st, 0);
+ return true;
+ }
- group = script_getnum(st,2);
- script_pushint(st,itemdb_searchrandomid(group));
+ if( !(data = itemdb->exists(nameid)) ) {
+ ShowWarning("buildin_grouprandomitem: unknown item id %d\n",nameid);
+ script_pushint(st, 0);
+ } else if ( !data->group ) {
+ ShowWarning("buildin_grouprandomitem: item '%s' (%d) isn't a group!\n",data->name,nameid);
+ script_pushint(st, 0);
+ } else {
+ script_pushint(st, itemdb->group_item(data->group));
+ }
+
return true;
}
@@ -6171,13 +6199,13 @@ BUILDIN(makeitem)
script->get_val(st,data);
if( data_isstring(data) ){
const char *name=script->conv_str(st,data);
- if( (item_data = itemdb_searchname(name)) )
+ if( (item_data = itemdb->search_name(name)) )
nameid=item_data->nameid;
else
nameid=UNKNOWN_ITEM_ID;
} else {
nameid=script->conv_num(st,data);
- if( nameid <= 0 || !(item_data = itemdb_exists(nameid)) ){
+ if( nameid <= 0 || !(item_data = itemdb->exists(nameid)) ){
ShowError("makeitem: Nonexistant item %d requested.\n", nameid);
return false; //No item created.
}
@@ -6384,7 +6412,7 @@ BUILDIN(delitem)
if( data_isstring(data) )
{
const char* item_name = script->conv_str(st,data);
- struct item_data* id = itemdb_searchname(item_name);
+ struct item_data* id = itemdb->search_name(item_name);
if( id == NULL )
{
ShowError("script:delitem: unknown item \"%s\".\n", item_name);
@@ -6396,7 +6424,7 @@ BUILDIN(delitem)
else
{
it.nameid = script->conv_num(st,data);// <item id>
- if( !itemdb_exists( it.nameid ) )
+ if( !itemdb->exists( it.nameid ) )
{
ShowError("script:delitem: unknown item \"%d\".\n", it.nameid);
st->state = END;
@@ -6453,7 +6481,7 @@ BUILDIN(delitem2)
if( data_isstring(data) )
{
const char* item_name = script->conv_str(st,data);
- struct item_data* id = itemdb_searchname(item_name);
+ struct item_data* id = itemdb->search_name(item_name);
if( id == NULL )
{
ShowError("script:delitem2: unknown item \"%s\".\n", item_name);
@@ -6465,7 +6493,7 @@ BUILDIN(delitem2)
else
{
it.nameid = script->conv_num(st,data);// <item id>
- if( !itemdb_exists( it.nameid ) )
+ if( !itemdb->exists( it.nameid ) )
{
ShowError("script:delitem: unknown item \"%d\".\n", it.nameid);
st->state = END;
@@ -8179,20 +8207,18 @@ BUILDIN(gettimestr)
/*==========================================
* Open player storage
*------------------------------------------*/
-BUILDIN(openstorage)
-{
+BUILDIN(openstorage) {
TBL_PC* sd;
sd = script_rid2sd(st);
if( sd == NULL )
return true;
- storage_storageopen(sd);
+ storage->open(sd);
return true;
}
-BUILDIN(guildopenstorage)
-{
+BUILDIN(guildopenstorage) {
TBL_PC* sd;
int ret;
@@ -8200,7 +8226,7 @@ BUILDIN(guildopenstorage)
if( sd == NULL )
return true;
- ret = storage_guild_storageopen(sd);
+ ret = gstorage->open(sd);
script_pushint(st,ret);
return true;
}
@@ -8424,7 +8450,12 @@ BUILDIN(monster)
if (sd && strcmp(mapn, "this") == 0)
m = sd->bl.m;
else {
- m = iMap->mapname2mapid(mapn);
+
+ if ( ( m = iMap->mapname2mapid(mapn) ) == -1 ) {
+ ShowWarning("buildin_monster: Attempted to spawn monster class %d on non-existing map '%s'\n",class_, mapn);
+ return false;
+ }
+
if (map[m].flag.src4instance && st->instance_id >= 0) { // Try to redirect to the instance map, not the src map
if ((m = instance->mapid2imapid(m, st->instance_id)) < 0) {
ShowError("buildin_monster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
@@ -8458,7 +8489,7 @@ BUILDIN(getmobdrops)
{
if( mob->dropitem[i].nameid < 1 )
continue;
- if( itemdb_exists(mob->dropitem[i].nameid) == NULL )
+ if( itemdb->exists(mob->dropitem[i].nameid) == NULL )
continue;
mapreg_setreg(reference_uid(add_str("$@MobDrop_item"), j), mob->dropitem[i].nameid);
@@ -9131,14 +9162,14 @@ BUILDIN(itemeffect) {
if( data_isstring( data ) ){
const char *name = script->conv_str( st, data );
- if( ( item_data = itemdb_searchname( name ) ) == NULL ){
+ if( ( item_data = itemdb->search_name( name ) ) == NULL ){
ShowError( "buildin_itemeffect: Nonexistant item %s requested.\n", name );
return false;
}
} else if( data_isint( data ) ){
int nameid = script->conv_num( st, data );
- if( ( item_data = itemdb_exists( nameid ) ) == NULL ){
+ if( ( item_data = itemdb->exists( nameid ) ) == NULL ){
ShowError("buildin_itemeffect: Nonexistant item %d requested.\n", nameid );
return false;
}
@@ -9365,7 +9396,7 @@ BUILDIN(getareadropitem)
script->get_val(st,data);
if( data_isstring(data) ){
const char *name=script->conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
+ struct item_data *item_data = itemdb->search_name(name);
item=UNKNOWN_ITEM_ID;
if( item_data )
item=item_data->nameid;
@@ -9934,7 +9965,7 @@ BUILDIN(changesex)
// 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);
- chrif_changesex(sd);
+ chrif->changesex(sd);
return true;
}
@@ -10313,6 +10344,7 @@ BUILDIN(getmapflag)
case MF_PVP_NOCALCRANK: script_pushint(st,map[m].flag.pvp_nocalcrank); break;
case MF_BATTLEGROUND: script_pushint(st,map[m].flag.battleground); break;
case MF_RESET: script_pushint(st,map[m].flag.reset); break;
+ case MF_NOTOMB: script_pushint(st,map[m].flag.notomb); break;
}
}
@@ -10429,6 +10461,7 @@ BUILDIN(setmapflag)
case MF_PVP_NOCALCRANK: map[m].flag.pvp_nocalcrank = 1; break;
case MF_BATTLEGROUND: map[m].flag.battleground = (val <= 0 || val > 2) ? 1 : val; break;
case MF_RESET: map[m].flag.reset = 1; break;
+ case MF_NOTOMB: map[m].flag.notomb = 1; break;
}
}
@@ -10517,6 +10550,7 @@ BUILDIN(removemapflag)
case MF_PVP_NOCALCRANK: map[m].flag.pvp_nocalcrank = 0; break;
case MF_BATTLEGROUND: map[m].flag.battleground = 0; break;
case MF_RESET: map[m].flag.reset = 0; break;
+ case MF_NOTOMB: map[m].flag.notomb = 0; break;
}
}
@@ -11448,13 +11482,13 @@ BUILDIN(getitemname)
if( data_isstring(data) ){
const char *name=script->conv_str(st,data);
- struct item_data *item_data = itemdb_searchname(name);
+ struct item_data *item_data = itemdb->search_name(name);
if( item_data )
item_id=item_data->nameid;
}else
item_id=script->conv_num(st,data);
- i_data = itemdb_exists(item_id);
+ i_data = itemdb->exists(item_id);
if (i_data == NULL)
{
script_pushconststr(st,"null");
@@ -11476,7 +11510,7 @@ BUILDIN(getitemslots)
item_id=script_getnum(st,2);
- i_data = itemdb_exists(item_id);
+ i_data = itemdb->exists(item_id);
if (i_data)
script_pushint(st,i_data->slot);
@@ -11517,7 +11551,7 @@ BUILDIN(getiteminfo)
item_id = script_getnum(st,2);
n = script_getnum(st,3);
- i_data = itemdb_exists(item_id);
+ i_data = itemdb->exists(item_id);
if (i_data && n>=0 && n<=14) {
item_arr = (int*)&i_data->value_buy;
@@ -11559,7 +11593,7 @@ BUILDIN(setiteminfo)
item_id = script_getnum(st,2);
n = script_getnum(st,3);
value = script_getnum(st,4);
- i_data = itemdb_exists(item_id);
+ i_data = itemdb->exists(item_id);
if (i_data && n>=0 && n<=14) {
item_arr = (int*)&i_data->value_buy;
@@ -13108,7 +13142,7 @@ BUILDIN(equip)
sd = script_rid2sd(st);
nameid=script_getnum(st,2);
- if((item_data = itemdb_exists(nameid)) == NULL)
+ if((item_data = itemdb->exists(nameid)) == NULL)
{
ShowError("wrong item ID : equipitem(%i)\n",nameid);
return false;
@@ -13127,7 +13161,7 @@ BUILDIN(autoequip)
nameid=script_getnum(st,2);
flag=script_getnum(st,3);
- if( ( item_data = itemdb_exists(nameid) ) == NULL )
+ if( ( item_data = itemdb->exists(nameid) ) == NULL )
{
ShowError("buildin_autoequip: Invalid item '%d'.\n", nameid);
return false;
@@ -14466,7 +14500,7 @@ BUILDIN(setitemscript)
new_bonus_script = script_getstr(st,3);
if( script_hasdata(st,4) )
n=script_getnum(st,4);
- i_data = itemdb_exists(item_id);
+ i_data = itemdb->exists(item_id);
if (!i_data || new_bonus_script==NULL || ( new_bonus_script[0] && new_bonus_script[0]!='{' )) {
script_pushint(st,0);
@@ -14632,10 +14666,10 @@ BUILDIN(searchitem)
int32 i;
TBL_PC* sd = NULL;
- if ((items[0] = itemdb_exists(atoi(itemname))))
+ if ((items[0] = itemdb->exists(atoi(itemname))))
count = 1;
else {
- count = itemdb_searchname_array(items, ARRAYLENGTH(items), itemname);
+ count = itemdb->search_name_array(items, ARRAYLENGTH(items), itemname);
if (count > MAX_SEARCH) count = MAX_SEARCH;
}
@@ -16074,27 +16108,33 @@ BUILDIN(has_instance) {
int i = 0, j = 0;
if( sd->instances ) {
for( i = 0; i < sd->instances; i++ ) {
- ARR_FIND(0, instances[sd->instance[i]].num_map, j, map[instances[sd->instance[i]].map[j]].instance_src_map == m);
- if( j != instances[sd->instance[i]].num_map )
- break;
+ if( sd->instance[i] >= 0 ) {
+ ARR_FIND(0, instances[sd->instance[i]].num_map, j, map[instances[sd->instance[i]].map[j]].instance_src_map == m);
+ if( j != instances[sd->instance[i]].num_map )
+ break;
+ }
}
if( i != sd->instances )
instance_id = sd->instance[i];
}
if( instance_id == -1 && sd->status.party_id && (p = party->search(sd->status.party_id)) && p->instances ) {
for( i = 0; i < p->instances; i++ ) {
- ARR_FIND(0, instances[p->instance[i]].num_map, j, map[instances[p->instance[i]].map[j]].instance_src_map == m);
- if( j != instances[p->instance[i]].num_map )
- break;
+ if( p->instance[i] >= 0 ) {
+ ARR_FIND(0, instances[p->instance[i]].num_map, j, map[instances[p->instance[i]].map[j]].instance_src_map == m);
+ if( j != instances[p->instance[i]].num_map )
+ break;
+ }
}
if( i != p->instances )
instance_id = p->instance[i];
}
if( instance_id == -1 && sd->guild && sd->guild->instances ) {
for( i = 0; i < sd->guild->instances; i++ ) {
- ARR_FIND(0, instances[sd->guild->instance[i]].num_map, j, map[instances[sd->guild->instance[i]].map[j]].instance_src_map == m);
- if( j != instances[sd->guild->instance[i]].num_map )
- break;
+ if( sd->guild->instance[i] >= 0 ) {
+ ARR_FIND(0, instances[sd->guild->instance[i]].num_map, j, map[instances[sd->guild->instance[i]].map[j]].instance_src_map == m);
+ if( j != instances[sd->guild->instance[i]].num_map )
+ break;
+ }
}
if( i != sd->guild->instances )
instance_id = sd->guild->instance[i];
@@ -16833,50 +16873,53 @@ BUILDIN(checkre)
return true;
}
-/* getrandgroupitem <group_id>,<quantity> */
+/* getrandgroupitem <container_item_id>,<quantity> */
BUILDIN(getrandgroupitem) {
- TBL_PC* sd;
- int i, get_count = 0, flag, nameid, group = script_getnum(st, 2), qty = script_getnum(st,3);
- struct item item_tmp;
-
- if( !( sd = script_rid2sd(st) ) )
- return true;
-
- if( qty <= 0 ) {
- ShowError("getrandgroupitem: qty is <= 0!\n");
- return false;
- }
-
- if(group < 1 || group >= MAX_ITEMGROUP) {
- ShowError("getrandgroupitem: Invalid group id %d\n", group);
- return false;
- }
- if (!itemgroup_db[group].qty) {
- ShowError("getrandgroupitem: group id %d is empty!\n", group);
- return false;
- }
-
- nameid = itemdb_searchrandomid(group);
- memset(&item_tmp,0,sizeof(item_tmp));
-
- item_tmp.nameid = nameid;
- item_tmp.identify = itemdb_isidentified(nameid);
-
- //Check if it's stackable.
- if (!itemdb_isstackable(nameid))
- get_count = 1;
- else
- get_count = qty;
+ struct item_data *data = NULL;
+ struct map_session_data *sd = NULL;
+ int nameid = script_getnum(st, 2);
+ int count = script_getnum(st, 3);
- for (i = 0; i < qty; i += get_count) {
- // if not pet egg
- if (!pet_create_egg(sd, nameid)) {
- if ((flag = pc->additem(sd, &item_tmp, get_count, LOG_TYPE_SCRIPT))) {
- clif->additem(sd, 0, 0, flag);
- if( pc->candrop(sd,&item_tmp) )
- iMap->addflooritem(&item_tmp,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ if( !(data = itemdb->exists(nameid)) ) {
+ ShowWarning("buildin_getrandgroupitem: unknown item id %d\n",nameid);
+ script_pushint(st, 1);
+ } else if ( count <= 0 ) {
+ ShowError("buildin_getrandgroupitem: qty is <= 0!\n");
+ script_pushint(st, 1);
+ } else if ( !data->group ) {
+ ShowWarning("buildin_getrandgroupitem: item '%s' (%d) isn't a group!\n",data->name,nameid);
+ script_pushint(st, 1);
+ } else if( !( sd = script->rid2sd(st) ) ) {
+ ShowWarning("buildin_getrandgroupitem: no player attached!! (item %s (%d))\n",data->name,nameid);
+ script_pushint(st, 1);
+ } else {
+ int i, get_count, flag;
+ struct item it;
+
+ memset(&it,0,sizeof(it));
+
+ nameid = itemdb->group_item(data->group);
+
+ it.nameid = nameid;
+ it.identify = itemdb_isidentified(nameid);
+
+ if (!itemdb_isstackable(nameid))
+ get_count = 1;
+ else
+ get_count = count;
+
+ for (i = 0; i < count; i += get_count) {
+ // if not pet egg
+ if (!pet_create_egg(sd, nameid)) {
+ if ((flag = pc->additem(sd, &it, get_count, LOG_TYPE_SCRIPT))) {
+ clif->additem(sd, 0, 0, flag);
+ if( pc->candrop(sd,&it) )
+ iMap->addflooritem(&it,get_count,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
+ }
}
}
+
+ script_pushint(st, 0);
}
return true;
@@ -17208,11 +17251,12 @@ BUILDIN(queueiterator) {
}
}
- if( i == script->hqis )
+ if( i == script->hqis ) {
RECREATE(script->hqi, struct hQueueIterator, ++script->hqis);
- else
+ script->hqi[ idx ].item = NULL;
+ } else
idx = i;
-
+
RECREATE(script->hqi[ idx ].item, int, queue->items);
memcpy(&script->hqi[idx].item, &queue->item, sizeof(int)*queue->items);
@@ -17270,6 +17314,41 @@ BUILDIN(qiclear) {
return true;
}
+/**
+ * packageitem({<optional container_item_id>})
+ * when no item id is provided it tries to assume it comes from the current item id being processed (if any)
+ **/
+BUILDIN(packageitem) {
+ struct item_data *data = NULL;
+ struct map_session_data *sd = NULL;
+ int nameid;
+
+ if( script_hasdata(st, 2) )
+ nameid = script_getnum(st, 2);
+ else if ( script->current_item_id )
+ nameid = script->current_item_id;
+ else {
+ ShowWarning("buildin_packageitem: no item id provided and no item attached\n");
+ script_pushint(st, 1);
+ return true;
+ }
+
+ if( !(data = itemdb->exists(nameid)) ) {
+ ShowWarning("buildin_packageitem: unknown item id %d\n",nameid);
+ script_pushint(st, 1);
+ } else if ( !data->package ) {
+ ShowWarning("buildin_packageitem: item '%s' (%d) isn't a package!\n",data->name,nameid);
+ script_pushint(st, 1);
+ } else if( !( sd = script->rid2sd(st) ) ) {
+ ShowWarning("buildin_packageitem: no player attached!! (item %s (%d))\n",data->name,nameid);
+ script_pushint(st, 1);
+ } else {
+ itemdb->package_item(sd,data->package);
+ script_pushint(st, 0);
+ }
+
+ return true;
+}
// declarations that were supposed to be exported from npc_chat.c
#ifdef PCRE_SUPPORT
@@ -17784,6 +17863,9 @@ void script_parse_builtin(void) {
BUILDIN_DEF(qicheck,"i"),
BUILDIN_DEF(qiget,"i"),
BUILDIN_DEF(qiclear,"i"),
+
+ BUILDIN_DEF(packageitem,"?"),
+
};
int i,n, len = ARRAYLENGTH(BUILDIN), start = script->buildin_count;
char* p;
@@ -17861,6 +17943,8 @@ void script_defaults(void) {
script->word_buf = NULL;
script->word_size = 0;
+ script->current_item_id = 0;
+
script->init = do_init_script;
script->final = do_final_script;
@@ -17876,6 +17960,9 @@ void script_defaults(void) {
script->push_str = push_str;
script->push_copy = push_copy;
script->pop_stack = pop_stack;
+ script->set_constant = script_set_constant;
+ script->set_constant2 = script_set_constant2;
+ script->get_constant = script_get_constant;
script->queue = script_hqueue_get;
script->queue_add = script_hqueue_add;
diff --git a/src/map/script.h b/src/map/script.h
index 3cfcd9de4..a047779a8 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -202,9 +202,6 @@ struct DBMap* script_get_label_db(void);
struct DBMap* script_get_userfunc_db(void);
void script_run_autobonus(const char *autobonus,int id, int pos);
-bool script_get_constant(const char* name, int* value);
-void script_set_constant(const char* name, int value, bool isparameter);
-
void script_cleararray_pc(struct map_session_data* sd, const char* varname, void* value);
void script_setarray_pc(struct map_session_data* sd, const char* varname, uint8 idx, void* value, int* refcache);
@@ -357,10 +354,12 @@ struct script_interface {
char *str_buf;
int str_size; // size of the buffer
int str_pos; // next position to be assigned
- //
+ /* */
char *word_buf;
int word_size;
/* */
+ unsigned short current_item_id;
+ /* */
void (*init) (void);
void (*final) (void);
/* */
@@ -376,6 +375,9 @@ struct script_interface {
struct script_data* (*push_str) (struct script_stack* stack, enum c_op type, char* str);
struct script_data* (*push_copy) (struct script_stack* stack, int pos);
void (*pop_stack) (struct script_state* st, int start, int end);
+ void (*set_constant) (const char* name, int value, bool isparameter);
+ void (*set_constant2) (const char *name, int value, bool isparameter);
+ bool (*get_constant) (const char* name, int* value);
/* */
struct hQueue *(*queue) (int idx);
bool (*queue_add) (int idx, int var);
diff --git a/src/map/searchstore.c b/src/map/searchstore.c
index 3cda77e4a..d346a0de6 100644
--- a/src/map/searchstore.c
+++ b/src/map/searchstore.c
@@ -135,14 +135,14 @@ void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned
// validate lists
for( i = 0; i < item_count; i++ ) {
- if( !itemdb_exists(itemlist[i]) ) {
+ if( !itemdb->exists(itemlist[i]) ) {
ShowWarning("searchstore_query: Client resolved item %hu is not known.\n", itemlist[i]);
clif->search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
return;
}
}
for( i = 0; i < card_count; i++ ) {
- if( !itemdb_exists(cardlist[i]) ) {
+ if( !itemdb->exists(cardlist[i]) ) {
ShowWarning("searchstore_query: Client resolved card %hu is not known.\n", cardlist[i]);
clif->search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
return;
diff --git a/src/map/skill.c b/src/map/skill.c
index 685fec353..1431d27a7 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -3781,6 +3781,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
break;
case SR_TIGERCANNON:
+ case GC_COUNTERSLASH:
+ case GC_ROLLINGCUTTER:
flag |= SD_ANIMATION;
case LG_MOONSLASHER:
clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
@@ -5314,6 +5316,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
status_kill(bl);
break;
case SA_REVERSEORCISH:
+ case ALL_REVERSEORCISH:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
sc_start(bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv)));
break;
@@ -5460,7 +5463,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
src,skill_id,skill_lv,tick, flag|BCT_ENEMY|1, skill->castend_damage_id);
clif->skill_nodamage (src,src,skill_id,skill_lv,1);
// Initiate 10% of your damage becomes fire element.
- sc_start4(src,SC_WATK_ELEMENT,100,3,20,0,0,skill->get_time2(skill_id, skill_lv));
+ sc_start4(src,SC_SUB_WEAPONPROPERTY,100,3,20,0,0,skill->get_time2(skill_id, skill_lv));
if( sd )
skill->blockpc_start(sd, skill_id, skill->get_time(skill_id, skill_lv), false);
else if( bl->type == BL_MER )
@@ -5564,6 +5567,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case RK_VITALITYACTIVATION:
case RK_ABUNDANCE:
case RK_CRUSHSTRIKE:
+ case ALL_ODINS_POWER:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
break;
@@ -5634,6 +5638,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
skill->blockpc_start (sd, skill_id, skill->get_time2(skill_id,skill_lv), false);
break;
+ case ALL_ANGEL_PROTECT:
+ if( dstsd )
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,
+ sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ else if( sd )
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ break;
case AS_ENCHANTPOISON: // Prevent spamming [Valaris]
if (sd && dstsd && dstsd->sc.count) {
if (dstsd->sc.data[SC_PROPERTYFIRE] ||
@@ -6474,7 +6485,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
return 1;
}
if( sd ) {
- int x,bonus=100;
+ int x,bonus=100, potion = min(500+skill_lv,505);
x = skill_lv%11 - 1;
i = pc->search_inventory(sd,skill_db[skill_id].itemid[x]);
if( i < 0 || skill_db[skill_id].itemid[x] <= 0 ) {
@@ -6523,11 +6534,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
}
- if (sd->itemgrouphealrate[IG_POTION]>0) {
- hp += hp * sd->itemgrouphealrate[IG_POTION] / 100;
- sp += sp * sd->itemgrouphealrate[IG_POTION] / 100;
+ for(i = 0; i < ARRAYLENGTH(sd->itemhealrate) && sd->itemhealrate[i].nameid; i++) {
+ if (sd->itemhealrate[i].nameid == potion) {
+ hp += hp * sd->itemhealrate[i].rate / 100;
+ sp += sp * sd->itemhealrate[i].rate / 100;
+ break;
+ }
}
-
+
if( (i = pc->skillheal_bonus(sd, skill_id)) ) {
hp += hp * i / 100;
sp += sp * i / 100;
@@ -7700,6 +7714,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case NPC_TALK:
case ALL_WEWISH:
+ case ALL_CATCRY:
+ case ALL_DREAM_SUMMERNIGHT:
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
break;
case ALL_BUYING_STORE:
@@ -9936,7 +9952,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
int i = skill_lv%11 - 1;
struct item_data *item;
i = skill_db[skill_id].itemid[i];
- item = itemdb_search(i);
+ item = itemdb->search(i);
potion_flag = 1;
potion_hp = 0;
potion_sp = 0;
@@ -10022,6 +10038,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
if (!sg) break;
if (sce)
status_change_end(src, type, INVALID_TIMER); //Was under someone else's Gospel. [Skotlex]
+ status_change_clear_buffs(src,3);
sc_start4(src,type,100,skill_lv,0,sg->group_id,BCT_SELF,skill->get_time(skill_id,skill_lv));
clif->skill_poseffect(src, skill_id, skill_lv, 0, 0, tick); // PA_GOSPEL music packet
}
@@ -11371,14 +11388,17 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if( bl->id == ss->id )// it won't trigger on caster
break;
case UNT_LANDMINE:
- case UNT_CLAYMORETRAP:
case UNT_BLASTMINE:
case UNT_SHOCKWAVE:
case UNT_SANDMAN:
case UNT_FLASHER:
case UNT_FREEZINGTRAP:
case UNT_FIREPILLAR_ACTIVE:
- iMap->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick);
+ case UNT_CLAYMORETRAP:
+ if( sg->unit_id == UNT_FIRINGTRAP || sg->unit_id == UNT_ICEBOUNDTRAP || sg->unit_id == UNT_CLAYMORETRAP )
+ iMap->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag|BL_SKILL|~BCT_SELF, &src->bl,tick);
+ else
+ iMap->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick);
if (sg->unit_id != UNT_FIREPILLAR_ACTIVE)
clif->changetraplook(&src->bl, sg->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS);
sg->limit=DIFF_TICK(tick,sg->tick)+1500 +
@@ -14637,16 +14657,23 @@ int skill_detonator(struct block_list *bl, va_list ap)
case UNT_CLUSTERBOMB:
case UNT_FIRINGTRAP:
case UNT_ICEBOUNDTRAP:
- if( unit_id == UNT_TALKIEBOX ) {
- clif->talkiebox(bl,unit->group->valstr);
- unit->group->val2 = -1;
- } else
- iMap->foreachinrange(skill->trap_splash,bl,skill->get_splash(unit->group->skill_id,unit->group->skill_lv),unit->group->bl_flag,bl,unit->group->tick);
-
- clif->changetraplook(bl,unit_id == UNT_FIRINGTRAP ? UNT_DUMMYSKILL : UNT_USED_TRAPS);
- unit->group->unit_id = UNT_USED_TRAPS;
+ switch(unit_id){
+ case UNT_TALKIEBOX:
+ clif->talkiebox(bl,unit->group->valstr);
+ unit->group->val2 = -1;
+ break;
+ case UNT_CLAYMORETRAP:
+ case UNT_FIRINGTRAP:
+ case UNT_ICEBOUNDTRAP:
+ iMap->foreachinrange(skill->trap_splash,bl,skill->get_splash(unit->group->skill_id,unit->group->skill_lv),unit->group->bl_flag|BL_SKILL|~BCT_SELF,bl,unit->group->tick);
+ break;
+ default:
+ iMap->foreachinrange(skill->trap_splash,bl,skill->get_splash(unit->group->skill_id,unit->group->skill_lv),unit->group->bl_flag,bl,unit->group->tick);
+ }
+ clif->changetraplook(bl, UNT_USED_TRAPS);
unit->group->limit = DIFF_TICK(iTimer->gettick(),unit->group->tick) +
- (unit_id == UNT_TALKIEBOX ? 5000 : (unit_id == UNT_CLUSTERBOMB || unit_id == UNT_ICEBOUNDTRAP? 2500 : 1500) );
+ (unit_id == UNT_TALKIEBOX ? 5000 : (unit_id == UNT_CLUSTERBOMB || unit_id == UNT_ICEBOUNDTRAP? 2500 : (unit_id == UNT_FIRINGTRAP ? 0 : 1500)) );
+ unit->group->unit_id = UNT_USED_TRAPS;
break;
}
return 0;
@@ -14828,12 +14855,6 @@ int skill_trap_splash (struct block_list *bl, va_list ap) {
case UNT_ELECTRICSHOCKER:
clif->skill_damage(src,bl,tick,0,0,-30000,1,sg->skill_id,sg->skill_lv,5);
break;
- case UNT_FIRINGTRAP:
- case UNT_ICEBOUNDTRAP:
- case UNT_CLUSTERBOMB:
- if( ss != bl )
- skill->attack(BF_MISC,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1|SD_LEVEL);
- break;
case UNT_MAGENTATRAP:
case UNT_COBALTTRAP:
case UNT_MAIZETRAP:
@@ -14845,6 +14866,38 @@ int skill_trap_splash (struct block_list *bl, va_list ap) {
skill->addtimerskill(ss,tick+50,bl->id,0,0,WM_REVERBERATION_MELEE,sg->skill_lv,BF_WEAPON,0); // for proper skill delay animation when use with Dominion Impulse
skill->addtimerskill(ss,tick+250,bl->id,0,0,WM_REVERBERATION_MAGIC,sg->skill_lv,BF_MAGIC,0);
break;
+ case UNT_FIRINGTRAP:
+ case UNT_ICEBOUNDTRAP:
+ if( src->id == bl->id ) break;
+ if( bl->type == BL_SKILL ){
+ struct skill_unit *su = (struct skill_unit *)bl;
+ if( su->group->unit_id == UNT_USED_TRAPS )
+ break;
+ }
+ case UNT_CLUSTERBOMB:
+ if( ss != bl )
+ skill->attack(BF_MISC,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1|SD_LEVEL);
+ break;
+ case UNT_CLAYMORETRAP:
+ if( src->id == bl->id ) break;
+ if( bl->type == BL_SKILL ){
+ struct skill_unit *su = (struct skill_unit *)bl;
+ switch( su->group->unit_id ){
+ case UNT_CLAYMORETRAP:
+ case UNT_LANDMINE:
+ case UNT_BLASTMINE:
+ case UNT_SHOCKWAVE:
+ case UNT_SANDMAN:
+ case UNT_FLASHER:
+ case UNT_FREEZINGTRAP:
+ case UNT_FIRINGTRAP:
+ case UNT_ICEBOUNDTRAP:
+ clif->changetraplook(bl, UNT_USED_TRAPS);
+ su->group->limit = DIFF_TICK(iTimer->gettick(),su->group->tick) + 1500;
+ su->group->unit_id = UNT_USED_TRAPS;
+ }
+ break;
+ }
default:
skill->attack(skill->get_type(sg->skill_id),ss,src,bl,sg->skill_id,sg->skill_lv,tick,0);
break;
@@ -15925,7 +15978,7 @@ int skill_produce_mix (struct map_session_data *sd, uint16 skill_id, int nameid,
if( skill_id == RK_RUNEMASTERY ) {
int temp_qty, skill_lv = pc->checkskill(sd,skill_id);
- data = itemdb_search(nameid);
+ data = itemdb->search(nameid);
if( skill_lv == 10 ) temp_qty = 1 + rnd()%3;
else if( skill_lv > 5 ) temp_qty = 1 + rnd()%2;
@@ -16786,16 +16839,18 @@ int skill_destroy_trap( struct block_list *bl, va_list ap ) {
if (su->alive && (sg = su->group) && skill->get_inf2(sg->skill_id)&INF2_TRAP) {
switch( sg->unit_id ) {
- case UNT_LANDMINE:
case UNT_CLAYMORETRAP:
+ case UNT_FIRINGTRAP:
+ case UNT_ICEBOUNDTRAP:
+ iMap->foreachinrange(skill->trap_splash,&su->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag|BL_SKILL|~BCT_SELF, &su->bl,tick);
+ break;
+ case UNT_LANDMINE:
case UNT_BLASTMINE:
case UNT_SHOCKWAVE:
case UNT_SANDMAN:
case UNT_FLASHER:
case UNT_FREEZINGTRAP:
case UNT_CLUSTERBOMB:
- case UNT_FIRINGTRAP:
- case UNT_ICEBOUNDTRAP:
iMap->foreachinrange(skill->trap_splash,&su->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &su->bl,tick);
break;
}
@@ -17842,7 +17897,7 @@ void skill_reload (void) {
}
}
}
- chrif_skillid2idx(0);
+ chrif->skillid2idx(0);
/* lets update all players skill tree : so that if any skill modes were changed they're properly updated */
iter = mapit_getallusers();
for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) )
@@ -17855,7 +17910,7 @@ void skill_reload (void) {
*
*------------------------------------------*/
int do_init_skill (void) {
- skilldb_name2id = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, 0);
+ skilldb_name2id = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, MAX_SKILL_NAME_LENGTH);
skill->read_db();
group_db = idb_alloc(DB_OPT_BASE);
diff --git a/src/map/skill.h b/src/map/skill.h
index cc9ac4bfc..921a682a2 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -37,6 +37,7 @@ struct square;
#define MAX_SKILLUNITGROUP 25
#define MAX_SKILL_ITEM_REQUIRE 10
#define MAX_SKILLUNITGROUPTICKSET 25
+#define MAX_SKILL_NAME_LENGTH 30
// (Epoque:) To-do: replace this macro with some sort of skill tree check (rather than hard-coded skill names)
#define skill_ischangesex(id) ( \
@@ -1599,7 +1600,7 @@ struct skill_condition {
// Database skills
struct s_skill_db {
unsigned short nameid;
- char name[NAME_LENGTH];
+ char name[MAX_SKILL_NAME_LENGTH];
char desc[40];
int range[MAX_SKILL_LEVEL],hit,inf,element[MAX_SKILL_LEVEL],nk,splash[MAX_SKILL_LEVEL],max;
int num[MAX_SKILL_LEVEL];
diff --git a/src/map/status.c b/src/map/status.c
index 55b79fff7..dc5d5c5bd 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -196,7 +196,7 @@ void initChangeTables(void) {
//The main status definitions
add_sc( SM_BASH , SC_STUN );
set_sc( SM_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
- add_sc( SM_MAGNUM , SC_WATK_ELEMENT );
+ add_sc( SM_MAGNUM , SC_SUB_WEAPONPROPERTY );
set_sc( SM_ENDURE , SC_ENDURE , SI_ENDURE , SCB_MDEF|SCB_DSPD );
add_sc( MG_SIGHT , SC_SIGHT );
add_sc( MG_SAFETYWALL , SC_SAFETYWALL );
@@ -348,9 +348,9 @@ void initChangeTables(void) {
set_sc( LK_AURABLADE , SC_AURABLADE , SI_AURABLADE , SCB_NONE );
set_sc( LK_PARRYING , SC_PARRYING , SI_PARRYING , SCB_NONE );
#ifndef RENEWAL
- set_sc( LK_CONCENTRATION , SC_LKCONCENTRATION , SI_CONCENTRATION , SCB_BATK|SCB_WATK|SCB_HIT|SCB_DEF|SCB_DEF2);
+ set_sc( LK_CONCENTRATION , SC_LKCONCENTRATION , SI_LKCONCENTRATION , SCB_BATK|SCB_WATK|SCB_HIT|SCB_DEF|SCB_DEF2);
#else
- set_sc( LK_CONCENTRATION , SC_LKCONCENTRATION , SI_CONCENTRATION , SCB_HIT|SCB_DEF);
+ set_sc( LK_CONCENTRATION , SC_LKCONCENTRATION , SI_LKCONCENTRATION , SCB_HIT|SCB_DEF);
#endif
set_sc( LK_TENSIONRELAX , SC_TENSIONRELAX , SI_TENSIONRELAX , SCB_REGEN );
set_sc( LK_BERSERK , SC_BERSERK , SI_BERSERK , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN );
@@ -511,7 +511,7 @@ void initChangeTables(void) {
add_sc( MER_CRASH , SC_STUN );
set_sc( MER_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
- add_sc( MS_MAGNUM , SC_WATK_ELEMENT );
+ add_sc( MS_MAGNUM , SC_SUB_WEAPONPROPERTY );
add_sc( MER_SIGHT , SC_SIGHT );
set_sc( MER_DECAGI , SC_DEC_AGI , SI_DEC_AGI , SCB_AGI|SCB_SPEED );
set_sc( MER_MAGNIFICAT , SC_MAGNIFICAT , SI_MAGNIFICAT , SCB_REGEN );
@@ -757,6 +757,9 @@ void initChangeTables(void) {
set_sc( ALL_FULL_THROTTLE , SC_FULL_THROTTLE , SI_FULL_THROTTLE , SCB_SPEED|SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+ add_sc( ALL_REVERSEORCISH , SC_ORCISH );
+ set_sc( ALL_ANGEL_PROTECT , SC_ANGEL_PROTECT , SI_ANGEL_PROTECT , SCB_REGEN );
+
// Storing the target job rather than simply SC_SOULLINK simplifies code later on.
SkillStatusChangeTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
SkillStatusChangeTable[SL_MONK] = (sc_type)MAPID_MONK,
@@ -2371,7 +2374,6 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
+ sizeof(sd->expaddrace)
+ sizeof(sd->ignore_mdef)
+ sizeof(sd->ignore_def)
- + sizeof(sd->itemgrouphealrate)
+ sizeof(sd->sp_gain_race)
+ sizeof(sd->sp_gain_race_attack)
+ sizeof(sd->hp_gain_race_attack)
@@ -2600,16 +2602,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
current_equip_card_id= c= sd->status.inventory[index].card[j];
if(!c)
continue;
- data = itemdb_exists(c);
+ data = itemdb->exists(c);
if(!data)
continue;
- if(first && data->equip_script) {//Execute equip-script on login
- run_script(data->equip_script,0,sd->bl.id,0);
- if (!calculating)
- return 1;
- }
- if(!data->script)
- continue;
for(k = 0; k < map[sd->bl.m].zone->disabled_items_count; k++) {
if( map[sd->bl.m].zone->disabled_items[k] == data->nameid ) {
@@ -2620,6 +2615,15 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
if( k < map[sd->bl.m].zone->disabled_items_count )
continue;
+ if(first && data->equip_script) {//Execute equip-script on login
+ run_script(data->equip_script,0,sd->bl.id,0);
+ if (!calculating)
+ return 1;
+ }
+
+ if(!data->script)
+ continue;
+
if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) { //Left hand status.
sd->state.lr_flag = 1;
run_script(data->script,0,sd->bl.id,0);
@@ -2632,15 +2636,13 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
}
}
- if( sc->count && sc->data[SC_ITEMSCRIPT] )
- {
- struct item_data *data = itemdb_exists(sc->data[SC_ITEMSCRIPT]->val1);
+ if( sc->count && sc->data[SC_ITEMSCRIPT] ) {
+ struct item_data *data = itemdb->exists(sc->data[SC_ITEMSCRIPT]->val1);
if( data && data->script )
run_script(data->script,0,sd->bl.id,0);
}
- if( sd->pd )
- { // Pet Bonus
+ if( sd->pd ) { // Pet Bonus
struct pet_data *pd = sd->pd;
if( pd && pd->petDB && pd->petDB->equip_script && pd->pet.intimate >= battle_config.pet_equip_min_friendly )
run_script(pd->petDB->equip_script,0,sd->bl.id,0);
@@ -3296,7 +3298,6 @@ static unsigned short status_calc_vit(struct block_list *,struct status_change *
static unsigned short status_calc_int(struct block_list *,struct status_change *,int);
static unsigned short status_calc_dex(struct block_list *,struct status_change *,int);
static unsigned short status_calc_luk(struct block_list *,struct status_change *,int);
-static unsigned short status_calc_batk(struct block_list *,struct status_change *,int,bool);
static unsigned short status_calc_watk(struct block_list *,struct status_change *,int,bool);
static unsigned short status_calc_matk(struct block_list *,struct status_change *,int,bool);
static signed short status_calc_hit(struct block_list *,struct status_change *,int,bool);
@@ -3317,6 +3318,8 @@ static unsigned char status_calc_element_lv(struct block_list *bl, struct status
static unsigned short status_calc_mode(struct block_list *bl, struct status_change *sc, int mode);
#ifdef RENEWAL
static unsigned short status_calc_ematk(struct block_list *,struct status_change *,int);
+#else
+static unsigned short status_calc_batk(struct block_list *,struct status_change *,int,bool);
#endif
//Calculates base regen values.
@@ -3871,8 +3874,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
if(flag&SCB_DSPD) {
int dmotion;
- if( bl->type&BL_PC )
- {
+ if( bl->type&BL_PC ) {
if (b_status->agi == status->agi)
status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
else {
@@ -3883,16 +3885,11 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
//It's safe to ignore b_status->dmotion since no bonus affects it.
status->dmotion = status_calc_dmotion(bl, sc, status->dmotion);
}
- }
- else
- if( bl->type&BL_HOM )
- {
+ } else if( bl->type&BL_HOM ) {
dmotion = 800-status->agi*4;
status->dmotion = cap_value(dmotion, 400, 800);
status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
- }
- else // mercenary and mobs
- {
+ } else { // mercenary and mobs
status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
}
}
@@ -3918,13 +3915,13 @@ void status_calc_bl_(struct block_list* bl, enum scb_flag flag, bool first)
if( flag&SCB_BASE ) {// calculate the object's base status too
switch( bl->type ) {
- case BL_PC: status_calc_pc_(BL_CAST(BL_PC,bl), first); break;
- case BL_MOB: status_calc_mob_(BL_CAST(BL_MOB,bl), first); break;
- case BL_PET: status_calc_pet_(BL_CAST(BL_PET,bl), first); break;
- case BL_HOM: status_calc_homunculus_(BL_CAST(BL_HOM,bl), first); break;
- case BL_MER: status_calc_mercenary_(BL_CAST(BL_MER,bl), first); break;
- case BL_ELEM: status_calc_elemental_(BL_CAST(BL_ELEM,bl), first); break;
- case BL_NPC: status_calc_npc_(BL_CAST(BL_NPC,bl), first); break;
+ case BL_PC: status_calc_pc_(BL_CAST(BL_PC,bl), first); break;
+ case BL_MOB: status_calc_mob_(BL_CAST(BL_MOB,bl), first); break;
+ case BL_PET: status_calc_pet_(BL_CAST(BL_PET,bl), first); break;
+ case BL_HOM: status_calc_homunculus_(BL_CAST(BL_HOM,bl), first); break;
+ case BL_MER: status_calc_mercenary_(BL_CAST(BL_MER,bl), first); break;
+ case BL_ELEM: status_calc_elemental_(BL_CAST(BL_ELEM,bl), first); break;
+ case BL_NPC: status_calc_npc_(BL_CAST(BL_NPC,bl), first); break;
}
}
@@ -4404,19 +4401,25 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang
return (unsigned short)cap_value(luk,0,USHRT_MAX);
}
-
+#ifdef RENEWAL
+unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk, bool viewable)
+#else
static unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk, bool viewable)
+#endif
{
if(!sc || !sc->count)
return cap_value(batk,0,USHRT_MAX);
if( !viewable ){
/* some statuses that are hidden in the status window */
+ if(sc->data[SC_PLUSATTACKPOWER])
+ batk += sc->data[SC_PLUSATTACKPOWER]->val1;
return (unsigned short)cap_value(batk,0,USHRT_MAX);
}
-
+#ifndef RENEWAL
if(sc->data[SC_PLUSATTACKPOWER])
batk += sc->data[SC_PLUSATTACKPOWER]->val1;
+#endif
if(sc->data[SC_BATKFOOD])
batk += sc->data[SC_BATKFOOD]->val1;
if(sc->data[SC_GS_GATLINGFEVER])
@@ -6300,43 +6303,43 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
else
tick -= (status->vit + status->luk) / 20 * 1000;
break;
- case SC_BURNING:
- tick -= 75 * status->luk + 125 * status->agi;
- tick = max(tick,5000); // Minimum Duration 5s.
- break;
- case SC_FROSTMISTY:
- tick -= 1000 * ((status->vit + status->dex) / 20);
- tick = max(tick,6000); // Minimum Duration 10s.
- break;
- case SC_OBLIVIONCURSE: // 100% - (100 - 0.8 x INT)
- sc_def = 100 - ( 100 - status->int_* 8 / 10 );
- sc_def = max(sc_def, 5); // minimum of 5%
- break;
- case SC_WUGBITE: // {(Base Success chance) - (Target's AGI / 4)}
- rate -= status->agi*100/4;
- rate = max(rate,5000); // minimum of 50%
- break;
- case SC_ELECTRICSHOCKER:
- if( bl->type == BL_MOB )
- tick -= 1000 * (status->agi/10);
- break;
- case SC_CRYSTALIZE:
- tick -= (1000*(status->vit/10))+(status_get_lv(bl)/50);
- break;
- case SC_MANDRAGORA:
- sc_def = (status->vit+status->luk)/5;
- break;
- case SC_KYOUGAKU:
- tick -= 1000 * status_get_int(bl) / 20;
- break;
- case SC_NEEDLE_OF_PARALYZE:
- tick -= 50 * (status->vit + status->luk); //(1000/20);
- break;
- default:
- //Effect that cannot be reduced? Likely a buff.
- if (!(rnd()%10000 < rate))
- return 0;
- return tick?tick:1;
+ case SC_BURNING:
+ tick -= 75 * status->luk + 125 * status->agi;
+ tick = max(tick,5000); // Minimum Duration 5s.
+ break;
+ case SC_FROSTMISTY:
+ tick -= 1000 * ((status->vit + status->dex) / 20);
+ tick = max(tick,6000); // Minimum Duration 10s.
+ break;
+ case SC_OBLIVIONCURSE: // 100% - (100 - 0.8 x INT)
+ sc_def = 100 - ( 100 - status->int_* 8 / 10 );
+ sc_def = max(sc_def, 5); // minimum of 5%
+ break;
+ case SC_WUGBITE: // {(Base Success chance) - (Target's AGI / 4)}
+ rate -= status->agi*100/4;
+ rate = max(rate,5000); // minimum of 50%
+ break;
+ case SC_ELECTRICSHOCKER:
+ if( bl->type == BL_MOB )
+ tick -= 1000 * (status->agi/10);
+ break;
+ case SC_CRYSTALIZE:
+ tick -= (1000*(status->vit/10))+(status_get_lv(bl)/50);
+ break;
+ case SC_MANDRAGORA:
+ sc_def = (status->vit+status->luk)/5;
+ break;
+ case SC_KYOUGAKU:
+ tick -= 1000 * status_get_int(bl) / 20;
+ break;
+ case SC_NEEDLE_OF_PARALYZE:
+ tick -= 50 * (status->vit + status->luk); //(1000/20);
+ break;
+ default:
+ //Effect that cannot be reduced? Likely a buff.
+ if (!(rnd()%10000 < rate))
+ return 0;
+ return tick?tick:1;
}
if (sd) {
@@ -6528,27 +6531,26 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX) // Confirmed.
return 0; // Immune to status ailements
switch( type ) {
- case SC_QUAGMIRE://Tester said it protects against this and decrease agi.
- case SC_DEC_AGI:
- case SC_BURNING:
- case SC_FROSTMISTY:
- //case SC_WHITEIMPRISON://Need confirm. Protected against this in the past. [Rytech]
- case SC_MARSHOFABYSS:
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_DEATHHURT:
- case SC_PYREXIA:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
- case SC_CRYSTALIZE: ////08/31/2011 - Class Balance Changes
- case SC_DEEP_SLEEP:
- case SC_MANDRAGORA:
+ case SC_QUAGMIRE://Tester said it protects against this and decrease agi.
+ case SC_DEC_AGI:
+ case SC_BURNING:
+ case SC_FROSTMISTY:
+ //case SC_WHITEIMPRISON://Need confirm. Protected against this in the past. [Rytech]
+ case SC_MARSHOFABYSS:
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
+ case SC_CRYSTALIZE: ////08/31/2011 - Class Balance Changes
+ case SC_DEEP_SLEEP:
+ case SC_MANDRAGORA:
return 0;
}
- }
- else if( sc->data[SC_INSPIRATION] ) {
+ } else if( sc->data[SC_INSPIRATION] ) {
if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX )
return 0; // Immune to status ailements
switch( type ) {
@@ -6584,292 +6586,301 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
undead_flag = battle->check_undead(status->race,status->def_ele);
//Check for inmunities / sc fails
switch (type) {
+ case SC_DRUMBATTLE:
+ case SC_NIBELUNGEN:
+ case SC_INTOABYSS:
+ case SC_SIEGFRIED:
+ if( bl->type == BL_PC) {
+ struct map_session_data *sd = BL_CAST(BL_PC,bl);
+ if (!sd->status.party_id) return 0;
+ }
+ break;
case SC_ANGRIFFS_MODUS:
case SC_GOLDENE_FERSE:
if ((type==SC_GOLDENE_FERSE && sc->data[SC_ANGRIFFS_MODUS])
|| (type==SC_ANGRIFFS_MODUS && sc->data[SC_GOLDENE_FERSE])
)
return 0;
- case SC_STONE:
- if(sc->data[SC_POWER_OF_GAIA])
- return 0;
- case SC_FREEZE:
- //Undead are immune to Freeze/Stone
- if (undead_flag && !(flag&1))
- return 0;
- case SC_DEEP_SLEEP:
- case SC_SLEEP:
- case SC_STUN:
- case SC_FROSTMISTY:
- case SC_CRYSTALIZE:
- if (sc->opt1)
- return 0; //Cannot override other opt1 status changes. [Skotlex]
- if((type == SC_FREEZE || type == SC_FROSTMISTY || type == SC_CRYSTALIZE) && sc->data[SC_WARMER])
- return 0; //Immune to Frozen and Freezing status if under Warmer status. [Jobbie]
- break;
-
- //There all like berserk, do not everlap each other
- case SC__BLOODYLUST:
- if(!sd) return 0; //should only affect player
- case SC_BERSERK:
- if (((type == SC_BERSERK) && (sc->data[SC_SATURDAY_NIGHT_FEVER] || sc->data[SC__BLOODYLUST]))
- || ((type == SC__BLOODYLUST) && (sc->data[SC_SATURDAY_NIGHT_FEVER] || sc->data[SC_BERSERK]))
- )
- return 0;
+ case SC_STONE:
+ if(sc->data[SC_POWER_OF_GAIA])
+ return 0;
+ case SC_FREEZE:
+ //Undead are immune to Freeze/Stone
+ if (undead_flag && !(flag&1))
+ return 0;
+ case SC_DEEP_SLEEP:
+ case SC_SLEEP:
+ case SC_STUN:
+ case SC_FROSTMISTY:
+ case SC_CRYSTALIZE:
+ if (sc->opt1)
+ return 0; //Cannot override other opt1 status changes. [Skotlex]
+ if((type == SC_FREEZE || type == SC_FROSTMISTY || type == SC_CRYSTALIZE) && sc->data[SC_WARMER])
+ return 0; //Immune to Frozen and Freezing status if under Warmer status. [Jobbie]
break;
- case SC_BURNING:
- if(sc->opt1 || sc->data[SC_FROSTMISTY])
- return 0;
- break;
+ //There all like berserk, do not everlap each other
+ case SC__BLOODYLUST:
+ if(!sd) return 0; //should only affect player
+ case SC_BERSERK:
+ if (((type == SC_BERSERK) && (sc->data[SC_SATURDAY_NIGHT_FEVER] || sc->data[SC__BLOODYLUST]))
+ || ((type == SC__BLOODYLUST) && (sc->data[SC_SATURDAY_NIGHT_FEVER] || sc->data[SC_BERSERK]))
+ )
+ return 0;
+ break;
- case SC_CRUCIS:
- //Only affects demons and undead element (but not players)
- if((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
- return 0;
- break;
- case SC_LEXAETERNA:
- if( (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) || sc->data[SC_FREEZE] )
- return 0;
- break;
- case SC_KYRIE:
- if (bl->type == BL_MOB)
- return 0;
- break;
- case SC_OVERTHRUST:
- if (sc->data[SC_OVERTHRUSTMAX])
- return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex]
- case SC_OVERTHRUSTMAX:
- if( sc->option&OPTION_MADOGEAR )
- return 0;//Overthrust and Overthrust Max cannot be used on Mado Gear [Ind]
- break;
- case SC_ADRENALINE:
- if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE)))
- return 0;
- if (sc->data[SC_QUAGMIRE] ||
- sc->data[SC_DEC_AGI] ||
- sc->option&OPTION_MADOGEAR //Adrenaline doesn't affect Mado Gear [Ind]
- )
- return 0;
- break;
- case SC_ADRENALINE2:
- if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE2)))
- return 0;
- if (sc->data[SC_QUAGMIRE] ||
- sc->data[SC_DEC_AGI]
- )
- return 0;
- break;
- case SC_MAGNIFICAT:
- if( sc->data[SC_OFFERTORIUM] || sc->option&OPTION_MADOGEAR ) //Mado is immune to magnificat
- return 0;
+ case SC_BURNING:
+ if(sc->opt1 || sc->data[SC_FROSTMISTY])
+ return 0;
break;
- case SC_ONEHANDQUICKEN:
- case SC_MER_QUICKEN:
- case SC_TWOHANDQUICKEN:
- if(sc->data[SC_DEC_AGI])
- return 0;
- case SC_INC_AGI:
- if(sd && pc_issit(sd)){
- pc->setstand(sd);
- clif->standing(&sd->bl);
- }
+ case SC_CRUCIS:
+ //Only affects demons and undead element (but not players)
+ if((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
+ return 0;
+ break;
+ case SC_LEXAETERNA:
+ if( (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) || sc->data[SC_FREEZE] )
+ return 0;
+ break;
+ case SC_KYRIE:
+ if (bl->type == BL_MOB)
+ return 0;
+ break;
+ case SC_OVERTHRUST:
+ if (sc->data[SC_OVERTHRUSTMAX])
+ return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex]
+ case SC_OVERTHRUSTMAX:
+ if( sc->option&OPTION_MADOGEAR )
+ return 0;//Overthrust and Overthrust Max cannot be used on Mado Gear [Ind]
+ break;
+ case SC_ADRENALINE:
+ if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE)))
+ return 0;
+ if (sc->data[SC_QUAGMIRE] ||
+ sc->data[SC_DEC_AGI] ||
+ sc->option&OPTION_MADOGEAR //Adrenaline doesn't affect Mado Gear [Ind]
+ )
+ return 0;
+ break;
+ case SC_ADRENALINE2:
+ if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE2)))
+ return 0;
+ if (sc->data[SC_QUAGMIRE] ||
+ sc->data[SC_DEC_AGI]
+ )
+ return 0;
+ break;
+ case SC_MAGNIFICAT:
+ if( sc->data[SC_OFFERTORIUM] || sc->option&OPTION_MADOGEAR ) //Mado is immune to magnificat
+ return 0;
+ break;
+ case SC_ONEHANDQUICKEN:
+ case SC_MER_QUICKEN:
+ case SC_TWOHANDQUICKEN:
+ if(sc->data[SC_DEC_AGI])
+ return 0;
- case SC_CONCENTRATION:
- case SC_SPEARQUICKEN:
- case SC_TRUESIGHT:
- case SC_WINDWALK:
- case SC_CARTBOOST:
- case SC_ASSNCROS:
- if (sc->data[SC_QUAGMIRE])
- return 0;
- if(sc->option&OPTION_MADOGEAR)
- return 0;//Mado is immune to increase agi, wind walk, cart boost, etc (others above) [Ind]
- break;
- case SC_CLOAKING:
- //Avoid cloaking with no wall and low skill level. [Skotlex]
- //Due to the cloaking card, we have to check the wall versus to known
- //skill level rather than the used one. [Skotlex]
- //if (sd && val1 < 3 && skill_check_cloaking(bl,NULL))
- if( sd && pc->checkskill(sd, AS_CLOAKING) < 3 && !skill->check_cloaking(bl,NULL) )
- return 0;
- break;
- case SC_MODECHANGE:
- {
- int mode;
- struct status_data *bstatus = status_get_base_status(bl);
- if (!bstatus) return 0;
- if (sc->data[type])
- { //Pile up with previous values.
- if(!val2) val2 = sc->data[type]->val2;
- val3 |= sc->data[type]->val3;
- val4 |= sc->data[type]->val4;
- }
- mode = val2?val2:bstatus->mode; //Base mode
- if (val4) mode&=~val4; //Del mode
- if (val3) mode|= val3; //Add mode
- if (mode == bstatus->mode) { //No change.
- if (sc->data[type]) //Abort previous status
- return status_change_end(bl, type, INVALID_TIMER);
- return 0;
- }
- }
- break;
- //Strip skills, need to divest something or it fails.
- case SC_NOEQUIPWEAPON:
- if (sd && !(flag&4)) { //apply sc anyway if loading saved sc_data
- int i;
- opt_flag = 0; //Reuse to check success condition.
- if(sd->bonus.unstripable_equip&EQP_WEAPON)
+ case SC_INC_AGI:
+ if(sd && pc_issit(sd)){
+ pc->setstand(sd);
+ clif->standing(&sd->bl);
+ }
+
+ case SC_CONCENTRATION:
+ case SC_SPEARQUICKEN:
+ case SC_TRUESIGHT:
+ case SC_WINDWALK:
+ case SC_CARTBOOST:
+ case SC_ASSNCROS:
+ if (sc->data[SC_QUAGMIRE])
+ return 0;
+ if(sc->option&OPTION_MADOGEAR)
+ return 0;//Mado is immune to increase agi, wind walk, cart boost, etc (others above) [Ind]
+ break;
+ case SC_CLOAKING:
+ //Avoid cloaking with no wall and low skill level. [Skotlex]
+ //Due to the cloaking card, we have to check the wall versus to known
+ //skill level rather than the used one. [Skotlex]
+ //if (sd && val1 < 3 && skill_check_cloaking(bl,NULL))
+ if( sd && pc->checkskill(sd, AS_CLOAKING) < 3 && !skill->check_cloaking(bl,NULL) )
+ return 0;
+ break;
+ case SC_MODECHANGE:
+ {
+ int mode;
+ struct status_data *bstatus = status_get_base_status(bl);
+ if (!bstatus) return 0;
+ if (sc->data[type])
+ { //Pile up with previous values.
+ if(!val2) val2 = sc->data[type]->val2;
+ val3 |= sc->data[type]->val3;
+ val4 |= sc->data[type]->val4;
+ }
+ mode = val2?val2:bstatus->mode; //Base mode
+ if (val4) mode&=~val4; //Del mode
+ if (val3) mode|= val3; //Add mode
+ if (mode == bstatus->mode) { //No change.
+ if (sc->data[type]) //Abort previous status
+ return status_change_end(bl, type, INVALID_TIMER);
return 0;
+ }
+ }
+ break;
+ //Strip skills, need to divest something or it fails.
+ case SC_NOEQUIPWEAPON:
+ if (sd && !(flag&4)) { //apply sc anyway if loading saved sc_data
+ int i;
+ opt_flag = 0; //Reuse to check success condition.
+ if(sd->bonus.unstripable_equip&EQP_WEAPON)
+ return 0;
- i = sd->equip_index[EQI_HAND_R];
- if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
- opt_flag|=2;
+ 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);
+ }
+ if (!opt_flag) return 0;
+ }
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ break;
+ case SC_NOEQUIPSHIELD:
+ if( val2 == 1 ) val2 = 0; //GX effect. Do not take shield off..
+ else
+ if (sd && !(flag&4)) {
+ int i;
+ if(sd->bonus.unstripable_equip&EQP_SHIELD)
+ return 0;
+ 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);
}
- if (!opt_flag) return 0;
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_NOEQUIPSHIELD:
- if( val2 == 1 ) val2 = 0; //GX effect. Do not take shield off..
- else
- if (sd && !(flag&4)) {
- int i;
- if(sd->bonus.unstripable_equip&EQP_SHIELD)
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ break;
+ case SC_NOEQUIPARMOR:
+ if (sd && !(flag&4)) {
+ int i;
+ if(sd->bonus.unstripable_equip&EQP_ARMOR)
+ return 0;
+ i = sd->equip_index[EQI_ARMOR];
+ if ( i < 0 || !sd->inventory_data[i] )
+ return 0;
+ pc->unequipitem(sd,i,3);
+ }
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ break;
+ case SC_NOEQUIPHELM:
+ if (sd && !(flag&4)) {
+ int i;
+ if(sd->bonus.unstripable_equip&EQP_HELM)
+ return 0;
+ i = sd->equip_index[EQI_HEAD_TOP];
+ if ( i < 0 || !sd->inventory_data[i] )
+ return 0;
+ pc->unequipitem(sd,i,3);
+ }
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ break;
+ case SC_MER_FLEE:
+ case SC_MER_ATK:
+ case SC_MER_HP:
+ case SC_MER_SP:
+ case SC_MER_HIT:
+ if( bl->type != BL_MER )
+ return 0; // Stats only for Mercenaries
+ break;
+ case SC_FOOD_STR:
+ if (sc->data[SC_FOOD_STR_CASH] && sc->data[SC_FOOD_STR_CASH]->val1 > val1)
return 0;
- i = sd->equip_index[EQI_HAND_L];
- if ( i < 0 || !sd->inventory_data[i] || sd->inventory_data[i]->type != IT_ARMOR )
+ break;
+ case SC_FOOD_AGI:
+ if (sc->data[SC_FOOD_AGI_CASH] && sc->data[SC_FOOD_AGI_CASH]->val1 > val1)
return 0;
- pc->unequipitem(sd,i,3);
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_NOEQUIPARMOR:
- if (sd && !(flag&4)) {
- int i;
- if(sd->bonus.unstripable_equip&EQP_ARMOR)
+ break;
+ case SC_FOOD_VIT:
+ if (sc->data[SC_FOOD_VIT_CASH] && sc->data[SC_FOOD_VIT_CASH]->val1 > val1)
return 0;
- i = sd->equip_index[EQI_ARMOR];
- if ( i < 0 || !sd->inventory_data[i] )
+ break;
+ case SC_FOOD_INT:
+ if (sc->data[SC_FOOD_INT_CASH] && sc->data[SC_FOOD_INT_CASH]->val1 > val1)
return 0;
- pc->unequipitem(sd,i,3);
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_NOEQUIPHELM:
- if (sd && !(flag&4)) {
- int i;
- if(sd->bonus.unstripable_equip&EQP_HELM)
+ break;
+ case SC_FOOD_DEX:
+ if (sc->data[SC_FOOD_DEX_CASH] && sc->data[SC_FOOD_DEX_CASH]->val1 > val1)
return 0;
- i = sd->equip_index[EQI_HEAD_TOP];
- if ( i < 0 || !sd->inventory_data[i] )
+ break;
+ case SC_FOOD_LUK:
+ if (sc->data[SC_FOOD_LUK_CASH] && sc->data[SC_FOOD_LUK_CASH]->val1 > val1)
return 0;
- pc->unequipitem(sd,i,3);
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_MER_FLEE:
- case SC_MER_ATK:
- case SC_MER_HP:
- case SC_MER_SP:
- case SC_MER_HIT:
- if( bl->type != BL_MER )
- return 0; // Stats only for Mercenaries
- break;
- case SC_FOOD_STR:
- if (sc->data[SC_FOOD_STR_CASH] && sc->data[SC_FOOD_STR_CASH]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_AGI:
- if (sc->data[SC_FOOD_AGI_CASH] && sc->data[SC_FOOD_AGI_CASH]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_VIT:
- if (sc->data[SC_FOOD_VIT_CASH] && sc->data[SC_FOOD_VIT_CASH]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_INT:
- if (sc->data[SC_FOOD_INT_CASH] && sc->data[SC_FOOD_INT_CASH]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_DEX:
- if (sc->data[SC_FOOD_DEX_CASH] && sc->data[SC_FOOD_DEX_CASH]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_LUK:
- if (sc->data[SC_FOOD_LUK_CASH] && sc->data[SC_FOOD_LUK_CASH]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_STR_CASH:
- if (sc->data[SC_FOOD_STR] && sc->data[SC_FOOD_STR]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_AGI_CASH:
- if (sc->data[SC_FOOD_AGI] && sc->data[SC_FOOD_AGI]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_VIT_CASH:
- if (sc->data[SC_FOOD_VIT] && sc->data[SC_FOOD_VIT]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_INT_CASH:
- if (sc->data[SC_FOOD_INT] && sc->data[SC_FOOD_INT]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_DEX_CASH:
- if (sc->data[SC_FOOD_DEX] && sc->data[SC_FOOD_DEX]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_LUK_CASH:
- if (sc->data[SC_FOOD_LUK] && sc->data[SC_FOOD_LUK]->val1 > val1)
- return 0;
- break;
- case SC_CAMOUFLAGE:
- if( sd && pc->checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill->check_camouflage(bl,NULL) )
- return 0;
- break;
- case SC__STRIPACCESSARY:
- if( sd ) {
- int i = -1;
- if( !(sd->bonus.unstripable_equip&EQI_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
- } if( !(sd->bonus.unstripable_equip&EQI_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
- }
- if( i < 0 )
+ break;
+ case SC_FOOD_STR_CASH:
+ if (sc->data[SC_FOOD_STR] && sc->data[SC_FOOD_STR]->val1 > val1)
return 0;
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_DEATHHURT:
- case SC_PYREXIA:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
- { // it doesn't stack or even renewed
- int i = SC_TOXIN;
- for(; i<= SC_LEECHESEND; i++)
- if(sc->data[i]) return 0;
- }
- break;
- case SC_SATURDAY_NIGHT_FEVER:
- if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION] || sc->data[SC__BLOODYLUST])
- return 0;
break;
- case SC_OFFERTORIUM:
- if (sc->data[SC_MAGNIFICAT])
- return 0;
+ case SC_FOOD_AGI_CASH:
+ if (sc->data[SC_FOOD_AGI] && sc->data[SC_FOOD_AGI]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_VIT_CASH:
+ if (sc->data[SC_FOOD_VIT] && sc->data[SC_FOOD_VIT]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_INT_CASH:
+ if (sc->data[SC_FOOD_INT] && sc->data[SC_FOOD_INT]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_DEX_CASH:
+ if (sc->data[SC_FOOD_DEX] && sc->data[SC_FOOD_DEX]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_LUK_CASH:
+ if (sc->data[SC_FOOD_LUK] && sc->data[SC_FOOD_LUK]->val1 > val1)
+ return 0;
+ break;
+ case SC_CAMOUFLAGE:
+ if( sd && pc->checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill->check_camouflage(bl,NULL) )
+ return 0;
+ break;
+ case SC__STRIPACCESSARY:
+ if( sd ) {
+ int i = -1;
+ if( !(sd->bonus.unstripable_equip&EQI_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
+ } if( !(sd->bonus.unstripable_equip&EQI_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
+ }
+ if( i < 0 )
+ return 0;
+ }
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
+ { // it doesn't stack or even renewed
+ int i = SC_TOXIN;
+ for(; i<= SC_LEECHESEND; i++)
+ if(sc->data[i]) return 0;
+ }
+ break;
+ case SC_SATURDAY_NIGHT_FEVER:
+ if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION] || sc->data[SC__BLOODYLUST])
+ return 0;
+ break;
+ case SC_OFFERTORIUM:
+ if (sc->data[SC_MAGNIFICAT])
+ return 0;
+ break;
}
//Check for BOSS resistances
@@ -6915,236 +6926,236 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//Before overlapping fail, one must check for status cured.
switch (type) {
- case SC_BLESSING:
- //TO-DO Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
- //but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
- if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC) {
- status_change_end(bl, SC_CURSE, INVALID_TIMER);
- if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- }
- break;
- case SC_INC_AGI:
- status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
- break;
- case SC_QUAGMIRE:
- status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
- status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
- status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
- //Also blocks the ones below...
- case SC_DEC_AGI:
- status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
- //Also blocks the ones below...
- case SC_DONTFORGETME:
- status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
- status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
- status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
- status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_ACCELERATION, INVALID_TIMER);
- break;
- case SC_ONEHANDQUICKEN:
- //Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
- status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
- break;
- case SC_OVERTHRUSTMAX:
- //Cancels Normal Overthrust. [Skotlex]
- status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
- break;
- case SC_KYRIE:
- //Cancels Assumptio
- status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
- break;
- case SC_DELUGE:
- if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
- status_change_end(bl, SC_BLIND, INVALID_TIMER);
- break;
- case SC_SILENCE:
- if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
- status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
- break;
- case SC_HIDING:
- status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER);
- status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER);
- break;
- case SC__BLOODYLUST:
- case SC_BERSERK:
- if(battle_config.berserk_cancels_buffs) {
- status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
+ case SC_BLESSING:
+ //TO-DO Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
+ //but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
+ if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC) {
+ status_change_end(bl, SC_CURSE, INVALID_TIMER);
+ if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ }
+ break;
+ case SC_INC_AGI:
+ status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
+ break;
+ case SC_QUAGMIRE:
+ status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
+ status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
+ status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
+ //Also blocks the ones below...
+ case SC_DEC_AGI:
+ status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
+ //Also blocks the ones below...
+ case SC_DONTFORGETME:
+ status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
+ status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
- status_change_end(bl, SC_PARRYING, INVALID_TIMER);
- status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
+ status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
- }
-#ifdef RENEWAL
- else {
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- }
-#endif
- break;
- case SC_ASSUMPTIO:
- status_change_end(bl, SC_KYRIE, INVALID_TIMER);
- status_change_end(bl, SC_KAITE, INVALID_TIMER);
- break;
- case SC_KAITE:
- status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
- break;
- case SC_CARTBOOST:
- if(sc->data[SC_DEC_AGI])
- { //Cancel Decrease Agi, but take no further effect [Skotlex]
- status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
- return 0;
- }
- break;
- case SC_FUSION:
- status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
- break;
- case SC_GS_ADJUSTMENT:
- status_change_end(bl, SC_GS_MADNESSCANCEL, INVALID_TIMER);
- break;
- case SC_GS_MADNESSCANCEL:
- status_change_end(bl, SC_GS_ADJUSTMENT, INVALID_TIMER);
- break;
- //NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
- case SC_PROPERTYUNDEAD:
- status_change_end(bl, SC_BLESSING, INVALID_TIMER);
- status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
- break;
- case SC_FOOD_STR:
- status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_AGI:
- status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_VIT:
- status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_INT:
- status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_DEX:
- status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_LUK:
- status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_STR_CASH:
- status_change_end(bl, SC_FOOD_STR, INVALID_TIMER);
- break;
- case SC_FOOD_AGI_CASH:
- status_change_end(bl, SC_FOOD_AGI, INVALID_TIMER);
- break;
- case SC_FOOD_VIT_CASH:
- status_change_end(bl, SC_FOOD_VIT, INVALID_TIMER);
- break;
- case SC_FOOD_INT_CASH:
- status_change_end(bl, SC_FOOD_INT, INVALID_TIMER);
- break;
- case SC_FOOD_DEX_CASH:
- status_change_end(bl, SC_FOOD_DEX, INVALID_TIMER);
- break;
- case SC_FOOD_LUK_CASH:
- status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER);
- break;
- case SC_ENDURE:
- if( val4 )
- status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
- break;
- case SC_FIGHTINGSPIRIT:
- status_change_end(bl, type, INVALID_TIMER); // Remove previous one.
- break;
- case SC_MARSHOFABYSS:
- status_change_end(bl, SC_INCAGI, INVALID_TIMER);
- status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
- break;
- case SC_SWING:
- case SC_SYMPHONY_LOVE:
- case SC_MOONLIT_SERENADE:
- case SC_RUSH_WINDMILL:
- case SC_ECHOSONG:
- case SC_HARMONIZE: //group A doesn't overlap
- if (type != SC_SWING) status_change_end(bl, SC_SWING, INVALID_TIMER);
- if (type != SC_SYMPHONY_LOVE) status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER);
- if (type != SC_MOONLIT_SERENADE) status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER);
- if (type != SC_RUSH_WINDMILL) status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER);
- if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
- if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
- break;
- case SC_SIREN:
- case SC_DEEP_SLEEP:
- case SC_GLOOMYDAY:
- case SC_SONG_OF_MANA:
- case SC_DANCE_WITH_WUG:
- case SC_SATURDAY_NIGHT_FEVER:
- case SC_LERADS_DEW:
- case SC_MELODYOFSINK:
- case SC_BEYOND_OF_WARCRY:
- case SC_UNLIMITED_HUMMING_VOICE: //group B
- if (type != SC_SIREN) status_change_end(bl, SC_SIREN, INVALID_TIMER);
- if (type != SC_DEEP_SLEEP) status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
- if (type != SC_LERADS_DEW) status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER);
- if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
- if (type != SC_BEYOND_OF_WARCRY) status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
- if (type != SC_UNLIMITED_HUMMING_VOICE) status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER);
- if (type != SC_GLOOMYDAY) {
- status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
- status_change_end(bl, SC_GLOOMYDAY_SK, INVALID_TIMER);
- }
- if (type != SC_SONG_OF_MANA) status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER);
- if (type != SC_DANCE_WITH_WUG) status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER);
- if (type != SC_SATURDAY_NIGHT_FEVER) {
- if (sc->data[SC_SATURDAY_NIGHT_FEVER]) {
- sc->data[SC_SATURDAY_NIGHT_FEVER]->val2 = 0; //mark to not lose hp
- status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER);
- }
- }
- break;
- case SC_REFLECTSHIELD:
- status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER);
- break;
- case SC_LG_REFLECTDAMAGE:
- status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
- break;
- case SC_SHIELDSPELL_DEF:
- case SC_SHIELDSPELL_MDEF:
- case SC_SHIELDSPELL_REF:
- status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
- if( type != SC_SHIELDSPELL_DEF )
- status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
- if( type != SC_SHIELDSPELL_MDEF )
- status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
- if( type != SC_SHIELDSPELL_REF )
- status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
- break;
- case SC_GENTLETOUCH_ENERGYGAIN:
- case SC_GENTLETOUCH_CHANGE:
- case SC_GENTLETOUCH_REVITALIZE:
- if( type != SC_GENTLETOUCH_REVITALIZE )
- status_change_end(bl, SC_GENTLETOUCH_REVITALIZE, INVALID_TIMER);
- if( type != SC_GENTLETOUCH_ENERGYGAIN )
- status_change_end(bl, SC_GENTLETOUCH_ENERGYGAIN, INVALID_TIMER);
- if( type != SC_GENTLETOUCH_CHANGE )
- status_change_end(bl, SC_GENTLETOUCH_CHANGE, INVALID_TIMER);
- break;
- case SC_INVINCIBLE:
- status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER);
- break;
- case SC_INVINCIBLEOFF:
- status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER);
- break;
- case SC_MAGICPOWER:
- status_change_end(bl, type, INVALID_TIMER);
- break;
+ status_change_end(bl, SC_ACCELERATION, INVALID_TIMER);
+ break;
+ case SC_ONEHANDQUICKEN:
+ //Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
+ status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
+ break;
+ case SC_OVERTHRUSTMAX:
+ //Cancels Normal Overthrust. [Skotlex]
+ status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
+ break;
+ case SC_KYRIE:
+ //Cancels Assumptio
+ status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
+ break;
+ case SC_DELUGE:
+ if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
+ break;
+ case SC_SILENCE:
+ if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
+ status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
+ break;
+ case SC_HIDING:
+ status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER);
+ status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER);
+ break;
+ case SC__BLOODYLUST:
+ case SC_BERSERK:
+ if(battle_config.berserk_cancels_buffs) {
+ status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
+ status_change_end(bl, SC_PARRYING, INVALID_TIMER);
+ status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
+ status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
+ }
+ #ifdef RENEWAL
+ else {
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ }
+ #endif
+ break;
+ case SC_ASSUMPTIO:
+ status_change_end(bl, SC_KYRIE, INVALID_TIMER);
+ status_change_end(bl, SC_KAITE, INVALID_TIMER);
+ break;
+ case SC_KAITE:
+ status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
+ break;
+ case SC_CARTBOOST:
+ if(sc->data[SC_DEC_AGI])
+ { //Cancel Decrease Agi, but take no further effect [Skotlex]
+ status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
+ return 0;
+ }
+ break;
+ case SC_FUSION:
+ status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
+ break;
+ case SC_GS_ADJUSTMENT:
+ status_change_end(bl, SC_GS_MADNESSCANCEL, INVALID_TIMER);
+ break;
+ case SC_GS_MADNESSCANCEL:
+ status_change_end(bl, SC_GS_ADJUSTMENT, INVALID_TIMER);
+ break;
+ //NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
+ case SC_PROPERTYUNDEAD:
+ status_change_end(bl, SC_BLESSING, INVALID_TIMER);
+ status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
+ break;
+ case SC_FOOD_STR:
+ status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_AGI:
+ status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_VIT:
+ status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_INT:
+ status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_DEX:
+ status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_LUK:
+ status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_STR_CASH:
+ status_change_end(bl, SC_FOOD_STR, INVALID_TIMER);
+ break;
+ case SC_FOOD_AGI_CASH:
+ status_change_end(bl, SC_FOOD_AGI, INVALID_TIMER);
+ break;
+ case SC_FOOD_VIT_CASH:
+ status_change_end(bl, SC_FOOD_VIT, INVALID_TIMER);
+ break;
+ case SC_FOOD_INT_CASH:
+ status_change_end(bl, SC_FOOD_INT, INVALID_TIMER);
+ break;
+ case SC_FOOD_DEX_CASH:
+ status_change_end(bl, SC_FOOD_DEX, INVALID_TIMER);
+ break;
+ case SC_FOOD_LUK_CASH:
+ status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER);
+ break;
+ case SC_ENDURE:
+ if( val4 )
+ status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
+ break;
+ case SC_FIGHTINGSPIRIT:
+ status_change_end(bl, type, INVALID_TIMER); // Remove previous one.
+ break;
+ case SC_MARSHOFABYSS:
+ status_change_end(bl, SC_INCAGI, INVALID_TIMER);
+ status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
+ break;
+ case SC_SWING:
+ case SC_SYMPHONY_LOVE:
+ case SC_MOONLIT_SERENADE:
+ case SC_RUSH_WINDMILL:
+ case SC_ECHOSONG:
+ case SC_HARMONIZE: //group A doesn't overlap
+ if (type != SC_SWING) status_change_end(bl, SC_SWING, INVALID_TIMER);
+ if (type != SC_SYMPHONY_LOVE) status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER);
+ if (type != SC_MOONLIT_SERENADE) status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER);
+ if (type != SC_RUSH_WINDMILL) status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER);
+ if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
+ if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
+ break;
+ case SC_SIREN:
+ case SC_DEEP_SLEEP:
+ case SC_GLOOMYDAY:
+ case SC_SONG_OF_MANA:
+ case SC_DANCE_WITH_WUG:
+ case SC_SATURDAY_NIGHT_FEVER:
+ case SC_LERADS_DEW:
+ case SC_MELODYOFSINK:
+ case SC_BEYOND_OF_WARCRY:
+ case SC_UNLIMITED_HUMMING_VOICE: //group B
+ if (type != SC_SIREN) status_change_end(bl, SC_SIREN, INVALID_TIMER);
+ if (type != SC_DEEP_SLEEP) status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
+ if (type != SC_LERADS_DEW) status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER);
+ if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
+ if (type != SC_BEYOND_OF_WARCRY) status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
+ if (type != SC_UNLIMITED_HUMMING_VOICE) status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER);
+ if (type != SC_GLOOMYDAY) {
+ status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
+ status_change_end(bl, SC_GLOOMYDAY_SK, INVALID_TIMER);
+ }
+ if (type != SC_SONG_OF_MANA) status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER);
+ if (type != SC_DANCE_WITH_WUG) status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER);
+ if (type != SC_SATURDAY_NIGHT_FEVER) {
+ if (sc->data[SC_SATURDAY_NIGHT_FEVER]) {
+ sc->data[SC_SATURDAY_NIGHT_FEVER]->val2 = 0; //mark to not lose hp
+ status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER);
+ }
+ }
+ break;
+ case SC_REFLECTSHIELD:
+ status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER);
+ break;
+ case SC_LG_REFLECTDAMAGE:
+ status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
+ break;
+ case SC_SHIELDSPELL_DEF:
+ case SC_SHIELDSPELL_MDEF:
+ case SC_SHIELDSPELL_REF:
+ status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
+ if( type != SC_SHIELDSPELL_DEF )
+ status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
+ if( type != SC_SHIELDSPELL_MDEF )
+ status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
+ if( type != SC_SHIELDSPELL_REF )
+ status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
+ break;
+ case SC_GENTLETOUCH_ENERGYGAIN:
+ case SC_GENTLETOUCH_CHANGE:
+ case SC_GENTLETOUCH_REVITALIZE:
+ if( type != SC_GENTLETOUCH_REVITALIZE )
+ status_change_end(bl, SC_GENTLETOUCH_REVITALIZE, INVALID_TIMER);
+ if( type != SC_GENTLETOUCH_ENERGYGAIN )
+ status_change_end(bl, SC_GENTLETOUCH_ENERGYGAIN, INVALID_TIMER);
+ if( type != SC_GENTLETOUCH_CHANGE )
+ status_change_end(bl, SC_GENTLETOUCH_CHANGE, INVALID_TIMER);
+ break;
+ case SC_INVINCIBLE:
+ status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER);
+ break;
+ case SC_INVINCIBLEOFF:
+ status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER);
+ break;
+ case SC_MAGICPOWER:
+ status_change_end(bl, type, INVALID_TIMER);
+ break;
}
//Check for overlapping fails
@@ -8822,6 +8833,27 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (battle_config.sc_castcancel&bl->type)
unit_skillcastcancel(bl, 0);
break;
+ /* */
+ case SC_ITEMSCRIPT:
+ if( sd ) {
+ switch( val1 ) {
+ //case 4121://Phree
+ //case 4047://Ghostring
+ case 4302://Gunka
+ clif->status_change(bl,SI_MVPCARD_TAOGUNKA,1,tick,0,0,0);
+ break;
+ case 4132://Mistress
+ clif->status_change(bl,SI_MVPCARD_MISTRESS,1,tick,0,0,0);
+ break;
+ case 4143://Orc Hero
+ clif->status_change(bl,SI_MVPCARD_ORCHERO,1,tick,0,0,0);
+ break;
+ case 4135://Orc Lord
+ clif->status_change(bl,SI_MVPCARD_ORCLORD,1,tick,0,0,0);
+ break;
+ }
+ }
+ break;
}
// Set option as needed.
@@ -9223,24 +9255,24 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if (sce->timer != INVALID_TIMER) //Could be a SC with infinite duration
iTimer->delete_timer(sce->timer,status_change_timer);
if (sc->opt1)
- switch (type) {
- //"Ugly workaround" [Skotlex]
- //delays status change ending so that a skill that sets opt1 fails to
- //trigger when it also removed one
- case SC_STONE:
- sce->val3 = 0; //Petrify time counter.
- case SC_FREEZE:
- case SC_STUN:
- case SC_SLEEP:
- if (sce->val1) {
- //Removing the 'level' shouldn't affect anything in the code
- //since these SC are not affected by it, and it lets us know
- //if we have already delayed this attack or not.
- sce->val1 = 0;
- sce->timer = iTimer->add_timer(iTimer->gettick()+10, status_change_timer, bl->id, type);
- return 1;
+ switch (type) {
+ //"Ugly workaround" [Skotlex]
+ //delays status change ending so that a skill that sets opt1 fails to
+ //trigger when it also removed one
+ case SC_STONE:
+ sce->val3 = 0; //Petrify time counter.
+ case SC_FREEZE:
+ case SC_STUN:
+ case SC_SLEEP:
+ if (sce->val1) {
+ //Removing the 'level' shouldn't affect anything in the code
+ //since these SC are not affected by it, and it lets us know
+ //if we have already delayed this attack or not.
+ sce->val1 = 0;
+ sce->timer = iTimer->add_timer(iTimer->gettick()+10, status_change_timer, bl->id, type);
+ return 1;
+ }
}
- }
}
(sc->count)--;
@@ -9253,7 +9285,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
vd = status_get_viewdata(bl);
calc_flag = StatusChangeFlagTable[type];
- switch(type){
+ switch(type) {
case SC_GRANITIC_ARMOR:{
int dammage = status->max_hp*sce->val3/100;
if(status->hp < dammage) //to not kill him
@@ -9665,6 +9697,26 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
case SC_FULL_THROTTLE:
sc_start(bl,SC_REBOUND,100,sce->val1,skill->get_time2(ALL_FULL_THROTTLE,sce->val1));
break;
+ case SC_ITEMSCRIPT:
+ if( sd ) {
+ switch( sce->val1 ) {
+ //case 4121://Phree
+ //case 4047://Ghostring
+ case 4302://Gunka
+ clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_MVPCARD_TAOGUNKA);
+ break;
+ case 4132://Mistress
+ clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_MVPCARD_MISTRESS);
+ break;
+ case 4143://Orc Hero
+ clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_MVPCARD_ORCHERO);
+ break;
+ case 4135://Orc Lord
+ clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_MVPCARD_ORCLORD);
+ break;
+ }
+ }
+ break;
}
opt_flag = 1;
@@ -10830,7 +10882,7 @@ int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int fl
struct status_change *sc = status_get_sc(bl);
if ( bl->type == BL_PC && watk->atk ){
- if ( flag&16 )
+ if ( flag&2 )
dstr = status_get_dex(bl);
else
dstr = status_get_str(bl);
@@ -10851,10 +10903,10 @@ int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int fl
else
max = min;
}
-
- if( bl->type == BL_PC && ((TBL_PC*)bl)->right_weapon.overrefine > 0)
- max += rnd()%((TBL_PC*)bl)->right_weapon.overrefine + 1;
+ if( bl->type == BL_PC && ((TBL_PC*)bl)->right_weapon.overrefine > 0 && !(flag&2) )
+ max += rnd()%((TBL_PC*)bl)->right_weapon.overrefine + 1;
+
max = status_calc_watk(bl, sc, max, false);
return max;
@@ -10967,11 +11019,15 @@ int status_change_clear_buffs (struct block_list* bl, int type)
if( !sc->data[i] || !status_get_sc_type(i) )
continue;
- if( type&1 && !(status_get_sc_type(i)&SC_BUFF) )
+ if( type&3 && !(status_get_sc_type(i)&SC_BUFF) && !(status_get_sc_type(i)&SC_DEBUFF) )
continue;
- if( type&2 && !(status_get_sc_type(i)&SC_DEBUFF) )
- continue;
+ if( !(type&3) ){
+ if( type&1 && !(status_get_sc_type(i)&SC_BUFF) )
+ continue;
+ if( type&2 && !(status_get_sc_type(i)&SC_DEBUFF) )
+ continue;
+ }
switch (i) {
case SC_DEEP_SLEEP:
@@ -11417,12 +11473,11 @@ static bool status_readdb_refine(char* fields[], int columns, int current)
return true;
}
-static bool status_readdb_scconfig(char* fields[], int columns, int current)
-{
+static bool status_readdb_scconfig(char* fields[], int columns, int current) {
int val = 0;
char* type = fields[0];
- if( !script_get_constant(type, &val) ){
+ if( !script->get_constant(type, &val) ){
ShowWarning("status_readdb_sc_conf: Invalid status type %s specified.\n", type);
return false;
}
diff --git a/src/map/status.h b/src/map/status.h
index fbce95f17..a469dc71f 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -147,7 +147,7 @@ typedef enum sc_type {
SC_VOLCANO, //100,
SC_DELUGE,
SC_VIOLENTGALE,
- SC_WATK_ELEMENT,
+ SC_SUB_WEAPONPROPERTY,
SC_ARMOR,
SC_ARMORPROPERTY,
SC_NOCHAT,
@@ -672,6 +672,7 @@ typedef enum sc_type {
SC_HANBOK,
SC_MONSTER_TRANSFORM,
+ SC_ANGEL_PROTECT,
SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
} sc_type;
@@ -993,7 +994,7 @@ enum si_type {
SI_INVINCIBLE = 311,
SI_CASH_PLUSONLYJOBEXP = 312,
SI_PARTYFLEE = 313,
-// SI_ANGEL_PROTECT = 314,
+ SI_ANGEL_PROTECT = 314,
// SI_ENDURE_MDEF = 315,
SI_ENCHANTBLADE = 316,
SI_DEATHBOUND = 317,
@@ -1850,11 +1851,12 @@ int status_check_visibility(struct block_list *src, struct block_list *target);
int status_change_spread( struct block_list *src, struct block_list *bl );
defType status_calc_def(struct block_list *bl, struct status_change *sc, int, bool);
-signed short status_calc_def2(struct block_list *,struct status_change *, int, bool);
+signed short status_calc_def2(struct block_list *, struct status_change *, int, bool);
defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int, bool);
-signed short status_calc_mdef2(struct block_list *,struct status_change *, int, bool);
+signed short status_calc_mdef2(struct block_list *, struct status_change *, int, bool);
#ifdef RENEWAL
+unsigned short status_calc_batk(struct block_list *, struct status_change *, int, bool);
unsigned short status_base_matk(const struct status_data* status, int level);
int status_get_weapon_atk(struct block_list *src, struct weapon_atk *watk, int flag);
int status_get_total_mdef(struct block_list *src);
diff --git a/src/map/storage.c b/src/map/storage.c
index ea30f6c0f..5b3c75d58 100644
--- a/src/map/storage.c
+++ b/src/map/storage.c
@@ -1,5 +1,6 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
+// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// See the LICENSE file
+// Portions Copyright (c) Athena Dev Teams
#include "../common/cbasetypes.h"
#include "../common/db.h"
@@ -23,9 +24,6 @@
#include <stdlib.h>
#include <string.h>
-
-static DBMap* guild_storage_db; // int guild_id -> struct guild_storage*
-
/*==========================================
* Sort items in the warehouse
*------------------------------------------*/
@@ -57,14 +55,13 @@ static void storage_sortitem(struct item* items, unsigned int size)
/*==========================================
* Init/Terminate
*------------------------------------------*/
-int do_init_storage(void) // Called from map.c::do_init()
-{
- guild_storage_db=idb_alloc(DB_OPT_RELEASE_DATA);
+/* ##TODO not really init_storage but init_gstorage, should rename/move */
+int do_init_storage(void) { // Called from map.c::do_init()
+ gstorage->db = idb_alloc(DB_OPT_RELEASE_DATA);
return 1;
}
-void do_final_storage(void) // by [MC Cameri]
-{
- guild_storage_db->destroy(guild_storage_db,NULL);
+void do_final_storage(void) { // by [MC Cameri]
+ gstorage->db->destroy(gstorage->db,NULL);
}
/**
@@ -75,15 +72,14 @@ static int storage_reconnect_sub(DBKey key, DBData *data, va_list ap)
{
struct guild_storage *stor = DB->data2ptr(data);
if (stor->dirty && stor->storage_status == 0) //Save closed storages.
- storage_guild_storagesave(0, stor->guild_id,0);
+ gstorage->save(0, stor->guild_id,0);
return 0;
}
//Function to be invoked upon server reconnection to char. To save all 'dirty' storages [Skotlex]
-void do_reconnect_storage(void)
-{
- guild_storage_db->foreach(guild_storage_db, storage_reconnect_sub);
+void do_reconnect_storage(void) {
+ gstorage->db->foreach(gstorage->db, storage_reconnect_sub);
}
/*==========================================
@@ -132,8 +128,7 @@ int compare_item(struct item *a, struct item *b)
/*==========================================
* Internal add-item function.
*------------------------------------------*/
-static int storage_additem(struct map_session_data* sd, struct item* item_data, int amount)
-{
+int storage_additem(struct map_session_data* sd, struct item* item_data, int amount) {
struct storage_data* stor = &sd->status.storage;
struct item_data *data;
int i;
@@ -141,7 +136,7 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data,
if( item_data->nameid <= 0 || amount <= 0 )
return 1;
- data = itemdb_search(item_data->nameid);
+ data = itemdb->search(item_data->nameid);
if( data->stack.storage && amount > data->stack.amount )
{// item stack limitation
@@ -226,7 +221,7 @@ int storage_storageadd(struct map_session_data* sd, int index, int amount)
if( amount < 1 || amount > sd->status.inventory[index].amount )
return 0;
- if( storage_additem(sd,&sd->status.inventory[index],amount) == 0 )
+ if( storage->additem(sd,&sd->status.inventory[index],amount) == 0 )
pc->delitem(sd,index,amount,0,4,LOG_TYPE_STORAGE);
return 1;
@@ -253,7 +248,7 @@ int storage_storageget(struct map_session_data* sd, int index, int amount)
return 0;
if( (flag = pc->additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE)) == 0 )
- storage_delitem(sd,index,amount);
+ storage->delitem(sd,index,amount);
else
clif->additem(sd,0,0,flag);
@@ -283,7 +278,7 @@ int storage_storageaddfromcart(struct map_session_data* sd, int index, int amoun
if( amount < 1 || amount > sd->status.cart[index].amount )
return 0;
- if( storage_additem(sd,&sd->status.cart[index],amount) == 0 )
+ if( storage->additem(sd,&sd->status.cart[index],amount) == 0 )
pc->cart_delitem(sd,index,amount,0,LOG_TYPE_STORAGE);
return 1;
@@ -310,7 +305,7 @@ int storage_storagegettocart(struct map_session_data* sd, int index, int amount)
return 0;
if( pc->cart_additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE) == 0 )
- storage_delitem(sd,index,amount);
+ storage->delitem(sd,index,amount);
return 1;
}
@@ -326,7 +321,7 @@ void storage_storageclose(struct map_session_data* sd)
clif->storageclose(sd);
if( iMap->save_settings&4 )
- chrif_save(sd,0); //Invokes the storage saving as well.
+ chrif->save(sd,0); //Invokes the storage saving as well.
sd->state.storage_flag = 0;
}
@@ -339,7 +334,7 @@ void storage_storage_quit(struct map_session_data* sd, int flag)
nullpo_retv(sd);
if (iMap->save_settings&4)
- chrif_save(sd, flag); //Invokes the storage saving as well.
+ chrif->save(sd, flag); //Invokes the storage saving as well.
sd->state.storage_flag = 0;
}
@@ -359,19 +354,17 @@ struct guild_storage *guild2storage(int guild_id)
{
struct guild_storage *gs = NULL;
if(guild->search(guild_id) != NULL)
- gs = idb_ensure(guild_storage_db,guild_id,create_guildstorage);
+ gs = idb_ensure(gstorage->db,guild_id,create_guildstorage);
return gs;
}
//For just locating a storage without creating one. [Skotlex]
-struct guild_storage *guild2storage2(int guild_id)
-{
- return (struct guild_storage*)idb_get(guild_storage_db,guild_id);
+struct guild_storage *guild2storage2(int guild_id) {
+ return (struct guild_storage*)idb_get(gstorage->db,guild_id);
}
-int guild_storage_delete(int guild_id)
-{
- idb_remove(guild_storage_db,guild_id);
+int guild_storage_delete(int guild_id) {
+ idb_remove(gstorage->db,guild_id);
return 0;
}
@@ -399,7 +392,7 @@ int storage_guild_storageopen(struct map_session_data* sd)
return 1;
}
- if((gstor = guild2storage2(sd->status.guild_id)) == NULL) {
+ if((gstor = gstorage->id2storage2(sd->status.guild_id)) == NULL) {
intif_request_guild_storage(sd->status.account_id,sd->status.guild_id);
return 0;
}
@@ -435,7 +428,7 @@ int guild_storage_additem(struct map_session_data* sd, struct guild_storage* sto
if(item_data->nameid <= 0 || amount <= 0)
return 1;
- data = itemdb_search(item_data->nameid);
+ data = itemdb->search(item_data->nameid);
if( data->stack.guildstorage && amount > data->stack.amount )
{// item stack limitation
@@ -512,7 +505,7 @@ int storage_guild_storageadd(struct map_session_data* sd, int index, int amount)
struct guild_storage *stor;
nullpo_ret(sd);
- nullpo_ret(stor=guild2storage2(sd->status.guild_id));
+ nullpo_ret(stor=gstorage->id2storage2(sd->status.guild_id));
if( !stor->storage_status || stor->storage_amount > MAX_GUILD_STORAGE )
return 0;
@@ -527,11 +520,11 @@ int storage_guild_storageadd(struct map_session_data* sd, int index, int amount)
return 0;
if( stor->lock ) {
- storage_guild_storageclose(sd);
+ gstorage->close(sd);
return 0;
}
- if(guild_storage_additem(sd,stor,&sd->status.inventory[index],amount)==0)
+ if(gstorage->additem(sd,stor,&sd->status.inventory[index],amount)==0)
pc->delitem(sd,index,amount,0,4,LOG_TYPE_GSTORAGE);
return 1;
@@ -565,12 +558,12 @@ int storage_guild_storageget(struct map_session_data* sd, int index, int amount)
return 0;
if( stor->lock ) {
- storage_guild_storageclose(sd);
+ gstorage->close(sd);
return 0;
}
if((flag = pc->additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)) == 0)
- guild_storage_delitem(sd,stor,index,amount);
+ gstorage->delitem(sd,stor,index,amount);
else //inform fail
clif->additem(sd,0,0,flag);
// log_fromstorage(sd, index, 1);
@@ -604,7 +597,7 @@ int storage_guild_storageaddfromcart(struct map_session_data* sd, int index, int
if( amount < 1 || amount > sd->status.cart[index].amount )
return 0;
- if(guild_storage_additem(sd,stor,&sd->status.cart[index],amount)==0)
+ if(gstorage->additem(sd,stor,&sd->status.cart[index],amount)==0)
pc->cart_delitem(sd,index,amount,0,LOG_TYPE_GSTORAGE);
return 1;
@@ -637,7 +630,7 @@ int storage_guild_storagegettocart(struct map_session_data* sd, int index, int a
return 0;
if(pc->cart_additem(sd,&stor->items[index],amount,LOG_TYPE_GSTORAGE)==0)
- guild_storage_delitem(sd,stor,index,amount);
+ gstorage->delitem(sd,stor,index,amount);
return 1;
}
@@ -673,7 +666,7 @@ int storage_guild_storagesaved(int guild_id)
{
struct guild_storage *stor;
- if((stor=guild2storage2(guild_id)) != NULL) {
+ if((stor=gstorage->id2storage2(guild_id)) != NULL) {
if (stor->dirty && stor->storage_status == 0)
{ //Storage has been correctly saved.
stor->dirty = 0;
@@ -689,15 +682,15 @@ int storage_guild_storageclose(struct map_session_data* sd)
struct guild_storage *stor;
nullpo_ret(sd);
- nullpo_ret(stor=guild2storage2(sd->status.guild_id));
+ nullpo_ret(stor=gstorage->id2storage2(sd->status.guild_id));
clif->storageclose(sd);
if (stor->storage_status)
{
if (iMap->save_settings&4)
- chrif_save(sd, 0); //This one also saves the storage. [Skotlex]
+ chrif->save(sd, 0); //This one also saves the storage. [Skotlex]
else
- storage_guild_storagesave(sd->status.account_id, sd->status.guild_id,0);
+ gstorage->save(sd->status.account_id, sd->status.guild_id,0);
stor->storage_status=0;
}
sd->state.storage_flag = 0;
@@ -710,7 +703,7 @@ int storage_guild_storage_quit(struct map_session_data* sd, int flag)
struct guild_storage *stor;
nullpo_ret(sd);
- nullpo_ret(stor=guild2storage2(sd->status.guild_id));
+ nullpo_ret(stor=gstorage->id2storage2(sd->status.guild_id));
if(flag)
{ //Only during a guild break flag is 1 (don't save storage)
@@ -718,18 +711,55 @@ int storage_guild_storage_quit(struct map_session_data* sd, int flag)
stor->storage_status = 0;
clif->storageclose(sd);
if (iMap->save_settings&4)
- chrif_save(sd,0);
+ chrif->save(sd,0);
return 0;
}
if(stor->storage_status) {
if (iMap->save_settings&4)
- chrif_save(sd,0);
+ chrif->save(sd,0);
else
- storage_guild_storagesave(sd->status.account_id,sd->status.guild_id,1);
+ gstorage->save(sd->status.account_id,sd->status.guild_id,1);
}
sd->state.storage_flag = 0;
stor->storage_status = 0;
return 0;
}
+void storage_defaults(void) {
+ storage = &storage_s;
+
+ /* */
+ storage->init = do_init_storage;
+ storage->final = do_final_storage;
+ /* */
+ storage->reconnect = do_reconnect_storage;
+ /* */
+ storage->delitem = storage_delitem;
+ storage->open = storage_storageopen;
+ storage->add = storage_storageadd;
+ storage->additem = storage_additem;
+ storage->get = storage_storageget;
+ storage->addfromcart = storage_storageaddfromcart;
+ storage->gettocart = storage_storagegettocart;
+ storage->close = storage_storageclose;
+ storage->pc_quit = storage_storage_quit;
+}
+void gstorage_defaults(void) {
+ gstorage = &gstorage_s;
+
+ gstorage->id2storage = guild2storage;
+ gstorage->id2storage2 = guild2storage2;
+ gstorage->delete = guild_storage_delete;
+ gstorage->open = storage_guild_storageopen;
+ gstorage->additem = guild_storage_additem;
+ gstorage->delitem = guild_storage_delitem;
+ gstorage->add = storage_guild_storageadd;
+ gstorage->get = storage_guild_storageget;
+ gstorage->addfromcart = storage_guild_storageaddfromcart;
+ gstorage->gettocart = storage_guild_storagegettocart;
+ gstorage->close = storage_guild_storageclose;
+ gstorage->pc_quit = storage_guild_storage_quit;
+ gstorage->save = storage_guild_storagesave;
+ gstorage->saved = storage_guild_storagesaved;
+}
diff --git a/src/map/storage.h b/src/map/storage.h
index c08ec81cb..fc05ef06c 100644
--- a/src/map/storage.h
+++ b/src/map/storage.h
@@ -1,41 +1,56 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
+// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// See the LICENSE file
+// Portions Copyright (c) Athena Dev Teams
#ifndef _STORAGE_H_
#define _STORAGE_H_
-//#include "../common/mmo.h"
struct storage_data;
struct guild_storage;
struct item;
-//#include "map.h"
struct map_session_data;
+struct DBMap;
-int storage_delitem(struct map_session_data* sd, int n, int amount);
-int storage_storageopen(struct map_session_data *sd);
-int storage_storageadd(struct map_session_data *sd,int index,int amount);
-int storage_storageget(struct map_session_data *sd,int index,int amount);
-int storage_storageaddfromcart(struct map_session_data *sd,int index,int amount);
-int storage_storagegettocart(struct map_session_data *sd,int index,int amount);
-void storage_storageclose(struct map_session_data *sd);
-int do_init_storage(void);
-void do_final_storage(void);
-void do_reconnect_storage(void);
-void storage_storage_quit(struct map_session_data *sd, int flag);
+struct storage_interface {
+ int (*init) (void);
+ void (*final) (void);
+ /* */
+ void (*reconnect) (void);
+ /* */
+ int (*delitem) (struct map_session_data* sd, int n, int amount);
+ int (*open) (struct map_session_data *sd);
+ int (*add) (struct map_session_data *sd,int index,int amount);
+ int (*get) (struct map_session_data *sd,int index,int amount);
+ int (*additem) (struct map_session_data* sd, struct item* item_data, int amount);
+ int (*addfromcart) (struct map_session_data *sd,int index,int amount);
+ int (*gettocart) (struct map_session_data *sd,int index,int amount);
+ void (*close) (struct map_session_data *sd);
+ void (*pc_quit) (struct map_session_data *sd, int flag);
+} storage_s;
+struct storage_interface *storage;
-struct guild_storage* guild2storage(int guild_id);
-struct guild_storage *guild2storage2(int guild_id);
-int guild_storage_delete(int guild_id);
-int storage_guild_storageopen(struct map_session_data *sd);
-int guild_storage_additem(struct map_session_data *sd,struct guild_storage *stor,struct item *item_data,int amount);
-int guild_storage_delitem(struct map_session_data *sd,struct guild_storage *stor,int n,int amount);
-int storage_guild_storageadd(struct map_session_data *sd,int index,int amount);
-int storage_guild_storageget(struct map_session_data *sd,int index,int amount);
-int storage_guild_storageaddfromcart(struct map_session_data *sd,int index,int amount);
-int storage_guild_storagegettocart(struct map_session_data *sd,int index,int amount);
-int storage_guild_storageclose(struct map_session_data *sd);
-int storage_guild_storage_quit(struct map_session_data *sd,int flag);
-int storage_guild_storagesave(int account_id, int guild_id, int flag);
-int storage_guild_storagesaved(int guild_id); //Ack from char server that guild store was saved.
+struct guild_storage_interface {
+ struct DBMap* db; // int guild_id -> struct guild_storage*
+ /* */
+ struct guild_storage *(*id2storage) (int guild_id);
+ struct guild_storage *(*id2storage2) (int guild_id);
+ int (*delete) (int guild_id);
+ int (*open) (struct map_session_data *sd);
+ int (*additem) (struct map_session_data *sd,struct guild_storage *stor,struct item *item_data,int amount);
+ int (*delitem) (struct map_session_data *sd,struct guild_storage *stor,int n,int amount);
+ int (*add) (struct map_session_data *sd,int index,int amount);
+ int (*get) (struct map_session_data *sd,int index,int amount);
+ int (*addfromcart) (struct map_session_data *sd,int index,int amount);
+ int (*gettocart) (struct map_session_data *sd,int index,int amount);
+ int (*close) (struct map_session_data *sd);
+ int (*pc_quit) (struct map_session_data *sd,int flag);
+ int (*save) (int account_id, int guild_id, int flag);
+ int (*saved) (int guild_id); //Ack from char server that guild store was saved.
+} gstorage_s;
+
+struct guild_storage_interface *gstorage;
+
+void storage_defaults(void);
+void gstorage_defaults(void);
#endif /* _STORAGE_H_ */
diff --git a/src/map/trade.c b/src/map/trade.c
index f469f4b28..c44f04884 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -206,13 +206,13 @@ int impossible_trade_check(struct map_session_data *sd)
intif_wis_message_to_gm(iMap->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, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block
set_eof(sd->fd); // forced to disconnect because of the hack
// message about the ban
strcpy(message_to_gm, msg_txt(540)); // 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, 2, 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).
@@ -257,7 +257,7 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
if (amount > inventory[n].amount)
return 0; //qty Exploit?
- data = itemdb_search(inventory[n].nameid);
+ data = itemdb->search(inventory[n].nameid);
i = MAX_INVENTORY;
if (itemdb_isstackable2(data)) { //Stackable item.
for(i = 0; i < MAX_INVENTORY; i++)
@@ -288,7 +288,7 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd)
if (amount > inventory2[n].amount)
return 0;
// search if it's possible to add item (for full inventory)
- data = itemdb_search(inventory2[n].nameid);
+ data = itemdb->search(inventory2[n].nameid);
i = MAX_INVENTORY;
if (itemdb_isstackable2(data)) {
for(i = 0; i < MAX_INVENTORY; i++)
@@ -603,8 +603,8 @@ void trade_tradecommit(struct map_session_data *sd)
// save both player to avoid crash: they always have no advantage/disadvantage between the 2 players
if (iMap->save_settings&1)
{
- chrif_save(sd,0);
- chrif_save(tsd,0);
+ chrif->save(sd,0);
+ chrif->save(tsd,0);
}
}
@@ -621,4 +621,4 @@ void trade_defaults(void)
trade->ok = trade_tradeok;
trade->cancel = trade_tradecancel;
trade->commit = trade_tradecommit;
-} \ No newline at end of file
+}
diff --git a/src/map/trade.h b/src/map/trade.h
index f66c70525..8bf918ad2 100644
--- a/src/map/trade.h
+++ b/src/map/trade.h
@@ -1,10 +1,10 @@
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see LICENCE in the main folder
+// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// See the LICENSE file
+// Portions Copyright (c) Athena Dev Teams
#ifndef _TRADE_H_
#define _TRADE_H_
-//#include "map.h"
struct map_session_data;
struct trade_interface {
@@ -20,6 +20,7 @@ struct trade_interface {
} trade_s;
struct trade_interface *trade;
+
void trade_defaults(void);
#endif /* _TRADE_H_ */
diff --git a/src/map/unit.c b/src/map/unit.c
index 021859bba..5e836dc2e 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -2108,9 +2108,9 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
buyingstore->close(sd);
searchstore->close(sd);
if(sd->state.storage_flag == 1)
- storage_storage_quit(sd,0);
+ storage->pc_quit(sd,0);
else if (sd->state.storage_flag == 2)
- storage_guild_storage_quit(sd,0);
+ gstorage->pc_quit(sd,0);
sd->state.storage_flag = 0; //Force close it when being warped.
if(sd->party_invite>0)
party->reply_invite(sd,sd->party_invite,0);
diff --git a/src/map/vending.c b/src/map/vending.c
index b9575c8dd..898008a3a 100644
--- a/src/map/vending.c
+++ b/src/map/vending.c
@@ -198,8 +198,8 @@ void vending_purchasereq(struct map_session_data* sd, int aid, unsigned int uid,
//Always save BOTH: buyer and customer
if( iMap->save_settings&2 ) {
- chrif_save(sd,0);
- chrif_save(vsd,0);
+ chrif->save(sd,0);
+ chrif->save(vsd,0);
}
//check for @AUTOTRADE users [durf]
diff --git a/src/plugins/db2sql.c b/src/plugins/db2sql.c
index 723a3cc94..8db4a006f 100644
--- a/src/plugins/db2sql.c
+++ b/src/plugins/db2sql.c
@@ -17,7 +17,7 @@
HPExport struct hplugin_info pinfo = {
"DB2SQL", // Plugin name
SERVER_TYPE_MAP,// Which server types this plugin works with?
- "0.1", // Plugin version
+ "0.4", // Plugin version
HPM_VERSION, // HPM Version (don't change, macro is automatically updated)
};
@@ -55,10 +55,10 @@ int db2sql(char** str, const char* source, int line, int scriptopt) {
/* renewal has the 'matk' and 'equip_level' is now 'equip_level_min', and there is a new 'equip_level_max' field */
#ifdef RENEWAL
if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "REPLACE INTO `%s` (`id`,`name_english`,`name_japanese`,`type`,`price_buy`,`price_sell`,`weight`,`atk`,`matk`,`defence`,`range`,`slots`,`equip_jobs`,`equip_upper`,`equip_genders`,`equip_locations`,`weapon_level`,`equip_level_min`,`equip_level_max`,`refineable`,`view`,`script`,`equip_script`,`unequip_script`) VALUES ('%u',?,?,'%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u',?,?,?)",iMap->item_db_re_db,
- it->nameid,it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->matk,it->def,it->range,it->slot,(unsigned int)strtoul(str[11+offset],NULL,0),atoi(str[12+offset]),atoi(str[13+offset]),atoi(str[14+offset]),it->wlv,it->elv,it->elvmax,atoi(str[17+offset]),it->look) )
+ it->nameid,it->flag.delay_consume?IT_DELAYCONSUME:it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->matk,it->def,it->range,it->slot,(unsigned int)strtoul(str[11+offset],NULL,0),atoi(str[12+offset]),atoi(str[13+offset]),atoi(str[14+offset]),it->wlv,it->elv,it->elvmax,atoi(str[17+offset]),it->look) )
#else
if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "REPLACE INTO `%s` (`id`,`name_english`,`name_japanese`,`type`,`price_buy`,`price_sell`,`weight`,`atk`,`defence`,`range`,`slots`,`equip_jobs`,`equip_upper`,`equip_genders`,`equip_locations`,`weapon_level`,`equip_level`,`refineable`,`view`,`script`,`equip_script`,`unequip_script`) VALUES ('%u',?,?,'%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u',?,?,?)",iMap->item_db_db,
- it->nameid,it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->def,it->range,it->slot,(unsigned int)strtoul(str[11],NULL,0),atoi(str[12]),atoi(str[13]),atoi(str[14]),it->wlv,it->elv,atoi(str[17]),it->look) )
+ it->nameid,it->flag.delay_consume?IT_DELAYCONSUME:it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->def,it->range,it->slot,(unsigned int)strtoul(str[11],NULL,0),atoi(str[12]),atoi(str[13]),atoi(str[14]),it->wlv,it->elv,atoi(str[17]),it->look) )
#endif
SqlStmt_ShowDebug(stmt);
else {
@@ -98,6 +98,11 @@ int db2sql(char** str, const char* source, int line, int scriptopt) {
CPCMD(db2sql) {
+ if( iMap->db_use_sqldbs ) {
+ ShowInfo("db2sql: this should not be used with 'db_use_sqldbs' enabled, skipping...\n");
+ return;
+ }
+
stmt = SQL->StmtMalloc(mysql_handle);
if( stmt == NULL ) {
SqlStmt_ShowDebug(stmt);
@@ -107,9 +112,12 @@ CPCMD(db2sql) {
/* link */
parse_dbrow = itemdb->parse_dbrow;
itemdb->parse_dbrow = db2sql;
-
/* empty table */
+#ifdef RENEWAL
+ if ( SQL_ERROR == SQL->Query(mysql_handle, "DELETE FROM `%s`", iMap->item_db_re_db ) )
+#else
if ( SQL_ERROR == SQL->Query(mysql_handle, "DELETE FROM `%s`", iMap->item_db_db) )
+#endif
Sql_ShowDebug(mysql_handle);
else {
itemdb->reload();