* BL_PC and BL_MOB control script commands (experimental).

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@5627 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
Lance 2006-03-16 15:39:49 +00:00
parent 3e1af99395
commit 46bdee18f9
8 changed files with 422 additions and 4 deletions

View File

@ -5,6 +5,7 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. EV
GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS
2006/03/15 2006/03/15
* BL_PC and BL_MOB control script commands (experimental) [Lance]
* Made an adjustment to addspiritball() to allow Gunslingers to summon up to 10 spheres [reddozen] * Made an adjustment to addspiritball() to allow Gunslingers to summon up to 10 spheres [reddozen]
* Fixed Tarot Card of Fate using time instead of time2 which is the one * Fixed Tarot Card of Fate using time instead of time2 which is the one
that actually holds the effect duration. [Skotlex] that actually holds the effect duration. [Skotlex]

View File

@ -9109,6 +9109,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data *sd) { // S 008c <
#ifdef PCRE_SUPPORT #ifdef PCRE_SUPPORT
map_foreachinrange(npc_chat_sub, &sd->bl, AREA_SIZE, BL_NPC, message, strlen(message), &sd->bl); map_foreachinrange(npc_chat_sub, &sd->bl, AREA_SIZE, BL_NPC, message, strlen(message), &sd->bl);
map_foreachinrange(mob_chat_sub, &sd->bl, AREA_SIZE, BL_MOB, message, strlen(message), &sd->bl);
#endif #endif
// Celest // Celest

View File

@ -872,6 +872,8 @@ struct mob_data {
int skilltarget; int skilltarget;
int def_ele; int def_ele;
int master_id,master_dist; int master_id,master_dist;
struct npc_data *nd;
short skillx,skilly,skillid,skilllv,skillidx; short skillx,skilly,skillid,skilllv,skillidx;
unsigned int skilldelay[MAX_MOBSKILL]; unsigned int skilldelay[MAX_MOBSKILL];

View File

@ -2281,15 +2281,27 @@ int mob_damage(struct block_list *src,struct mob_data *md,int damage,int type)
int drop_rate; int drop_rate;
int base_drop_delay; int base_drop_delay;
int race; int race;
char buffer[64];
nullpo_retr(0, md); //srcはNULLで呼ばれる場合もあるので、他でチェック nullpo_retr(0, md); //srcはNULLで呼ばれる場合もあるので、他でチェック
max_hp = status_get_max_hp(&md->bl); max_hp = status_get_max_hp(&md->bl);
race = status_get_race(&md->bl); race = status_get_race(&md->bl);
if(src && src->type == BL_PC) { if(src){
sd = (struct map_session_data *)src; if(md->nd){
mvp_sd = sd; sprintf(buffer, "$@%d_attacker", md->bl.id);
set_var(NULL, buffer, src->id);
sprintf(buffer, "$@%d_attacktype", md->bl.id);
set_var(NULL, buffer, src->type);
sprintf(buffer, "%s::OnDamage", md->nd->exname);
npc_event_do(buffer);
return 0;
}
if(src->type == BL_PC) {
sd = (struct map_session_data *)src;
mvp_sd = sd;
}
} }
if(md->bl.prev==NULL){ if(md->bl.prev==NULL){

View File

@ -16,6 +16,7 @@
#ifdef PCRE_SUPPORT #ifdef PCRE_SUPPORT
void npc_chat_finalize(struct npc_data *nd); void npc_chat_finalize(struct npc_data *nd);
int mob_chat_sub(struct block_list *bl, va_list ap);
#endif #endif
int npc_chat_sub(struct block_list *bl, va_list ap); int npc_chat_sub(struct block_list *bl, va_list ap);
int npc_event_dequeue(struct map_session_data *sd); int npc_event_dequeue(struct map_session_data *sd);

View File

@ -372,6 +372,20 @@ void npc_chat_finalize(struct npc_data *nd)
aFree(npcParse); aFree(npcParse);
} }
int mob_chat_sub(struct block_list *bl, va_list ap){
int len;
unsigned char *msg = NULL;
struct map_session_data *sd = NULL;
struct mob_data *md = (struct mob_data *)bl;
if(md->nd){
msg = va_arg(ap,unsigned char*);
len = va_arg(ap,int);
sd = va_arg(ap,struct map_session_data *);
npc_chat_sub(&md->nd->bl, msg, len, sd);
}
return 0;
}
/** /**
* Handler called whenever a global message is spoken in a NPC's area * Handler called whenever a global message is spoken in a NPC's area
*/ */

View File

@ -4491,7 +4491,7 @@ int pc_stop_following (struct map_session_data *sd)
int pc_follow(struct map_session_data *sd,int target_id) int pc_follow(struct map_session_data *sd,int target_id)
{ {
struct block_list *bl = map_id2bl(target_id); struct block_list *bl = map_id2bl(target_id);
if (bl == NULL || bl->type != BL_PC) if (bl == NULL /*|| bl->type != BL_PC*/)
return 1; return 1;
if (sd->followtimer != -1) if (sd->followtimer != -1)
pc_stop_following(sd); pc_stop_following(sd);

View File

@ -404,6 +404,26 @@ int buildin_callshop(struct script_state *st); // [Skotlex]
int buildin_equip(struct script_state *st); int buildin_equip(struct script_state *st);
int buildin_autoequip(struct script_state *st); int buildin_autoequip(struct script_state *st);
int buildin_setbattleflag(struct script_state *st); int buildin_setbattleflag(struct script_state *st);
// [zBuffer] List of player cont commands --->
int buildin_pcwalkxy(struct script_state *st);
int buildin_pctalk(struct script_state *st);
int buildin_pcemote(struct script_state *st);
int buildin_pcfollow(struct script_state *st);
int buildin_pcstopfollow(struct script_state *st);
// <--- [zBuffer] List of player cont commands
// [zBuffer] List of mob control commands --->
int buildin_spawnmob(struct script_state *st);
int buildin_removemob(struct script_state *st);
int buildin_mobwalk(struct script_state *st);
int buildin_getmobdata(struct script_state *st);
int buildin_setmobdata(struct script_state *st);
int buildin_mobattack(struct script_state *st);
int buildin_mobstop(struct script_state *st);
int buildin_mobassist(struct script_state *st);
int buildin_mobtalk(struct script_state *st);
int buildin_mobemote(struct script_state *st);
int buildin_mobattach(struct script_state *st);
// <--- [zBuffer] List of mob control commands
void push_val(struct script_stack *stack,int type,int val); void push_val(struct script_stack *stack,int type,int val);
int run_func(struct script_state *st); int run_func(struct script_state *st);
@ -711,6 +731,26 @@ struct {
{buildin_setitemscript,"setitemscript","is"}, //Set NEW item bonus script. Lupus {buildin_setitemscript,"setitemscript","is"}, //Set NEW item bonus script. Lupus
{buildin_disguise,"disguise","i"}, //disguise player. Lupus {buildin_disguise,"disguise","i"}, //disguise player. Lupus
{buildin_undisguise,"undisguise","i"}, //undisguise player. Lupus {buildin_undisguise,"undisguise","i"}, //undisguise player. Lupus
// [zBuffer] List of player cont commands --->
{buildin_pcwalkxy,"pcwalkxy","iii"},
{buildin_pctalk,"pctalk","is"},
{buildin_pcemote,"pcemote","ii"},
{buildin_pcfollow,"pcfollow","ii"},
{buildin_pcstopfollow,"pcstopfollow","i"},
// <--- [zBuffer] List of player cont commands
// [zBuffer] List of mob control commands --->
{buildin_spawnmob,"spawnmob","*"},
{buildin_removemob,"removemob","*"},
{buildin_mobwalk,"mobwalk","*"},
{buildin_getmobdata,"getmobdata","*"},
{buildin_setmobdata,"setmobdata","*"},
{buildin_mobattack,"mobattack","*"},
{buildin_mobstop,"mobstop","*"},
{buildin_mobassist,"mobassist","*"},
{buildin_mobtalk,"mobtalk","*"},
{buildin_mobemote,"mobemote","*"},
{buildin_mobattach,"mobattach","*"},
// <--- [zBuffer] List of mob control commands
{NULL,NULL,NULL}, {NULL,NULL,NULL},
}; };
@ -9787,6 +9827,353 @@ int buildin_delmonsterdrop(struct script_state *st)
} }
*/ */
// [zBuffer] List of player cont commands --->
int buildin_pcwalkxy(struct script_state *st){
int id, x, y;
struct map_session_data *sd = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start + 2]));
x = conv_num(st, & (st->stack->stack_data[st->start + 3]));
y = conv_num(st, & (st->stack->stack_data[st->start + 4]));
if(id)
sd = map_id2sd(id);
else
sd = script_rid2sd(st);
if(sd)
pc_walktoxy(sd, x, y);
return 0;
}
int buildin_pctalk(struct script_state *st){
int id;
char *str;
char message[255];
struct map_session_data *sd = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start + 2]));
str = conv_str(st, & (st->stack->stack_data[st->start + 3]));
if(id)
sd = map_id2sd(id);
else
sd = script_rid2sd(st);
if(sd){
memcpy(message, sd->status.name, NAME_LENGTH);
strcat(message," : ");
strncat(message,str, 254); //Prevent overflow possibility. [Skotlex]
clif_message(&(sd->bl), message);
clif_displaymessage(sd->fd, message);
}
return 0;
}
int buildin_pcemote(struct script_state *st) {
int id, emo;
struct map_session_data *sd = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start + 2]));
emo = conv_num(st, & (st->stack->stack_data[st->start + 3]));
if(id)
sd = map_id2sd(id);
else
sd = script_rid2sd(st);
if(sd)
clif_emotion(&sd->bl,emo);
return 0;
}
int buildin_pcfollow(struct script_state *st) {
int id, targetid;
struct map_session_data *sd = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start + 2]));
targetid = conv_num(st, & (st->stack->stack_data[st->start + 3]));
if(id)
sd = map_id2sd(id);
else
sd = script_rid2sd(st);
if(sd)
pc_follow(sd, targetid);
return 0;
}
int buildin_pcstopfollow(struct script_state *st) {
int id;
struct map_session_data *sd = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start + 2]));
if(id)
sd = map_id2sd(id);
else
sd = script_rid2sd(st);
if(sd)
pc_stop_following(sd);
return 0;
}
// <--- [zBuffer] List of player cont commands
// [zBuffer] List of mob control commands --->
int buildin_spawnmob(struct script_state *st){
int class_,x,y,id;
char *str,*map,*event="";
struct mob_data *md = NULL;
// Who?
str =conv_str(st,& (st->stack->stack_data[st->start+2]));
// What?
class_ =conv_num(st,& (st->stack->stack_data[st->start+3]));
// Where?
map =conv_str(st,& (st->stack->stack_data[st->start+4]));
x =conv_num(st,& (st->stack->stack_data[st->start+5]));
y =conv_num(st,& (st->stack->stack_data[st->start+6]));
// When?
if( st->end > st->start+8 )
event=conv_str(st,& (st->stack->stack_data[st->start+7]));
id = mob_once_spawn(map_id2sd(st->rid),map,x,y,str,class_,1,event);
if(id){
md = (struct mob_data *)map_id2bl(id);
if(md){
md->mode = md->db->mode;
}
push_val(st->stack,C_INT,id);
}
return 0;
}
int buildin_removemob(struct script_state *st) {
int id;
struct mob_data *md = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
md = (struct mob_data *)map_id2bl(id);
if(md)
mob_delete(md);
return 0;
}
int buildin_mobwalk(struct script_state *st){
int id,x,y;
struct mob_data *md = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
x = conv_num(st, & (st->stack->stack_data[st->start+3]));
y = conv_num(st, & (st->stack->stack_data[st->start+4]));
md = (struct mob_data *)map_id2bl(id);
if(md)
push_val(st->stack,C_INT,mob_walktoxy(md,x,y,0)); // We'll use harder calculations.
return 0;
}
int buildin_getmobdata(struct script_state *st) {
int num, id;
char *name;
struct mob_data *md = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
if(!(md = (struct mob_data *)map_id2bl(id)) || st->stack->stack_data[st->start+3].type!=C_NAME ){
ShowWarning("buildin_getmobdata: Error in argiment!\n");
} else {
num=st->stack->stack_data[st->start+2].u.num;
name=(char *)(str_buf+str_data[num&0x00ffffff].str);
setd_sub(map_id2sd(st->rid),name,0,(void *)md->class_);
setd_sub(map_id2sd(st->rid),name,1,(void *)md->level);
setd_sub(map_id2sd(st->rid),name,2,(void *)md->hp);
setd_sub(map_id2sd(st->rid),name,3,(void *)md->max_hp);
setd_sub(map_id2sd(st->rid),name,4,(void *)md->master_id);
setd_sub(map_id2sd(st->rid),name,5,(void *)md->bl.m);
setd_sub(map_id2sd(st->rid),name,6,(void *)md->bl.x);
setd_sub(map_id2sd(st->rid),name,7,(void *)md->bl.y);
setd_sub(map_id2sd(st->rid),name,8,(void *)md->speed);
setd_sub(map_id2sd(st->rid),name,9,(void *)md->mode);
setd_sub(map_id2sd(st->rid),name,10,(void *)md->state.state);
setd_sub(map_id2sd(st->rid),name,11,(void *)md->special_state.ai);
setd_sub(map_id2sd(st->rid),name,12,(void *)md->db->option);
setd_sub(map_id2sd(st->rid),name,13,(void *)md->db->sex);
setd_sub(map_id2sd(st->rid),name,14,(void *)md->db->view_class);
setd_sub(map_id2sd(st->rid),name,15,(void *)md->db->hair);
setd_sub(map_id2sd(st->rid),name,16,(void *)md->db->hair_color);
setd_sub(map_id2sd(st->rid),name,17,(void *)md->db->head_buttom);
setd_sub(map_id2sd(st->rid),name,18,(void *)md->db->head_mid);
setd_sub(map_id2sd(st->rid),name,19,(void *)md->db->head_top);
setd_sub(map_id2sd(st->rid),name,20,(void *)md->db->clothes_color);
setd_sub(map_id2sd(st->rid),name,21,(void *)md->db->equip);
setd_sub(map_id2sd(st->rid),name,22,(void *)md->db->weapon);
setd_sub(map_id2sd(st->rid),name,23,(void *)md->db->shield);
setd_sub(map_id2sd(st->rid),name,24,(void *)md->dir);
}
return 0;
}
int buildin_setmobdata(struct script_state *st){
int num, id, i = 0;
char *name;
struct script_data dat;
struct mob_data *md = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
if(!(md = (struct mob_data *)map_id2bl(id)) || st->stack->stack_data[st->start+3].type!=C_NAME ){
ShowWarning("buildin_setmobdata: Error in argiment!\n");
} else {
#define INCREMENT dat.type=C_NAME; dat.u.num=add_str((unsigned char *) name)+(i<<24); get_val(st,&dat); i++
#define VALUE(x) x = (dat.u.num == -1)? x : dat.u.num
num=st->stack->stack_data[st->start+2].u.num;
name=(char *)(str_buf+str_data[num&0x00ffffff].str);
INCREMENT; VALUE(md->class_); INCREMENT; VALUE(md->level);
INCREMENT; VALUE(md->hp); INCREMENT; VALUE(md->max_hp);
INCREMENT; VALUE(md->hp); INCREMENT; VALUE(md->master_id);
INCREMENT; VALUE(md->bl.m); INCREMENT; VALUE(md->bl.x);
INCREMENT; VALUE(md->bl.y); INCREMENT; VALUE(md->speed);
INCREMENT; VALUE(md->mode); INCREMENT; VALUE(md->state.state);
INCREMENT; VALUE(md->special_state.ai); INCREMENT; VALUE(md->db->option);
INCREMENT; VALUE(md->db->sex); INCREMENT; VALUE(md->db->view_class);
INCREMENT; VALUE(md->db->hair); INCREMENT; VALUE(md->db->hair_color);
INCREMENT; VALUE(md->db->head_buttom); INCREMENT; VALUE(md->db->head_mid);
INCREMENT; VALUE(md->db->head_top); INCREMENT; VALUE(md->db->clothes_color);
INCREMENT; VALUE(md->db->equip); INCREMENT; VALUE(md->db->weapon);
INCREMENT; VALUE(md->dir);
}
return 0;
}
int buildin_mobattack(struct script_state *st) {
int id;
char *target;
struct mob_data *md = NULL;
struct map_session_data *sd = NULL;
struct block_list *bl = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
target = conv_str(st, & (st->stack->stack_data[st->start+3]));
if((sd = map_nick2sd(target)) != NULL || (bl = map_id2bl(atoi(target))) != NULL) {
if(sd) {
md = (struct mob_data *)map_id2bl(id);
if(md) {
md->target_id = sd->bl.id;
md->state.targettype = ATTACKABLE;
md->special_state.ai = 1;
md->min_chase = distance_bl(bl,&md->bl) + md->db->range2;
}
} else {
if(bl->type == BL_MOB || bl->type == BL_PC) {
md = (struct mob_data *)map_id2bl(id);
if(md) {
md->target_id = bl->id;
md->state.targettype = ATTACKABLE;
md->special_state.ai = 1;
md->min_chase = distance_bl(bl,&md->bl) + md->db->range2;
}
}
}
}
return 0;
}
int buildin_mobstop(struct script_state *st) {
int id;
struct mob_data *md = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
md = (struct mob_data *)map_id2bl(id);
if(md){
mob_stopattack(md);
mob_stop_walking(md,0);
md->master_id = md->bl.id; // Quick hack to stop random walking.
}
return 0;
}
int buildin_mobassist(struct script_state *st) {
int id;
char *target;
struct mob_data *md = NULL;
struct block_list *bl = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
target = conv_str(st, & (st->stack->stack_data[st->start+3]));
if((bl =&(map_nick2sd(target)->bl)) || (bl = map_id2bl(atoi(target)))) {
md = (struct mob_data *)map_id2bl(id);
if(md) {
md->master_id = bl->id;
if(bl->type == BL_PC)
md->target_id = map_id2sd(bl->id)->attacktarget;
else if(bl->type == BL_MOB)
md->target_id = ((struct mob_data *)bl)->target_id;
if(map_id2bl(md->target_id)){
md->state.targettype = ATTACKABLE;
md->min_chase = distance_bl(&md->bl,map_id2bl(md->target_id)) + md->db->range2;
}
}
}
return 0;
}
int buildin_mobtalk(struct script_state *st)
{
char *str;
int id;
char message[255];
struct mob_data *md = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
str=conv_str(st,& (st->stack->stack_data[st->start+3]));
md = (struct mob_data *)map_id2bl(id);
if(md) {
memcpy(message, md->name, NAME_LENGTH);
strcat(message," : ");
strncat(message,str, 254); //Prevent overflow possibility. [Skotlex]
clif_message(&(md->bl), message);
}
return 0;
}
int buildin_mobemote(struct script_state *st) {
int id, emo;
struct mob_data *md = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
emo = conv_num(st, & (st->stack->stack_data[st->start+3]));
if((md = (struct mob_data *)map_id2bl(id)))
clif_emotion(&md->bl,emo);
return 0;
}
int buildin_mobattach(struct script_state *st){
int id;
struct mob_data *md = NULL;
id = conv_num(st, & (st->stack->stack_data[st->start+2]));
if((md = (struct mob_data *)map_id2bl(id)))
md->nd = (struct npc_data *)map_id2bl(st->oid);
return 0;
}
// <--- [zBuffer] List of mob control commands
// //
// ŽÀ<C5BD>s•”main // ŽÀ<C5BD>s•”main
// //