diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/mmo.h | 7 | ||||
-rw-r--r-- | src/config/const.h | 7 | ||||
-rw-r--r-- | src/map/atcommand.c | 27 | ||||
-rw-r--r-- | src/map/battle.c | 28 | ||||
-rw-r--r-- | src/map/clif.c | 59 | ||||
-rw-r--r-- | src/map/intif.c | 4 | ||||
-rw-r--r-- | src/map/mail.c | 26 | ||||
-rw-r--r-- | src/map/mail.h | 29 | ||||
-rw-r--r-- | src/map/map.c | 4 | ||||
-rw-r--r-- | src/map/npc.c | 3 | ||||
-rw-r--r-- | src/map/pc.c | 12 | ||||
-rw-r--r-- | src/map/pc.h | 2 | ||||
-rw-r--r-- | src/map/script.c | 191 | ||||
-rw-r--r-- | src/map/script.h | 12 | ||||
-rw-r--r-- | src/map/skill.c | 19 | ||||
-rw-r--r-- | src/map/status.c | 18 | ||||
-rw-r--r-- | src/map/status.h | 2 | ||||
-rw-r--r-- | src/map/trade.c | 35 | ||||
-rw-r--r-- | src/map/trade.h | 21 | ||||
-rw-r--r-- | src/map/unit.c | 2 |
20 files changed, 306 insertions, 202 deletions
diff --git a/src/common/mmo.h b/src/common/mmo.h index eaffdf7df..8643d2b54 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -54,6 +54,13 @@ // Comment the following line if your client is NOT ragexeRE (required because of conflicting packets in ragexe vs ragexeRE). #define PACKETVER_RE +// Client support for experimental RagexeRE UI present in 2012-04-10 and 2012-04-18 +#ifdef PACKETVER_RE +#if (PACKETVER == 20120410) || (PACKETVER == 20120418) + #define PARTY_RECRUIT +#endif +#endif + // Comment the following line to disable sc_data saving. [Skotlex] #define ENABLE_SC_SAVING diff --git a/src/config/const.h b/src/config/const.h index f4a2821f8..d8e397b1e 100644 --- a/src/config/const.h +++ b/src/config/const.h @@ -92,12 +92,7 @@ #else #define MAX_CARTS 5 #endif -/* Client Supports Party Recruit or Party Booking? */ -#ifdef PACKETVER_RE -#if (PACKETVER == 20120410) || (PACKETVER == 20120418) - #define PARTY_RECRUIT -#endif -#endif + // Renewal variable cast time reduction #ifdef RENEWAL_CAST #define VARCAST_REDUCTION(val){ \ diff --git a/src/map/atcommand.c b/src/map/atcommand.c index d9810e77c..b6a9e42ee 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -3718,10 +3718,33 @@ ACMD(reloadpcdb) *------------------------------------------*/ ACMD(reloadscript) { + struct s_mapiterator* iter; + struct map_session_data* pl_sd; + nullpo_retr(-1, sd); //atcommand_broadcast( fd, sd, "@broadcast", "Server is reloading scripts..." ); //atcommand_broadcast( fd, sd, "@broadcast", "You will feel a bit of lag at this point !" ); + iter = mapit_getallusers(); + for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) { + if (pl_sd->npc_id || pl_sd->npc_shopid) { + if (pl_sd->state.using_fake_npc) { + clif->clearunit_single(pl_sd->npc_id, CLR_OUTSIGHT, pl_sd->fd); + pl_sd->state.using_fake_npc = 0; + } + if (pl_sd->state.menu_or_input) + pl_sd->state.menu_or_input = 0; + if (pl_sd->npc_menu) + pl_sd->npc_menu = 0; + + pl_sd->npc_id = 0; + pl_sd->npc_shopid = 0; + if (pl_sd->st && pl_sd->st->state != END) + pl_sd->st->state = END; + } + } + mapit->free(iter); + flush_fifos(); iMap->reloadnpc(true); // reload config files seeking for npcs script_reload(); @@ -6397,7 +6420,7 @@ ACMD(trade) return false; } - trade_traderequest(sd, pl_sd); + trade->request(sd, pl_sd); return true; } @@ -6601,7 +6624,7 @@ ACMD(misceffect) { ACMD(mail) { nullpo_ret(sd); - mail_openmail(sd); + mail->openmail(sd); return true; } diff --git a/src/map/battle.c b/src/map/battle.c index 31fe502f6..ace947aca 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -753,8 +753,8 @@ int battle_calc_masteryfix(struct block_list *src, struct block_list *target, ui int ratio = sd->status.base_level + status_get_dex(src) + status_get_luk(src); if ( i == 2 ) ratio += status_get_str(src); //Star Anger if (skill < 4 ) - ratio /= 12 - 3 * skill; - damage += damage * ratio; + ratio /= (12 - 3 * skill); + damage += damage * ratio / 100; } if( sc ){ @@ -4345,15 +4345,11 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list wd.damage = sstatus->max_hp* 9/100; wd.damage2 = 0; break; - -#ifdef RENEWAL - 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); - // first value is still not confirm. - wd.damage = status_get_sp(src) + 10 * status_get_sp(src) * wd.damage / 100 + 8 * wd.damage; - flag.tdef = 1; - break; case NJ_ISSEN: // [malufett] +#ifndef RENEWAL + wd.damage = 40*sstatus->str +skill_lv*(sstatus->hp/10 + 35); + wd.damage2 = 0; +#else { short totaldef = status_get_total_def(target); i = 0; @@ -4367,12 +4363,14 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list ATK_RATE(50); flag.idef = 1; } -#else - - wd.damage = 40*sstatus->str +skill_lv*(sstatus->hp/10 + 35); - wd.damage2 = 0; -#endif 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); + // first value is still not confirm. + wd.damage = status_get_sp(src) + 10 * status_get_sp(src) * wd.damage / 100 + 8 * wd.damage; + flag.tdef = 1; +#endif + break; #ifndef RENEWAL case LK_SPIRALPIERCE: case ML_SPIRALPIERCE: diff --git a/src/map/clif.c b/src/map/clif.c index 2feb6f4bf..73d4b6666 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -5964,12 +5964,13 @@ void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len) safestrncpy((char*)WFIFOP(fd,28), mes, mes_len); WFIFOSET(fd,WFIFOW(fd,2)); #else + struct map_session_data *ssd = iMap->nick2sd(nick); + WFIFOHEAD(fd, mes_len + NAME_LENGTH + 8); WFIFOW(fd,0) = 0x97; WFIFOW(fd,2) = mes_len + NAME_LENGTH + 8; safestrncpy((char*)WFIFOP(fd,4), nick, NAME_LENGTH); - WFIFOL(fd,28) = 0; // isAdmin; if nonzero, also displays text above char - // TODO: WFIFOL(fd,28) = pc->get_group_level(ssd); + WFIFOL(fd,28) = (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 @@ -8560,7 +8561,7 @@ void clif_refresh(struct map_session_data *sd) // unlike vending, resuming buyingstore crashes the client. buyingstore->close(sd); - mail_clear(sd); + mail->clear(sd); if( disguised(&sd->bl) ) {/* refresh-da */ short disguise = sd->disguise; @@ -9601,7 +9602,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) } } - mail_clear(sd); + mail->clear(sd); clif->maptypeproperty2(&sd->bl,SELF); @@ -9756,7 +9757,7 @@ void clif_parse_progressbar(int fd, struct map_session_data * sd) if( iTimer->gettick() < sd->progressbar.timeout && sd->st ) sd->st->state = END; - sd->progressbar.npc_id = sd->progressbar.timeout = 0; + sd->state.workinprogress = sd->progressbar.npc_id = sd->progressbar.timeout = 0; npc_scriptcont(sd, npc_id, false); } @@ -9776,8 +9777,8 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd) if (sd->sc.opt1 && ( sd->sc.opt1 == OPT1_STONEWAIT || sd->sc.opt1 == OPT1_BURNING )) ; //You CAN walk on this OPT1 value. - else if( sd->progressbar.npc_id ) - clif->progressbar_abort(sd); + /*else if( sd->progressbar.npc_id ) + clif->progressbar_abort(sd);*/ else if (pc_cant_act(sd)) return; @@ -10572,7 +10573,7 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd) if (pc_isdead(sd)) break; - if ( pc_cant_act2(sd) ) + if ( pc_cant_act2(sd) || sd->state.vending ) break; if (sd->sc.count && ( @@ -10794,7 +10795,7 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd) #endif return; } - if ( pc_cant_act2(sd) || !(bl = iMap->id2bl(RFIFOL(fd,2))) ) + if ( pc_cant_act2(sd) || !(bl = iMap->id2bl(RFIFOL(fd,2))) || sd->state.vending ) return; switch (bl->type) { @@ -11041,7 +11042,7 @@ void clif_parse_TradeRequest(int fd,struct map_session_data *sd) return; } - trade_traderequest(sd,t_sd); + trade->request(sd,t_sd); } @@ -11052,7 +11053,7 @@ void clif_parse_TradeRequest(int fd,struct map_session_data *sd) /// 4 = rejected void clif_parse_TradeAck(int fd,struct map_session_data *sd) { - trade_tradeack(sd,RFIFOB(fd,2)); + trade->ack(sd,RFIFOB(fd,2)); } @@ -11064,9 +11065,9 @@ void clif_parse_TradeAddItem(int fd,struct map_session_data *sd) int amount = RFIFOL(fd,4); if( index == 0 ) - trade_tradeaddzeny(sd, amount); + trade->addzeny(sd, amount); else - trade_tradeadditem(sd, index, (short)amount); + trade->additem(sd, index, (short)amount); } @@ -11074,7 +11075,7 @@ void clif_parse_TradeAddItem(int fd,struct map_session_data *sd) /// 00eb void clif_parse_TradeOk(int fd,struct map_session_data *sd) { - trade_tradeok(sd); + trade->ok(sd); } @@ -11082,7 +11083,7 @@ void clif_parse_TradeOk(int fd,struct map_session_data *sd) /// 00ed void clif_parse_TradeCancel(int fd,struct map_session_data *sd) { - trade_tradecancel(sd); + trade->cancel(sd); } @@ -11090,7 +11091,7 @@ void clif_parse_TradeCancel(int fd,struct map_session_data *sd) /// 00ef void clif_parse_TradeCommit(int fd,struct map_session_data *sd) { - trade_tradecommit(sd); + trade->commit(sd); } @@ -14471,8 +14472,8 @@ void clif_parse_Mail_refreshinbox(int fd, struct map_session_data *sd) else clif->mail_refreshinbox(sd); - mail_removeitem(sd, 0); - mail_removezeny(sd, 0); + mail->removeitem(sd, 0); + mail->removezeny(sd, 0); } @@ -14546,7 +14547,7 @@ void clif_parse_Mail_read(int fd, struct map_session_data *sd) if( mail_id <= 0 ) return; - if( mail_invalid_operation(sd) ) + if( mail->invalid_operation(sd) ) return; clif->mail_read(sd, RFIFOL(fd,2)); @@ -14565,7 +14566,7 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd) return; if( mail_id <= 0 ) return; - if( mail_invalid_operation(sd) ) + if( mail->invalid_operation(sd) ) return; ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id); @@ -14626,7 +14627,7 @@ void clif_parse_Mail_delete(int fd, struct map_session_data *sd) return; if( mail_id <= 0 ) return; - if( mail_invalid_operation(sd) ) + if( mail->invalid_operation(sd) ) return; ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id); @@ -14652,7 +14653,7 @@ void clif_parse_Mail_return(int fd, struct map_session_data *sd) if( mail_id <= 0 ) return; - if( mail_invalid_operation(sd) ) + if( mail->invalid_operation(sd) ) return; ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id); @@ -14676,7 +14677,7 @@ void clif_parse_Mail_setattach(int fd, struct map_session_data *sd) if (idx < 0 || amount < 0) return; - flag = mail_setitem(sd, idx, amount); + flag = mail->setitem(sd, idx, amount); clif->mail_setattachment(fd,idx,flag); } @@ -14692,9 +14693,9 @@ void clif_parse_Mail_winopen(int fd, struct map_session_data *sd) int flag = RFIFOW(fd,2); if (flag == 0 || flag == 1) - mail_removeitem(sd, 0); + mail->removeitem(sd, 0); if (flag == 0 || flag == 2) - mail_removezeny(sd, 0); + mail->removezeny(sd, 0); } @@ -14726,10 +14727,10 @@ void clif_parse_Mail_send(int fd, struct map_session_data *sd) if (body_len > MAIL_BODY_LENGTH) body_len = MAIL_BODY_LENGTH; - if( !mail_setattachment(sd, &msg) ) { // Invalid Append condition + if( !mail->setattachment(sd, &msg) ) { // Invalid Append condition clif->mail_send(sd->fd, true); // fail - mail_removeitem(sd,0); - mail_removezeny(sd,0); + mail->removeitem(sd,0); + mail->removezeny(sd,0); return; } @@ -14751,7 +14752,7 @@ void clif_parse_Mail_send(int fd, struct map_session_data *sd) msg.timestamp = time(NULL); if( !intif_Mail_send(sd->status.account_id, &msg) ) - mail_deliveryfail(sd, &msg); + mail->deliveryfail(sd, &msg); sd->cansendmail_tick = iTimer->gettick() + 1000; // 1 Second flood Protection } diff --git a/src/map/intif.c b/src/map/intif.c index 3cdf93487..f3931e79e 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -1582,7 +1582,7 @@ int intif_parse_Mail_getattach(int fd) memcpy(&item, RFIFOP(fd,12), sizeof(struct item)); - mail_getattachment(sd, zeny, &item); + mail->getattachment(sd, zeny, &item); return 0; } /*------------------------------------------ @@ -1718,7 +1718,7 @@ static void intif_parse_Mail_send(int fd) if( sd != NULL ) { if( fail ) - mail_deliveryfail(sd, &msg); + mail->deliveryfail(sd, &msg); else { clif->mail_send(sd->fd, false); diff --git a/src/map/mail.c b/src/map/mail.c index 299fb5117..9a8d4e521 100644 --- a/src/map/mail.c +++ b/src/map/mail.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/nullpo.h" #include "../common/showmsg.h" @@ -72,7 +73,7 @@ unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount) { return 0; } else { // Item Transfer idx -= 2; - mail_removeitem(sd, 0); + mail->removeitem(sd, 0); if( idx < 0 || idx >= MAX_INVENTORY ) return 1; @@ -121,8 +122,8 @@ bool mail_setattachment(struct map_session_data *sd, struct mail_message *msg) msg->zeny = sd->mail.zeny; // Removes the attachment from sender - mail_removeitem(sd,1); - mail_removezeny(sd,1); + mail->removeitem(sd,1); + mail->removezeny(sd,1); return true; } @@ -183,3 +184,18 @@ bool mail_invalid_operation(struct map_session_data *sd) return false; } + +void mail_defaults(void) +{ + mail = &mail_s; + + mail->clear = mail_clear; + mail->removeitem = mail_removeitem; + mail->removezeny = mail_removezeny; + mail->setitem = mail_setitem; + mail->setattachment = mail_setattachment; + mail->getattachment = mail_getattachment; + mail->openmail = mail_openmail; + mail->deliveryfail = mail_deliveryfail; + mail->invalid_operation = mail_invalid_operation; +}
\ No newline at end of file diff --git a/src/map/mail.h b/src/map/mail.h index cab582e55..99742c7bd 100644 --- a/src/map/mail.h +++ b/src/map/mail.h @@ -1,19 +1,26 @@ -// 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 _MAIL_H_ #define _MAIL_H_ #include "../common/mmo.h" -void mail_clear(struct map_session_data *sd); -int mail_removeitem(struct map_session_data *sd, short flag); -int mail_removezeny(struct map_session_data *sd, short flag); -unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount); -bool mail_setattachment(struct map_session_data *sd, struct mail_message *msg); -void mail_getattachment(struct map_session_data* sd, int zeny, struct item* item); -int mail_openmail(struct map_session_data *sd); -void mail_deliveryfail(struct map_session_data *sd, struct mail_message *msg); -bool mail_invalid_operation(struct map_session_data *sd); +struct mail_interface { + void (*clear) (struct map_session_data *sd); + int (*removeitem) (struct map_session_data *sd, short flag); + int (*removezeny) (struct map_session_data *sd, short flag); + unsigned char (*setitem) (struct map_session_data *sd, int idx, int amount); + bool (*setattachment) (struct map_session_data *sd, struct mail_message *msg); + void (*getattachment) (struct map_session_data* sd, int zeny, struct item* item); + int (*openmail) (struct map_session_data *sd); + void (*deliveryfail) (struct map_session_data *sd, struct mail_message *msg); + bool (*invalid_operation) (struct map_session_data *sd); +} mail_s; + +struct mail_interface *mail; + +void mail_defaults(void); #endif /* _MAIL_H_ */ diff --git a/src/map/map.c b/src/map/map.c index 5dbedebb6..5f86286e9 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -5239,12 +5239,14 @@ void map_hp_symbols(void) { HPM->share(ircbot,"ircbot"); HPM->share(itemdb,"itemdb"); HPM->share(logs,"logs"); + HPM->share(mail,"mail"); HPM->share(script,"script"); HPM->share(searchstore,"searchstore"); HPM->share(skill,"skill"); HPM->share(vending,"vending"); HPM->share(pc,"pc"); HPM->share(party,"party"); + HPM->share(trade,"trade"); HPM->share(iMap,"iMap"); /* partial */ HPM->share(mapit,"mapit"); @@ -5269,6 +5271,7 @@ void load_defaults(void) { ircbot_defaults(); itemdb_defaults(); log_defaults(); + mail_defaults(); npc_defaults(); script_defaults(); searchstore_defaults(); @@ -5276,6 +5279,7 @@ void load_defaults(void) { vending_defaults(); pc_defaults(); party_defaults(); + trade_defaults(); } int do_init(int argc, char *argv[]) { diff --git a/src/map/npc.c b/src/map/npc.c index f4027096c..46e6d0fd2 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1867,6 +1867,7 @@ int npc_unload(struct npc_data* nd, bool single) { aFree(nd->u.scr.timer_event); if (nd->src_id == 0) { if(nd->u.scr.script) { + script_stop_instances(nd->bl.id); script_free_code(nd->u.scr.script); nd->u.scr.script = NULL; } @@ -1885,8 +1886,6 @@ int npc_unload(struct npc_data* nd, bool single) { nd->ud = NULL; } - script_stop_sleeptimers(nd->bl.id); - aFree(nd); return 0; diff --git a/src/map/pc.c b/src/map/pc.c index 155812836..b7644f2fb 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4255,7 +4255,7 @@ int pc_useitem(struct map_session_data *sd,int n) nullpo_ret(sd); - if( sd->npc_id ){ + if( sd->npc_id || sd->state.workinprogress&1 ){ /* TODO: add to clif->messages enum */ #ifdef RENEWAL clif->msg(sd, 0x783); // TODO look for the client date that has this message. @@ -4295,8 +4295,8 @@ int pc_useitem(struct map_session_data *sd,int n) return 0; /* Items with delayed consume are not meant to work while in mounts except reins of mount(12622) */ - if( sd->inventory_data[n]->flag.delay_consume ) { - if( nameid != ITEMID_REINS_OF_MOUNT && sd->sc.data[SC_ALL_RIDING] ) + if( sd->inventory_data[n]->flag.delay_consume && nameid != ITEMID_REINS_OF_MOUNT ) { + if( sd->sc.data[SC_ALL_RIDING] ) return 0; else if( pc_issit(sd) ) return 0; @@ -4323,7 +4323,8 @@ int pc_useitem(struct map_session_data *sd,int n) } else {// not yet used item (all slots are initially empty) sd->item_delay[i].nameid = nameid; } - sd->item_delay[i].tick = tick + sd->inventory_data[n]->delay; + if( !(nameid == ITEMID_REINS_OF_MOUNT && sd->sc.option&(OPTION_WUGRIDER|OPTION_RIDING|OPTION_DRAGON|OPTION_MADOGEAR)) ) + sd->item_delay[i].tick = tick + sd->inventory_data[n]->delay; } else {// should not happen ShowError("pc_useitem: Exceeded item delay array capacity! (nameid=%d, char_id=%d)\n", nameid, sd->status.char_id); } @@ -6667,7 +6668,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { npc_script_event(sd,NPCE_DIE); // Clear anything NPC-related when you die and was interacting with one. - if (sd->npc_id) { + if (sd->npc_id || sd->npc_shopid) { if (sd->state.using_fake_npc) { clif->clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd); sd->state.using_fake_npc = 0; @@ -6678,6 +6679,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { sd->npc_menu = 0; sd->npc_id = 0; + sd->npc_shopid = 0; if (sd->st && sd->st->state != END) sd->st->state = END; } diff --git a/src/map/pc.h b/src/map/pc.h index 5c585af1c..43d5d40c7 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -603,7 +603,7 @@ enum equip_pos { #define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chatID || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend ) /* equals pc_cant_act except it doesn't check for chat rooms */ -#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend ) +#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend ) #define pc_setdir(sd,b,h) ( (sd)->ud.dir = (b) ,(sd)->head_dir = (h) ) #define pc_setchatid(sd,n) ( (sd)->chatID = n ) diff --git a/src/map/script.c b/src/map/script.c index f3bf2470a..682faa42b 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -181,8 +181,6 @@ int potion_target=0; c_op get_com(unsigned char *script,int *pos); int get_num(unsigned char *script,int *pos); -static struct linkdb_node* sleep_db;// int oid -> struct script_state* - /*========================================== * (Only those needed) local declaration prototype *------------------------------------------*/ @@ -2746,19 +2744,18 @@ void script_free_code(struct script_code* code) /// @param rid Who is running the script (attached player) /// @param oid Where the code is being run (npc 'object') /// @return Script state -struct script_state* script_alloc_state(struct script_code* script, int pos, int rid, int oid) -{ +struct script_state* script_alloc_state(struct script_code* rootscript, int pos, int rid, int oid) { struct script_state* st; - CREATE(st, struct script_state, 1); - st->stack = (struct script_stack*)aMalloc(sizeof(struct script_stack)); + + st = ers_alloc(script->st_ers, struct script_state); + st->stack = ers_alloc(script->stack_ers, struct script_stack); st->stack->sp = 0; st->stack->sp_max = 64; CREATE(st->stack->stack_data, struct script_data, st->stack->sp_max); st->stack->defsp = st->stack->sp; st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA); st->state = RUN; - st->script = script; - //st->scriptroot = script; + st->script = rootscript; st->pos = pos; st->rid = rid; st->oid = oid; @@ -2768,6 +2765,11 @@ struct script_state* script_alloc_state(struct script_code* script, int pos, int if( !st->script->script_vars ) st->script->script_vars = idb_alloc(DB_OPT_RELEASE_DATA); + st->id = script->next_id++; + script->active_scripts++; + + idb_put(script->st_db, st->id, st); + return st; } @@ -2785,14 +2787,18 @@ void script_free_state(struct script_state* st) script_free_vars(st->stack->var_function); script->pop_stack(st, 0, st->stack->sp); aFree(st->stack->stack_data); - aFree(st->stack); + 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; - aFree(st); + idb_remove(script->st_db, st->id); + ers_free(script->st_ers, st); + if( --script->active_scripts == 0 ) { + script->next_id = 0; + } } // @@ -3270,60 +3276,36 @@ void run_script(struct script_code *rootscript,int pos,int rid,int oid) { run_script_main(st); } -void script_stop_sleeptimers(int id) -{ +void script_stop_instances(int id) { + DBIterator *iter; struct script_state* st; - for(;;) - { - st = (struct script_state*)linkdb_erase(&sleep_db,(void*)__64BPTRSIZE(id)); - if( st == NULL ) - break; // no more sleep timers - script_free_state(st); + + if( !script->active_scripts ) + return;//dont even bother. + + iter = db_iterator(script->st_db); + + for( st = dbi_first(iter); dbi_exists(iter); st = dbi_next(iter) ) { + if( st->oid == id ) { + script_free_state(st); + } } -} - -/*========================================== - * Delete the specified node from sleep_db - *------------------------------------------*/ -struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n) -{ - struct linkdb_node *retnode; - - if( n == NULL) - return NULL; - if( n->prev == NULL ) - sleep_db = n->next; - else - n->prev->next = n->next; - if( n->next ) - n->next->prev = n->prev; - retnode = n->next; - aFree( n ); - return retnode; // The following; return retnode + + dbi_destroy(iter); } /*========================================== * Timer function for sleep *------------------------------------------*/ -int run_script_timer(int tid, unsigned int tick, int id, intptr_t data) -{ +int run_script_timer(int tid, unsigned int tick, int id, intptr_t data) { struct script_state *st = (struct script_state *)data; - struct linkdb_node *node = (struct linkdb_node *)sleep_db; TBL_PC *sd = iMap->id2sd(st->rid); - if((sd && sd->status.char_id != id) || (st->rid && !sd)) - { //Character mismatch. Cancel execution. + if((sd && sd->status.char_id != id) || (st->rid && !sd)) { //Character mismatch. Cancel execution. st->rid = 0; st->state = END; } - while( node && st->sleep.timer != INVALID_TIMER ) { - if( (int)__64BPTRSIZE(node->key) == st->oid && ((struct script_state *)node->data)->sleep.timer == st->sleep.timer ) { - script_erase_sleepdb(node); - st->sleep.timer = INVALID_TIMER; - break; - } - node = node->next; - } + st->sleep.timer = INVALID_TIMER; if(st->state != RERUNLINE) st->sleep.tick = 0; run_script_main(st); @@ -3523,9 +3505,7 @@ void run_script_main(struct script_state *st) st->sleep.charid = sd?sd->status.char_id:0; st->sleep.timer = iTimer->add_timer(iTimer->gettick()+st->sleep.tick, run_script_timer, st->sleep.charid, (intptr_t)st); - linkdb_insert(&sleep_db, (void*)__64BPTRSIZE(st->oid), st); - } - else if(st->state != END && st->rid){ + } else if(st->state != END && st->rid){ //Resume later (st is already attached to player). if(st->bk_st) { ShowWarning("Unable to restore stack! Double continuation!\n"); @@ -3711,6 +3691,9 @@ void script_setarray_pc(struct map_session_data* sd, const char* varname, uint8 *------------------------------------------*/ void do_final_script(void) { int i; + DBIterator *iter; + struct script_state *st; + #ifdef DEBUG_HASH if (battle_config.etc_log) { @@ -3771,16 +3754,15 @@ void do_final_script(void) { db_destroy(scriptlabel_db); userfunc_db->destroy(userfunc_db, db_script_free_code_sub); autobonus_db->destroy(autobonus_db, db_script_free_code_sub); - if(sleep_db) { - struct linkdb_node *n = (struct linkdb_node *)sleep_db; - while(n) { - struct script_state *st = (struct script_state *)n->data; - script_free_state(st); - n = n->next; - } - linkdb_final(&sleep_db); - } + iter = db_iterator(script->st_db); + + for( st = dbi_first(iter); dbi_exists(iter); st = dbi_next(iter) ) { + script_free_state(st); + } + + dbi_destroy(iter); + if (script->str_data) aFree(script->str_data); if (script->str_buf) @@ -3820,14 +3802,27 @@ void do_final_script(void) { aFree(script->hqi); if( script->word_buf != NULL ) aFree(script->word_buf); + + ers_destroy(script->st_ers); + ers_destroy(script->stack_ers); + + db_destroy(script->st_db); } /*========================================== * Initialization *------------------------------------------*/ void do_init_script(void) { + script->st_db = idb_alloc(DB_OPT_BASE); userfunc_db = strdb_alloc(DB_OPT_DUP_KEY,0); scriptlabel_db = strdb_alloc(DB_OPT_DUP_KEY,50); autobonus_db = strdb_alloc(DB_OPT_DUP_KEY,0); + + script->st_ers = ers_new(sizeof(struct script_state), "script.c::st_ers", ERS_OPT_NONE); + script->stack_ers = ers_new(sizeof(struct script_stack), "script.c::script_stack", ERS_OPT_NONE); + + ers_chunk_size(script->st_ers, 10); + ers_chunk_size(script->stack_ers, 10); + script->parse_builtin(); read_constdb(); mapreg_init(); @@ -3835,6 +3830,8 @@ void do_init_script(void) { int script_reload() { int i; + DBIterator *iter; + struct script_state *st; userfunc_db->clear(userfunc_db, db_script_free_code_sub); db_clear(scriptlabel_db); @@ -3848,15 +3845,16 @@ int script_reload() { atcommand->binding_count = 0; - if(sleep_db) { - struct linkdb_node *n = (struct linkdb_node *)sleep_db; - while(n) { - struct script_state *st = (struct script_state *)n->data; - script_free_state(st); - n = n->next; - } - linkdb_final(&sleep_db); + iter = db_iterator(script->st_db); + + for( st = dbi_first(iter); dbi_exists(iter); st = dbi_next(iter) ) { + script_free_state(st); } + + dbi_destroy(iter); + + db_clear(script->st_db); + mapreg_reload(); return 0; } @@ -7225,6 +7223,9 @@ BUILDIN(successrefitem) //Logs items, got from (N)PC scripts [Lupus] logs->pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i],sd->inventory_data[i]); + if (sd->status.inventory[i].refine >= MAX_REFINE) + return true; + sd->status.inventory[i].refine++; pc->unequipitem(sd,i,2); // status calc will happen in pc->equipitem() below @@ -15134,47 +15135,41 @@ BUILDIN(sleep2) /// Awakes all the sleep timers of the target npc /// /// awake "<npc name>"; -BUILDIN(awake) -{ +BUILDIN(awake) { + DBIterator *iter; + struct script_state *tst; struct npc_data* nd; - struct linkdb_node *node = (struct linkdb_node *)sleep_db; - nd = npc_name2id(script_getstr(st, 2)); - if( nd == NULL ) { + if( ( nd = npc_name2id(script_getstr(st, 2)) ) == NULL ) { ShowError("awake: NPC \"%s\" not found\n", script_getstr(st, 2)); return false; } - while( node ) - { - if( (int)__64BPTRSIZE(node->key) == nd->bl.id ) - {// sleep timer for the npc - struct script_state* tst = (struct script_state*)node->data; + iter = db_iterator(script->st_db); + + for( tst = dbi_first(iter); dbi_exists(iter); tst = dbi_next(iter) ) { + if( tst->oid == nd->bl.id ) { TBL_PC* sd = iMap->id2sd(tst->rid); - if( tst->sleep.timer == INVALID_TIMER ) - {// already awake ??? - node = node->next; + if( tst->sleep.timer == INVALID_TIMER ) {// already awake ??? continue; } - if( (sd && sd->status.char_id != tst->sleep.charid) || (tst->rid && !sd)) - {// char not online anymore / another char of the same account is online - Cancel execution + if( (sd && sd->status.char_id != tst->sleep.charid) || (tst->rid && !sd)) { + // char not online anymore / another char of the same account is online - Cancel execution tst->state = END; tst->rid = 0; } iTimer->delete_timer(tst->sleep.timer, run_script_timer); - node = script_erase_sleepdb(node); tst->sleep.timer = INVALID_TIMER; if(tst->state != RERUNLINE) tst->sleep.tick = 0; run_script_main(tst); } - else - { - node = node->next; - } } + + dbi_destroy(iter); + return true; } @@ -15271,7 +15266,7 @@ BUILDIN(openmail) if( sd == NULL ) return true; - mail_openmail(sd); + mail->openmail(sd); return true; } @@ -16317,6 +16312,7 @@ BUILDIN(progressbar) sd->progressbar.npc_id = st->oid; sd->progressbar.timeout = iTimer->gettick() + second*1000; + sd->state.workinprogress = 3; clif->progressbar(sd, strtol(color, (char **)NULL, 0), second); return true; @@ -16525,9 +16521,10 @@ BUILDIN(setmounting) { TBL_PC* sd; if( (sd = script_rid2sd(st)) == NULL ) return true; - if( sd->sc.option&(OPTION_WUGRIDER|OPTION_RIDING|OPTION_DRAGON|OPTION_MADOGEAR) ) + if( sd->sc.option&(OPTION_WUGRIDER|OPTION_RIDING|OPTION_DRAGON|OPTION_MADOGEAR) ){ + clif->msgtable(sd->fd, 0X78b); script_pushint(st,0);//can't mount with one of these - else { + }else { if( sd->sc.data[SC_ALL_RIDING] ) status_change_end(&sd->bl, SC_ALL_RIDING, INVALID_TIMER); else @@ -17840,6 +17837,12 @@ void script_parse_builtin(void) { void script_defaults(void) { script = &script_s; + script->st_db = NULL; + script->active_scripts = 0; + script->next_id = 0; + script->st_ers = NULL; + script->stack_ers = NULL; + script->hq = NULL; script->hqi = NULL; script->hqs = script->hqis = 0; diff --git a/src/map/script.h b/src/map/script.h index 92a083556..3cfcd9de4 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -9,6 +9,7 @@ #define NUM_WHISPER_VAR 10 struct map_session_data; +struct eri; extern int potion_flag; //For use on Alchemist improved potions/Potion Pitcher. [Skotlex] extern int potion_hp, potion_per_hp, potion_sp, potion_per_sp; @@ -160,6 +161,7 @@ struct script_state { unsigned freeloop : 1;// used by buildin_freeloop unsigned op2ref : 1;// used by op_2 unsigned npc_item_flag : 1; + unsigned int id; }; struct script_reg { @@ -189,11 +191,11 @@ int set_var(struct map_session_data *sd, char *name, void *val); int run_script_timer(int tid, unsigned int tick, int id, intptr_t data); void run_script_main(struct script_state *st); -void script_stop_sleeptimers(int id); +void script_stop_instances(int id); struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n); void script_free_code(struct script_code* code); void script_free_vars(struct DBMap *storage); -struct script_state* script_alloc_state(struct script_code* script, int pos, int rid, int oid); +struct script_state* script_alloc_state(struct script_code* rootscript, int pos, int rid, int oid); void script_free_state(struct script_state* st); struct DBMap* script_get_label_db(void); @@ -334,6 +336,12 @@ struct str_data_struct { /* script.c interface (incomplete) */ struct script_interface { /* */ + DBMap *st_db; + unsigned int active_scripts; + unsigned int next_id; + struct eri *st_ers; + struct eri *stack_ers; + /* */ struct hQueue *hq; struct hQueueIterator *hqi; int hqs, hqis; diff --git a/src/map/skill.c b/src/map/skill.c index 5a10038d8..685fec353 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -2395,6 +2395,10 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds //Can't attack nor use items until skill's delay expires. [Skotlex] sd->ud.attackabletime = sd->canuseitem_tick = sd->ud.canact_tick; break; + case TK_DODGE: + if( pc->checkskill(sd, TK_JUMPKICK) > 0 ) + flag = 1; + break; case SR_DRAGONCOMBO: if( pc->checkskill(sd, SR_FALLENEMPIRE) > 0 ) flag = 1; @@ -3761,7 +3765,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint int sflag = skill_area_temp[0] & 0xFFF, heal; if( flag&SD_LEVEL ) sflag |= SD_LEVEL; // -1 will be used in packets instead of the skill level - if( skill_area_temp[1] != bl->id && !(skill->get_inf2(skill_id)&INF2_NPC_SKILL) ) + if( (skill_area_temp[1] != bl->id && !(skill->get_inf2(skill_id)&INF2_NPC_SKILL)) || flag&SD_ANIMATION ) sflag |= SD_ANIMATION; // original target gets no animation (as well as all NPC skills) heal = skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, sflag); @@ -3776,6 +3780,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case GN_CARTCANNON: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); break; + case SR_TIGERCANNON: + flag |= SD_ANIMATION; case LG_MOONSLASHER: clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); break; @@ -7965,12 +7971,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; for(i = 0; i < SC_MAX; i++) { - if( SC_COMMON_MAX > i ){ - if ( !tsc->data[i] || !status_get_sc_type(i) ) - continue; + if ( !tsc->data[i] ) + continue; + if( SC_COMMON_MAX > i ) if ( status_get_sc_type(i)&SC_NO_CLEARANCE ) continue; - } switch (i) { case SC_ASSUMPTIO: if( bl->type == BL_MOB ) @@ -8551,7 +8556,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SR_FLASHCOMBO: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); for(i = SR_FLASHCOMBO_ATK_STEP1; i <= SR_FLASHCOMBO_ATK_STEP4; i++) - skill->addtimerskill(src, tick + 600 * (i - SR_FLASHCOMBO_ATK_STEP1), bl->id, 0, 0, i, skill_lv, BF_WEAPON, flag|SD_LEVEL); + skill->addtimerskill(src, tick + 500 * (i - SR_FLASHCOMBO_ATK_STEP1), bl->id, 0, 0, i, skill_lv, BF_WEAPON, flag|SD_LEVEL); break; case WA_SWING_DANCE: case WA_MOONLIT_SERENADE: @@ -13101,12 +13106,14 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id case TK_STORMKICK: case TK_DOWNKICK: case TK_COUNTER: + case TK_JUMPKICK: case HT_POWER: case GC_COUNTERSLASH: case GC_WEAPONCRUSH: case SR_FALLENEMPIRE: case SR_DRAGONCOMBO: case SR_TIGERCANNON: + case SR_GATEOFHELL: break; default: return 0; } diff --git a/src/map/status.c b/src/map/status.c index 8363b8021..55b79fff7 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -915,6 +915,7 @@ void initChangeTables(void) { StatusIconChangeTable[SC_PUSH_CART] = SI_ON_PUSH_CART; StatusIconChangeTable[SC_REBOUND] = SI_REBOUND; StatusIconChangeTable[SC_ALL_RIDING] = SI_ALL_RIDING; + StatusIconChangeTable[SC_MONSTER_TRANSFORM] = SI_MONSTER_TRANSFORM; //Other SC which are not necessarily associated to skills. StatusChangeFlagTable[SC_ATTHASTE_POTION1] = SCB_ASPD; @@ -1022,6 +1023,7 @@ void initChangeTables(void) { StatusDisplayType[SC_BLOOD_SUCKER] = true; StatusDisplayType[SC__SHADOWFORM] = true; StatusDisplayType[SC__MANHOLE] = true; + StatusDisplayType[SC_MONSTER_TRANSFORM] = true; #ifdef RENEWAL_EDP // renewal EDP increases your weapon atk @@ -2500,7 +2502,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) #ifdef RENEWAL wa->matk += sd->inventory_data[index]->matk; wa->wlv = wlv; - if( r ) // renewal magic attack refine bonus + if( r && sd->weapontype1 != W_BOW ) // renewal magic attack refine bonus wa->matk += refine_info[wlv].bonus[r-1] / 100; #endif @@ -8327,10 +8329,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; case SC_BLOOD_SUCKER: { - struct block_list *src = iMap->id2bl(sce->val2); + struct block_list *src = iMap->id2bl(val2); val3 = 1; if(src) - val3 = 200 + 100 * sce->val1 + status_get_int(src); + val3 = 200 + 100 * val1 + status_get_int(src); val4 = tick / 1000; tick_time = 1000; // [GodLesZ] tick time } @@ -8712,6 +8714,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val tick_time = 10000; val4 = tick / tick_time; break; + case SC_MONSTER_TRANSFORM: + if( !mobdb_checkid(val1) ) + val1 = 1002; // default poring + val_flag |= 1; + break; default: if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 ) { //Status change with no calc, no icon, and no skill associated...? @@ -8739,8 +8746,12 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_SUMMON3: case SC_SUMMON4: case SC_SUMMON5: + case SC_MONSTER_TRANSFORM: val_flag |= 1; break; + case SC_KYOUGAKU: + clif->status_change(bl, SI_ACTIVE_MONSTER_TRANSFORM, 1, 0, 1002, 0, 0); // Poring in disguise + break; } } @@ -9646,7 +9657,6 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const } break; case SC_KYOUGAKU: - clif->sc_end(&sd->bl,sd->bl.id,AREA,SI_KYOUGAKU); clif->sc_end(&sd->bl,sd->bl.id,AREA,SI_ACTIVE_MONSTER_TRANSFORM); break; case SC_CLAIRVOYANCE: diff --git a/src/map/status.h b/src/map/status.h index 617cd9572..fbce95f17 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -671,6 +671,8 @@ typedef enum sc_type { SC_ALL_RIDING, SC_HANBOK, + SC_MONSTER_TRANSFORM, + SC_MAX, //Automatically updated max, used in for's to check we are within bounds. } sc_type; diff --git a/src/map/trade.c b/src/map/trade.c index 8311dbf3d..f469f4b28 100644 --- a/src/map/trade.c +++ b/src/map/trade.c @@ -331,7 +331,7 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount) if( (target_sd = iMap->id2sd(sd->trade_partner)) == NULL ) { - trade_tradecancel(sd); + trade->cancel(sd); return; } @@ -415,13 +415,13 @@ void trade_tradeaddzeny(struct map_session_data* sd, int amount) if( (target_sd = iMap->id2sd(sd->trade_partner)) == NULL ) { - trade_tradecancel(sd); + trade->cancel(sd); return; } if( amount < 0 || amount > sd->status.zeny || amount > MAX_ZENY - target_sd->status.zeny ) { // invalid values, no appropriate packet for it => abort - trade_tradecancel(sd); + trade->cancel(sd); return; } @@ -440,7 +440,7 @@ void trade_tradeok(struct map_session_data *sd) return; if ((target_sd = iMap->id2sd(sd->trade_partner)) == NULL) { - trade_tradecancel(sd); + trade->cancel(sd); return; } sd->state.deal_locked = 1; @@ -532,18 +532,18 @@ void trade_tradecommit(struct map_session_data *sd) //Now is a good time (to save on resources) to check that the trade can indeed be made and it's not exploitable. // check exploit (trade more items that you have) - if (impossible_trade_check(sd)) { - trade_tradecancel(sd); + if (trade->check_impossible(sd)) { + trade->cancel(sd); return; } // check exploit (trade more items that you have) - if (impossible_trade_check(tsd)) { - trade_tradecancel(tsd); + if (trade->check_impossible(tsd)) { + trade->cancel(tsd); return; } // check for full inventory (can not add traded items) - if (!trade_check(sd,tsd)) { // check the both players - trade_tradecancel(sd); + if (!trade->check(sd,tsd)) { // check the both players + trade->cancel(sd); return; } @@ -607,3 +607,18 @@ void trade_tradecommit(struct map_session_data *sd) chrif_save(tsd,0); } } + +void trade_defaults(void) +{ + trade = &trade_s; + + trade->request = trade_traderequest; + trade->ack = trade_tradeack; + trade->check_impossible = impossible_trade_check; + trade->check = trade_check; + trade->additem = trade_tradeadditem; + trade->addzeny = trade_tradeaddzeny; + 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 6bb39936e..f66c70525 100644 --- a/src/map/trade.h +++ b/src/map/trade.h @@ -7,12 +7,19 @@ //#include "map.h" struct map_session_data; -void trade_traderequest(struct map_session_data *sd, struct map_session_data *target_sd); -void trade_tradeack(struct map_session_data *sd,int type); -void trade_tradeadditem(struct map_session_data *sd,short index,short amount); -void trade_tradeaddzeny(struct map_session_data *sd,int amount); -void trade_tradeok(struct map_session_data *sd); -void trade_tradecancel(struct map_session_data *sd); -void trade_tradecommit(struct map_session_data *sd); +struct trade_interface { + void (*request) (struct map_session_data *sd, struct map_session_data *target_sd); + void (*ack) (struct map_session_data *sd,int type); + int (*check_impossible) (struct map_session_data *sd); + int (*check) (struct map_session_data *sd, struct map_session_data *tsd); + void (*additem) (struct map_session_data *sd,short index,short amount); + void (*addzeny) (struct map_session_data *sd,int amount); + void (*ok) (struct map_session_data *sd); + void (*cancel) (struct map_session_data *sd); + void (*commit) (struct map_session_data *sd); +} 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 e5637e42d..021859bba 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -2104,7 +2104,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, if(sd->chatID) chat_leavechat(sd,0); if(sd->trade_partner) - trade_tradecancel(sd); + trade->cancel(sd); buyingstore->close(sd); searchstore->close(sd); if(sd->state.storage_flag == 1) |