summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/map/clif.h1
-rw-r--r--src/map/map.c4
-rw-r--r--src/map/map.h4
-rw-r--r--src/map/mob.c21
-rw-r--r--src/map/npc.c12
-rw-r--r--src/map/pc.c13
-rw-r--r--src/map/script.c280
-rw-r--r--src/map/script.h4
8 files changed, 185 insertions, 154 deletions
diff --git a/src/map/clif.h b/src/map/clif.h
index 7cae56cdf..64c0ef2eb 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -317,6 +317,7 @@ int clif_pet_emotion(struct pet_data *pd,int param);
int clif_pet_performance(struct block_list *bl,int param);
int clif_pet_equip(struct pet_data *pd,int nameid);
int clif_pet_food(struct map_session_data *sd,int foodid,int fail);
+int clif_send (unsigned char *buf, int len, struct block_list *bl, int type);
//friends list
int clif_friendslist_toggle_sub(struct map_session_data *sd,va_list ap);
diff --git a/src/map/map.c b/src/map/map.c
index 98af550c2..c43ed5ca2 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -1678,10 +1678,6 @@ int map_quit(struct map_session_data *sd) {
unit_remove_map(&sd->pd->bl, 0);
}
}
- if (sd->stack) {
- script_free_stack(sd->stack);
- sd->stack= NULL;
- }
//Do we really need to remove the name?
idb_remove(charid_db,sd->status.char_id);
diff --git a/src/map/map.h b/src/map/map.h
index a0d19f04e..9e92dea70 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -526,11 +526,9 @@ struct map_session_data {
unsigned int client_tick;
int npc_id,areanpc_id,npc_shopid;
int npc_item_flag; //Marks the npc_id with which you can use items during interactions with said npc (see script command enable_itemuse)
- int npc_pos;
int npc_menu;
int npc_amount;
- struct script_stack *stack;
- struct script_code *npc_script,*npc_scriptroot;
+ struct script_state *st;
int npc_scriptstate;
char npc_str[256];
int npc_timer_id; //For player attached npc timers. [Skotlex]
diff --git a/src/map/mob.c b/src/map/mob.c
index ab195ecac..63b71b941 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -774,12 +774,12 @@ static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
if ((*target) == bl || !status_check_skilluse(&md->bl, bl, 0, 0))
return 0;
- if(md->nd && mob_script_callback(md, bl, CALLBACK_DETECT))
- return 1; // We have script handling the work.
-
if(battle_check_target(&md->bl,bl,BCT_ENEMY)<=0)
return 0;
+ if(md->nd && mob_script_callback(md, bl, CALLBACK_DETECT))
+ return 1; // We have script handling the work.
+
switch (bl->type)
{
case BL_PC:
@@ -2120,9 +2120,10 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
if(pcdb_checkid(md->vd->class_))
{ //Player mobs are not removed automatically by the client.
- if(md->nd)
+ if(md->nd){
+ md->vd->dead_sit = 1;
return 1; // Let the dead body stay there.. we have something to do with it :D
- else
+ } else
clif_clearchar_delay(tick+3000,&md->bl,0);
}
@@ -2400,8 +2401,13 @@ int mob_summonslave(struct mob_data *md2,int *value,int amount,int skill_id)
md= mob_spawn_dataset(&data);
md->special_state.cached= battle_config.dynamic_mobs; //[Skotlex]
- if(skill_id == NPC_SUMMONSLAVE)
+ if(skill_id == NPC_SUMMONSLAVE){
md->master_id=md2->bl.id;
+ md->state.killer = md2->state.killer;
+ md->special_state.ai = md2->special_state.ai;
+ md->nd = md2->nd;
+ md->callback_flag = md2->callback_flag;
+ }
mob_spawn(md);
if (hp_rate) //Scale HP
@@ -2418,9 +2424,6 @@ int mob_summonslave(struct mob_data *md2,int *value,int amount,int skill_id)
clif_skill_nodamage(&md->bl,&md->bl,skill_id,amount,1);
}
- if(md2->nd)
- mob_convertslave(md2);
-
return 0;
}
diff --git a/src/map/npc.c b/src/map/npc.c
index 6f3fe5f00..a81a63b23 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -818,7 +818,7 @@ int npc_event_sub(struct map_session_data *sd, struct event_data *ev, const unsi
return 0;
}
- sd->npc_pos=run_script(ev->nd->u.scr.script,ev->pos,sd->bl.id,ev->nd->bl.id);
+ run_script(ev->nd->u.scr.script,ev->pos,sd->bl.id,ev->nd->bl.id);
return 0;
}
@@ -1108,7 +1108,7 @@ int npc_click(struct map_session_data *sd,struct block_list *bl)
npc_event_dequeue(sd);
break;
case SCRIPT:
- sd->npc_pos=run_script(nd->u.scr.script,0,sd->bl.id,nd->bl.id);
+ run_script(nd->u.scr.script,0,sd->bl.id,nd->bl.id);
break;
}
@@ -1129,14 +1129,12 @@ int npc_scriptcont(struct map_session_data *sd,int id)
}
if(id != fake_nd->bl.id) { // Not item script
- struct npc_data *nd;
- if ((nd = npc_checknear(sd,map_id2bl(id))) == NULL){
+ if ((npc_checknear(sd,map_id2bl(id))) == NULL){
ShowWarning("npc_scriptcont: failed npc_checknear test.\n");
return 1;
}
- sd->npc_pos=run_script(nd->u.scr.script,sd->npc_pos,sd->bl.id,id);
- } else // Item script, continue execution...
- sd->npc_pos=run_script(sd->npc_scriptroot,sd->npc_pos,sd->bl.id,id);
+ }
+ run_script_main(sd->st);
return 0;
}
diff --git a/src/map/pc.c b/src/map/pc.c
index fc7e5c7a8..ac3a054f2 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -4679,8 +4679,13 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
pc_setglobalreg(sd,"PC_DIE_COUNTER",++sd->die_counter);
- if (sd->state.event_death && (!src || src->type != BL_PC))
- pc_setglobalreg(sd, "killerrid", 0);
+ if (sd->state.event_death){
+ if(!src)
+ pc_setglobalreg(sd, "killerrid", 0);
+ else
+ pc_setglobalreg(sd,"killerrid",src->id);
+ npc_script_event(sd,NPCE_DIE);
+ }
if (src)
switch (src->type) {
@@ -4705,10 +4710,6 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
case BL_PC:
{
struct map_session_data *ssd = (struct map_session_data *)src;
- if (sd->state.event_death){
- pc_setglobalreg(sd,"killerrid",(ssd->status.account_id));
- npc_script_event(sd,NPCE_DIE);
- }
if (ssd->state.event_kill_pc) {
pc_setglobalreg(ssd, "killedrid", sd->bl.id);
npc_script_event(ssd, NPCE_KILLPC);
diff --git a/src/map/script.c b/src/map/script.c
index 3f7b98aaa..818280012 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -404,7 +404,7 @@ int buildin_setd(struct script_state *st);
int buildin_petstat(struct script_state *st); // [Lance] Pet Stat Rq: Dubby
int buildin_callshop(struct script_state *st); // [Skotlex]
int buildin_npcshopitem(struct script_state *st); // [Lance]
-int buildin_npcshopadditem(struct script_state *st);
+int buildin_npcshopadditem(struct script_state *st);
int buildin_npcshopdelitem(struct script_state *st);
int buildin_equip(struct script_state *st);
int buildin_autoequip(struct script_state *st);
@@ -741,7 +741,7 @@ struct {
{buildin_petstat,"petstat","i"},
{buildin_callshop,"callshop","si"}, // [Skotlex]
{buildin_npcshopitem,"npcshopitem","sii*"}, // [Lance]
- {buildin_npcshopadditem,"npcshopadditem","sii*"},
+ {buildin_npcshopadditem,"npcshopadditem","sii*"},
{buildin_npcshopdelitem,"npcshopdelitem","si*"},
{buildin_equip,"equip","i"},
{buildin_autoequip,"autoequip","ii"},
@@ -8992,18 +8992,18 @@ int buildin_movenpc(struct script_state *st)
x = conv_num(st,& (st->stack->stack_data[st->start+3]));
y = conv_num(st,& (st->stack->stack_data[st->start+4]));
- if ((nd = npc_name2id(npc)) == NULL)
- return -1;
-
- if ((m=nd->bl.m) < 0 || nd->bl.prev == NULL)
- return -1; //Not on a map.
-
- if (x < 0) x = 0;
- else if (x >= map[m].xs) x = map[m].xs-1;
- if (y < 0) y = 0;
- else if (y >= map[m].ys) y = map[m].ys-1;
- map_foreachinrange(clif_outsight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl);
- map_moveblock(&nd->bl, x, y, gettick());
+ if ((nd = npc_name2id(npc)) == NULL)
+ return -1;
+
+ if ((m=nd->bl.m) < 0 || nd->bl.prev == NULL)
+ return -1; //Not on a map.
+
+ if (x < 0) x = 0;
+ else if (x >= map[m].xs) x = map[m].xs-1;
+ if (y < 0) y = 0;
+ else if (y >= map[m].ys) y = map[m].ys-1;
+ map_foreachinrange(clif_outsight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl);
+ map_moveblock(&nd->bl, x, y, gettick());
map_foreachinrange(clif_insight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl);
return 0;
@@ -10134,83 +10134,83 @@ int buildin_npcshopitem(struct script_state *st)
return 0;
}
-int buildin_npcshopadditem(struct script_state *st) {
- struct npc_data *nd=NULL;
- int n = 0;
- int i = 3;
- int amount;
-
- char* npcname = conv_str(st, & (st->stack->stack_data[st->start+2]));
- nd = npc_name2id(npcname);
-
- if (nd && nd->bl.subtype==SHOP){
- amount = ((st->end-2)/2)+1;
- while (nd->u.shop_item[n].nameid && n < MAX_SHOPITEM)
+int buildin_npcshopadditem(struct script_state *st) {
+ struct npc_data *nd=NULL;
+ int n = 0;
+ int i = 3;
+ int amount;
+
+ char* npcname = conv_str(st, & (st->stack->stack_data[st->start+2]));
+ nd = npc_name2id(npcname);
+
+ if (nd && nd->bl.subtype==SHOP){
+ amount = ((st->end-2)/2)+1;
+ while (nd->u.shop_item[n].nameid && n < MAX_SHOPITEM)
n++;
nd = (struct npc_data *)aRealloc(nd,sizeof(struct npc_data) +
- sizeof(nd->u.shop_item[0]) * (amount+n));
-
- while(st->end > st->start + i){
- nd->u.shop_item[n].nameid = conv_num(st, & (st->stack->stack_data[st->start+i]));
- i++;
- nd->u.shop_item[n].value = conv_num(st, & (st->stack->stack_data[st->start+i]));
- i++;
- n++;
- }
-
- // Marks the last of our stuff..
- nd->u.shop_item[n].value = 0;
- nd->u.shop_item[n].nameid = 0;
-
- map_addiddb(&nd->bl);
- nd->master_nd = ((struct npc_data *)map_id2bl(st->oid));
- } else {
- ShowError("buildin_npcshopadditem: shop not found.\n");
- }
-
- return 0;
-}
-
-int buildin_npcshopdelitem(struct script_state *st)
-{
- struct npc_data *nd=NULL;
- int n=0;
- int i=3;
- int size = 0;
-
- char* npcname = conv_str(st, & (st->stack->stack_data[st->start+2]));
- nd = npc_name2id(npcname);
-
- if (nd && nd->bl.subtype==SHOP) {
- while (nd->u.shop_item[size].nameid)
- size++;
-
- while (st->end > st->start+i) {
- for(n=0;nd->u.shop_item[n].nameid && n < MAX_SHOPITEM;n++) {
- if (nd->u.shop_item[n].nameid == conv_num(st, & (st->stack->stack_data[st->start+i]))) {
- // We're moving 1 extra empty block. Junk data is eliminated later.
- memmove(&nd->u.shop_item[n], &nd->u.shop_item[n+1], sizeof(nd->u.shop_item[0])*(size-n));
- }
- }
- i++;
- }
-
- size = 0;
-
- while (nd->u.shop_item[size].nameid)
- size++;
-
- nd = (struct npc_data *)aRealloc(nd,sizeof(struct npc_data) +
- sizeof(nd->u.shop_item[0]) * (size+1));
-
- map_addiddb(&nd->bl);
- nd->master_nd = ((struct npc_data *)map_id2bl(st->oid));
- } else {
- ShowError("buildin_npcshopdelitem: shop not found.\n");
- }
-
- return 0;
+ sizeof(nd->u.shop_item[0]) * (amount+n));
+
+ while(st->end > st->start + i){
+ nd->u.shop_item[n].nameid = conv_num(st, & (st->stack->stack_data[st->start+i]));
+ i++;
+ nd->u.shop_item[n].value = conv_num(st, & (st->stack->stack_data[st->start+i]));
+ i++;
+ n++;
+ }
+
+ // Marks the last of our stuff..
+ nd->u.shop_item[n].value = 0;
+ nd->u.shop_item[n].nameid = 0;
+
+ map_addiddb(&nd->bl);
+ nd->master_nd = ((struct npc_data *)map_id2bl(st->oid));
+ } else {
+ ShowError("buildin_npcshopadditem: shop not found.\n");
+ }
+
+ return 0;
+}
+
+int buildin_npcshopdelitem(struct script_state *st)
+{
+ struct npc_data *nd=NULL;
+ int n=0;
+ int i=3;
+ int size = 0;
+
+ char* npcname = conv_str(st, & (st->stack->stack_data[st->start+2]));
+ nd = npc_name2id(npcname);
+
+ if (nd && nd->bl.subtype==SHOP) {
+ while (nd->u.shop_item[size].nameid)
+ size++;
+
+ while (st->end > st->start+i) {
+ for(n=0;nd->u.shop_item[n].nameid && n < MAX_SHOPITEM;n++) {
+ if (nd->u.shop_item[n].nameid == conv_num(st, & (st->stack->stack_data[st->start+i]))) {
+ // We're moving 1 extra empty block. Junk data is eliminated later.
+ memmove(&nd->u.shop_item[n], &nd->u.shop_item[n+1], sizeof(nd->u.shop_item[0])*(size-n));
+ }
+ }
+ i++;
+ }
+
+ size = 0;
+
+ while (nd->u.shop_item[size].nameid)
+ size++;
+
+ nd = (struct npc_data *)aRealloc(nd,sizeof(struct npc_data) +
+ sizeof(nd->u.shop_item[0]) * (size+1));
+
+ map_addiddb(&nd->bl);
+ nd->master_nd = ((struct npc_data *)map_id2bl(st->oid));
+ } else {
+ ShowError("buildin_npcshopdelitem: shop not found.\n");
+ }
+
+ return 0;
}
/*==========================================
@@ -10709,7 +10709,7 @@ int buildin_unitwarp(struct script_state *st){
y = conv_num(st, & (st->stack->stack_data[st->start+5]));
bl = map_id2bl(id);
- m = mapindex_name2id(map);
+ m = map_mapname2mapid(map);
if(m && bl){
push_val(st->stack,C_INT,unit_warp(bl, m, (short)x, (short)y, 0));
} else {
@@ -10831,7 +10831,8 @@ int buildin_unitdeadsit(struct script_state *st){
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
action = conv_num(st, & (st->stack->stack_data[st->start+3]));
if((bl = map_id2bl(id))){
- if(action > -1 && action < 3){
+ if(action > -1 && action < 4){
+ unsigned char *buf = NULL;
switch(bl->type){
case BL_MOB:
((TBL_MOB *)bl)->vd->dead_sit = action;
@@ -10848,6 +10849,10 @@ int buildin_unitdeadsit(struct script_state *st){
case BL_PET:
((TBL_PET *)bl)->vd.dead_sit = action;
break;
+ WBUFW(buf, 0) = 0x8a;
+ WBUFL(buf, 2) = bl->id;
+ WBUFB(buf,26) = (unsigned char)action;
+ clif_send(buf, 61, bl, AREA);
}
}else {
ShowError("buildin_unitdeadsit: Invalid action.\n");
@@ -11391,12 +11396,24 @@ int run_func(struct script_state *st)
* スクリプトの実行メイン部分
*------------------------------------------
*/
-int run_script_main(struct script_state *st)
+void run_script_main(struct script_state *st)
{
int c/*,rerun_pos*/;
int cmdcount=script_config.check_cmdcount;
int gotocount=script_config.check_gotocount;
struct script_stack *stack=st->stack;
+ TBL_PC *sd = (TBL_PC *)map_id2bl(st->rid);
+ struct script_state *bk_st = NULL;
+ int bk_npcid = 0;
+
+ if(sd){
+ if(sd->st != st){
+ bk_st = sd->st;
+ bk_npcid = sd->npc_id;
+ }
+ sd->st = st;
+ sd->npc_id = st->oid;
+ }
if(st->state == RERUNLINE) {
st->state = RUN;
@@ -11404,7 +11421,7 @@ int run_script_main(struct script_state *st)
if(st->state == GOTO){
st->state = RUN;
}
- } else {
+ } else if(st->state != END){
st->state = RUN;
}
while( st->state == RUN) {
@@ -11501,9 +11518,8 @@ int run_script_main(struct script_state *st)
break;
case END:
{
- struct map_session_data *sd=st->rid?map_id2sd(st->rid):NULL;
st->pos=-1;
- if(sd && (sd->npc_id==st->oid || sd->state.using_fake_npc)){
+ if(sd){
if(sd->state.using_fake_npc){
clif_clearchar_id(sd->npc_id, 0, sd->fd);
sd->state.using_fake_npc = 0;
@@ -11513,6 +11529,21 @@ int run_script_main(struct script_state *st)
}
break;
case RERUNLINE:
+ if(bk_st && sd->st != bk_st && st->sleep.tick <= 0){
+ ShowWarning("Unable to restore stack! Double continuation!\n");
+ script_free_stack(bk_st->stack);
+ aFree(bk_st);
+ }
+ if(st->sleep.tick > 0)
+ { //Delay execution
+ if(sd)
+ st->sleep.charid = sd->char_id;
+ else
+ st->sleep.charid = 0;
+ st->sleep.timer = add_timer(gettick()+st->sleep.tick,
+ run_script_timer, st->sleep.charid, (int)st);
+ linkdb_insert(&sleep_db, (void*)st->oid, st);
+ }
// Do not call function of commands two time! [ Eoe / jA 1094 ]
// For example: select "1", "2", callsub(...);
// If current script position is changed, callsub will be called two time.
@@ -11524,12 +11555,20 @@ int run_script_main(struct script_state *st)
}
if(st->state == END) {
- script_free_stack (st->stack);
- st->stack = NULL;
- aFree(st);
- st = NULL;
- return 0;
- }else{
+ if(sd){
+ script_free_stack(sd->st->stack);
+ aFree(sd->st);
+ sd->st = bk_st;
+ sd->npc_id = bk_npcid;
+ if (sd->state.reg_dirty&2)
+ intif_saveregistry(sd,2);
+ if (sd->state.reg_dirty&1)
+ intif_saveregistry(sd,1);
+ } else {
+ script_free_stack (st->stack);
+ aFree(st);
+ }
+ }/*else{
if(st->sleep.tick > 0)
{ //Delay execution
TBL_PC *sd = (TBL_PC *)map_id2bl(st->rid);
@@ -11538,41 +11577,33 @@ int run_script_main(struct script_state *st)
run_script_timer, st->sleep.charid, (int)st);
linkdb_insert(&sleep_db, (void*)st->oid, st);
}
- }
+ }*/
- return 1;
+ return;
}
/*==========================================
* スクリプトの実行
*------------------------------------------
*/
-int run_script(struct script_code *rootscript,int pos,int rid,int oid)
+void run_script(struct script_code *rootscript,int pos,int rid,int oid)
{
struct script_state *st;
struct map_session_data *sd=NULL;
//Variables for backing up the previous script and restore it if needed. [Skotlex]
- struct script_code *bck_script = NULL;
- struct script_code *bck_scriptroot = NULL;
- int bck_scriptstate = 0,bck_npcid = 0;
+ //struct script_code *bck_script = NULL;
+ //struct script_code *bck_scriptroot = NULL;
+ //int bck_scriptstate = 0,bck_npcid = 0;
struct script_stack *bck_stack = NULL;
if (rootscript == NULL || pos < 0)
- return -1;
+ return;
st = aCalloc(sizeof(struct script_state), 1);
- if ((sd = map_id2sd(rid)) && sd->stack && sd->npc_scriptroot == rootscript){
- // we have a stack for the same script, should continue exec.
- st->script = sd->npc_script;
- st->stack = sd->stack;
- st->state = sd->npc_scriptstate;
- // and clear vars
- sd->stack = NULL;
- sd->npc_script = NULL;
- sd->npc_scriptroot = NULL;
- sd->npc_scriptstate = 0;
+ if ((sd = map_id2sd(rid)) && sd->st && sd->st->scriptroot == rootscript && sd->st->pos == pos){
+ st = sd->st;
} else {
// the script is different, make new script_state and stack
st->stack = aMalloc (sizeof(struct script_stack));
@@ -11584,7 +11615,7 @@ int run_script(struct script_code *rootscript,int pos,int rid,int oid)
st->state = RUN;
st->script = rootscript;
- if (sd){
+ /*if (sd){
if(sd->stack) {
// if there's a sd and a stack - back it up and restore it if possible.
bck_script = sd->npc_script;
@@ -11595,15 +11626,15 @@ int run_script(struct script_code *rootscript,int pos,int rid,int oid)
}
bck_npcid = sd->npc_id;
sd->npc_id = oid;
- }
+ }*/
}
st->pos = pos;
st->rid = rid;
st->oid = oid;
st->sleep.timer = -1;
- if(run_script_main(st)){
- if (st->state != END){
+ run_script_main(st);
+ /* if (st->state != END){
pos = st->pos;
if(!st->sleep.tick && sd) {
// script is not finished, store data in sd.
@@ -11636,8 +11667,8 @@ int run_script(struct script_code *rootscript,int pos,int rid,int oid)
if (sd->state.reg_dirty&1)
intif_saveregistry(sd,1);
}
- }
- return 0;
+ }*/
+ return;
}
/*==========================================
@@ -11683,6 +11714,9 @@ int run_script_timer(int tid, unsigned int tick, int id, int data)
}
node = node->next;
}
+ if(st->rid && !sd)
+ st->state = END;
+
run_script_main(st);
return 0;
}
diff --git a/src/map/script.h b/src/map/script.h
index d94348e43..85ddc2d6a 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -64,14 +64,14 @@ struct script_state {
};
struct script_code *parse_script(unsigned char *,int);
-int run_script(struct script_code *rootscript,int pos,int rid,int oid);
+void run_script(struct script_code *rootscript,int pos,int rid,int oid);
int set_var(struct map_session_data *sd, char *name, void *val);
int conv_num(struct script_state *st,struct script_data *data);
char* conv_str(struct script_state *st,struct script_data *data);
void setd_sub(struct script_state *st, struct map_session_data *sd, char *varname, int elem, void *value, struct linkdb_node **ref);
int run_script_timer(int tid, unsigned int tick, int id, int data);
-int run_script_main(struct script_state *st);
+void run_script_main(struct script_state *st);
struct linkdb_node* script_erase_sleepdb(struct linkdb_node *n);
void script_free_code(struct script_code* code);