Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated npcspeed, npcwalkto and npcstop script commands #8354

Merged
merged 11 commits into from
Jun 16, 2024
17 changes: 7 additions & 10 deletions doc/script_commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7961,17 +7961,15 @@ Return values:
//
---------------------------------------

*npcspeed <speed value>;
*npcwalkto <x>,<y>;
*npcstop;
*npcspeed( <speed value> {,"<npc name>"} );
*npcwalkto( <x>,<y> {,"<speed value>" {,"<npc name>"} } );
*npcstop( {"<npc name>"} );

These commands will make the NPC object in question move around the map. As they
currently are, they are a bit buggy and are not useful for much more than making
an NPC move randomly around the map.
These commands will make the NPC object in question move around the map.

'npcspeed' will set the NPCs walking speed to a specified value. As in the
@speed GM command, 200 is the slowest possible speed while 0 is the fastest
possible (instant motion). 100 is the default character walking speed.
@speed GM command, MAX_WALK_SPEED (1000) is the slowest possible speed while MIN_WALK_SPEED (20) is the fastest
possible (instant motion). DEFAULT_NPC_WALK_SPEED (200) is the default npc walking speed.
Atemo marked this conversation as resolved.
Show resolved Hide resolved

'npcwalkto' will start the NPC sprite moving towards the specified coordinates
on the same map it is currently on. The script proceeds immediately after the
Expand All @@ -7981,8 +7979,7 @@ NPC begins moving.

While in transit, the NPC will be clickable, but invoking it will cause it to
stop moving, which will make its coordinates different from what the client
computed based on the speed and motion coordinates. The effect is rather
unnerving.
computed based on the speed and motion coordinates.

Only a few NPC sprites have walking animations, and those that do, do not get
the animation invoked when moving the NPC, due to the problem in the NPC walking
Expand Down
3 changes: 2 additions & 1 deletion src/common/mmo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ typedef uint32 t_itemid;
#define MAX_FAME 1000000000 ///Max fame points
#define MAX_CART 100 ///Maximum item in cart
#define MAX_SKILL 1623 ///Maximum skill can be hold by Player, Homunculus, & Mercenary (skill list) AND skill_db limit
#define DEFAULT_WALK_SPEED 150 ///Default walk speed
#define DEFAULT_WALK_SPEED 150 ///Default walk speed (other than NPC)
#define DEFAULT_NPC_WALK_SPEED 200 ///Default NPC walk speed
#define MIN_WALK_SPEED 20 ///Min walk speed
#define MAX_WALK_SPEED 1000 ///Max walk speed
#define MAX_STORAGE 600 ///Max number of storage slots a player can have
Expand Down
2 changes: 1 addition & 1 deletion src/map/mob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ void mvptomb_create(struct mob_data *md, char *killer, time_t time)
safestrncpy(nd->name, msg_txt(nullptr,656), sizeof(nd->name));

nd->class_ = 565;
nd->speed = 200;
nd->speed = DEFAULT_NPC_WALK_SPEED;
nd->subtype = NPCTYPE_TOMB;

