summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/mmo.h7
-rw-r--r--src/config/const.h7
-rw-r--r--src/map/atcommand.c27
-rw-r--r--src/map/battle.c28
-rw-r--r--src/map/clif.c59
-rw-r--r--src/map/intif.c4
-rw-r--r--src/map/mail.c26
-rw-r--r--src/map/mail.h29
-rw-r--r--src/map/map.c4
-rw-r--r--src/map/npc.c3
-rw-r--r--src/map/pc.c12
-rw-r--r--src/map/pc.h2
-rw-r--r--src/map/script.c191
-rw-r--r--src/map/script.h12
-rw-r--r--src/map/skill.c19
-rw-r--r--src/map/status.c18
-rw-r--r--src/map/status.h2
-rw-r--r--src/map/trade.c35
-rw-r--r--src/map/trade.h21
-rw-r--r--src/map/unit.c2
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)