nd->u.tomb.md = md;
Expand Down
16 changes: 8 additions & 8 deletions src/map/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ void BarterDatabase::loadingFinished(){
npc_parsename( nd, barter->name.c_str(), nullptr, nullptr, __FILE__ ":" QUOTE(__LINE__) );

nd->class_ = barter->sprite;
nd->speed = 200;
nd->speed = DEFAULT_NPC_WALK_SPEED;

nd->bl.type = BL_NPC;
nd->subtype = NPCTYPE_BARTER;
Expand Down Expand Up @@ -3824,7 +3824,7 @@ struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short
nd->class_ = JT_GUILD_FLAG;
else
nd->class_ = JT_WARPNPC;
nd->speed = 200;
nd->speed = DEFAULT_NPC_WALK_SPEED;

nd->u.warp.mapindex = to_mapindex;
nd->u.warp.x = to_x;
Expand Down Expand Up @@ -3896,7 +3896,7 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const
nd->class_ = JT_WARPNPC;
else
nd->class_ = JT_GUILD_FLAG;
nd->speed = 200;
nd->speed = DEFAULT_NPC_WALK_SPEED;

nd->u.warp.mapindex = i;
nd->u.warp.x = to_x;
Expand Down Expand Up @@ -4180,7 +4180,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const

npc_parsename(nd, w3, start, buffer, filepath);
nd->class_ = m == -1 ? JT_FAKENPC : npc_parseview(w4, start, buffer, filepath);
nd->speed = 200;
nd->speed = DEFAULT_NPC_WALK_SPEED;

++npc_shop;
nd->bl.type = BL_NPC;
Expand Down Expand Up @@ -4418,7 +4418,7 @@ static const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, cons

npc_parsename(nd, w3, start, buffer, filepath);
nd->class_ = m == -1 ? JT_FAKENPC : npc_parseview(w4, start, buffer, filepath);
nd->speed = 200;
nd->speed = DEFAULT_NPC_WALK_SPEED;
nd->u.scr.script = script;
nd->u.scr.label_list = label_list;
nd->u.scr.label_list_num = label_list_num;
Expand Down Expand Up @@ -4557,7 +4557,7 @@ const char* npc_parse_duplicate( char* w1, char* w2, char* w3, char* w4, const c
nd = npc_create_npc(m, x, y);
npc_parsename(nd, w3, start, buffer, filepath);
nd->class_ = m == -1 ? JT_FAKENPC : npc_parseview(w4, start, buffer, filepath);
nd->speed = 200;
nd->speed = DEFAULT_NPC_WALK_SPEED;
nd->src_id = src_id;
nd->bl.type = BL_NPC;
nd->subtype = (enum npc_subtype)type;
Expand Down Expand Up @@ -4690,7 +4690,7 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
safestrncpy(wnd->name, "", ARRAYLENGTH(wnd->name));
safestrncpy(wnd->exname, newname, ARRAYLENGTH(wnd->exname));
wnd->class_ = JT_WARPNPC;
wnd->speed = 200;
wnd->speed = DEFAULT_NPC_WALK_SPEED;
wnd->u.warp.mapindex = map_id2index(imap);
wnd->u.warp.x = snd->u.warp.x;
wnd->u.warp.y = snd->u.warp.y;
Expand Down Expand Up @@ -6237,7 +6237,7 @@ void do_init_npc(void){
// Init dummy NPC
fake_nd = npc_create_npc( -1, 0, 0 );
fake_nd->class_ = JT_FAKENPC;
fake_nd->speed = 200;
fake_nd->speed = DEFAULT_NPC_WALK_SPEED;
strcpy(fake_nd->name,"FAKE_NPC");
memcpy(fake_nd->exname, fake_nd->name, 9);

Expand Down
107 changes: 82 additions & 25 deletions src/map/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16064,49 +16064,106 @@ BUILDIN_FUNC(chatmes)
return SCRIPT_CMD_SUCCESS;
}

// change npc walkspeed [Valaris]
/**
* Change npc walkspeed.
* npcspeed <speed value> {,"<npc name>"};
*/
BUILDIN_FUNC(npcspeed)
{
struct npc_data* nd;
int speed;
npc_data* nd;

speed = script_getnum(st,2);
nd =(struct npc_data *)map_id2bl(st->oid);
if (script_hasdata(st, 3))
nd = npc_name2id(script_getstr(st, 3));
else
nd = map_id2nd(st->oid);

if( nd ) {
nd->speed = speed;
nd->ud.state.speed_changed = 1;
if (nd == nullptr) {
if (script_hasdata(st, 3))
ShowError("buildin_npcspeed: %s is a non-existing NPC.\n", script_getstr(st, 3));
else
ShowError("buildin_npcspeed: non-existing NPC.\n");
return SCRIPT_CMD_FAILURE;
}

int speed = script_getnum(st, 2);

if (speed < MIN_WALK_SPEED || speed > MAX_WALK_SPEED) {
ShowError("buildin_npcspeed: invalid speed %d (min: %d, max: %d).\n", speed, MIN_WALK_SPEED, MAX_WALK_SPEED);
return SCRIPT_CMD_FAILURE;
}

nd->speed = speed;
nd->ud.state.speed_changed = 1;

return SCRIPT_CMD_SUCCESS;
}
// make an npc walk to a position [Valaris]

/**
* Make an npc walk to a position.
* npcwalkto <x>,<y> {,"<speed>" {,"<npc name>"} };
*/
BUILDIN_FUNC(npcwalkto)
{
struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
int x=0,y=0;
npc_data* nd;

x=script_getnum(st,2);
y=script_getnum(st,3);
if (script_hasdata(st, 5))
nd = npc_name2id(script_getstr(st, 5));
else
nd = map_id2nd(st->oid);

if(nd) {
if (!nd->status.hp)
status_calc_npc(nd, SCO_FIRST);
if (nd == nullptr) {
if (script_hasdata(st, 5))
ShowError("buildin_npcwalkto: %s is a non-existing NPC.\n", script_getstr(st, 5));
else
status_calc_npc(nd, SCO_NONE);
unit_walktoxy(&nd->bl,x,y,0);
ShowError("buildin_npcwalkto: non-existing NPC.\n");
return SCRIPT_CMD_FAILURE;
}

if (script_hasdata(st, 4)) {
int speed = script_getnum(st, 4);

if (speed < MIN_WALK_SPEED || speed > MAX_WALK_SPEED) {
ShowError("buildin_npcwalkto: invalid speed %d (min: %d, max: %d).\n", speed, MIN_WALK_SPEED, MAX_WALK_SPEED);
return SCRIPT_CMD_FAILURE;
}
nd->speed = speed;
nd->ud.state.speed_changed = 1;
}
Atemo marked this conversation as resolved.
Show resolved Hide resolved

int x = script_getnum(st, 2);
int y = script_getnum(st, 3);
Atemo marked this conversation as resolved.
Show resolved Hide resolved

if (!nd->status.hp)
status_calc_npc(nd, SCO_FIRST);
else
status_calc_npc(nd, SCO_NONE);
unit_walktoxy(&nd->bl,x,y,0);

return SCRIPT_CMD_SUCCESS;
}

// stop an npc's movement [Valaris]
/**
* Stop an npc's movement.
* npcstop {"<npc name>"} };
*/
BUILDIN_FUNC(npcstop)
{
struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
npc_data* nd;

if(nd) {
unit_stop_walking(&nd->bl,1|4);
if (script_hasdata(st, 2))
nd = npc_name2id(script_getstr(st, 2));
else
nd = map_id2nd(st->oid);

if (nd == nullptr) {
if (script_hasdata(st, 2))
ShowError("buildin_npcstop: %s is a non-existing NPC.\n", script_getstr(st, 2));
else
ShowError("buildin_npcstop: non-existing NPC.\n");
return SCRIPT_CMD_FAILURE;
}
unit_stop_walking( &nd->bl, USW_FIXPOS | USW_MOVE_FULL_CELL | USW_FORCE_STOP );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just because I see that you added USW_FORCE_STOP here.
Do we want to make flag a parameter?


return SCRIPT_CMD_SUCCESS;
}

Expand Down Expand Up @@ -27584,9 +27641,9 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(mobcount,"ss"),
BUILDIN_DEF(getlook,"i?"),
BUILDIN_DEF(getsavepoint,"i?"),
BUILDIN_DEF(npcspeed,"i"), // [Valaris]
BUILDIN_DEF(npcwalkto,"ii"), // [Valaris]
BUILDIN_DEF(npcstop,""), // [Valaris]
BUILDIN_DEF(npcspeed,"i?"),
BUILDIN_DEF(npcwalkto,"ii??"),
BUILDIN_DEF(npcstop,"?"),
BUILDIN_DEF(getmapxy,"rrr??"), //by Lorky [Lupus]
BUILDIN_DEF(mapid2name,"i"),
BUILDIN_DEF(checkoption1,"i?"),
Expand Down
5 changes: 5 additions & 0 deletions src/map/script_constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10634,6 +10634,11 @@
export_constant(IWA_NONE);
export_constant(IWA_NOTDEAD);

/* npcspeed command */
export_constant(MIN_WALK_SPEED);
export_constant(MAX_WALK_SPEED);
export_constant(DEFAULT_NPC_WALK_SPEED);

/* skill hit */
export_constant(DMG_SINGLE);
export_constant(DMG_MULTI_HIT);
Expand Down