Jump to content
Garr

NPC masking

Recommended Posts

File Name: npcmask
File Submitter: Garr
File Submitted: 10 Oct 2014
File Category: Plugins

 

Masks NPCs on player's client based on his/her variables. Will need to leave NPC sight range/@refresh for it to trigger (if you change variable while NPC is still in sight nothing will change, but @refresh/leaving screen and entering again will trigger mask).
 

Usage:

npcmask <new sprite>,<int variable name>,<compare method>,<value1>,{<value 2>,{<new size>,{<new name>,{<npc name>}}}}npcunmask {<npc name>}

 

Applies and removes NPC masking, accordingly.

<new sprite> - sprite NPC will show if conditions are met

<int variable name> - variable name to check, only integer character variables.

<compare method> - compare method, based on following masks (v - variable, a- value1, b - value2)
0x01 - Less, uses value1 (v < a)
0x02 - Equal, uses value1 (v == a)
0x04 - More, uses value1 (v > a)
0x10 - "BETWEEN" - Between value1 and value2, including values 1 and 2 (a <= v <= b )
0x20 - "EXCLUDE" - Excluding between value1 and value2, values 1 and 2 are excluded also. (v < a OR v > b )
Example: 0x03 - same as less or equal, makes a check (v <= a)
"BETWEEN" and "EXCLUDE" methods overwrite anything else, "EXCLUDE" will take precedence over all other methods.

<value1> - value1 to compare too, used in all compare methods.

<value2> - value2, used in "BETWEEN" and "EXCLUDE" modes. Optional parameter, if it won't be provided
while using "BETWEEN" or "EXCLUDE" methods, those methods will be skipped.

<new size> - size masking, defaults to medium size.

<new name> - name masking, if not provided will use NPC's original name.

<npc name> - NPC name to use masking on. If not provided, will be used on NPC script is running from.

 

This plugin appeared from the idea of hiding NPCs from some players, while it still being visible to others. It's just added in functionality.

 

You can download the file here.

 

OR

 

You can copy it from here.

Edited by Garr

Share this post


Link to post
Share on other sites

Oh this would be very useful for quest type scripts where a player completes a certain phase and such. Like also making a player have access to a shop based on whether or not the did X or Y. Instead of just having the NPC be unresponsive or say something like you can't use this. Nice work.

Share this post


Link to post
Share on other sites

Mhmmm... Quick question without having the plugin installed yet. Can you make the NPC look as if it was gone by masking as the -1 sprite and rendering it unclickable?

Share this post


Link to post
Share on other sites

Maybe not -1 sprite, but you could go with the ( i think 111? or 139 *think this is the hidden warp portal* ). But the difference would be your hiding it to ALL players by just simply changing the sprite. With the masking it'd be only certain players.

 

But yes, it would be possible to simulate this effect somewhat using sprite id 111 and variable check to just end the script.

 

Edit: Oh lol, i see your asking about using the sprite in combination with the plugin (you just didn't install it yet -.-; feel like an idiot now lol !!) but the same methods should still apply by simply using 111 as the sprite id if -1 doesn't work.

Edited by GmOcean

Share this post


Link to post
Share on other sites

Yes, you can hide it, but by using 139 as sprite, not 111. 111 is invisible NPC with speech bubble, 139 is completely invisible :)

Share this post


Link to post
Share on other sites

Added in upaste mirror. And it's a plugin, used with HPM. If there will be requests of such I might make a source mod diff for it, but not today.

Share this post


Link to post
Share on other sites

Added in upaste mirror. And it's a plugin, used with HPM. If there will be requests of such I might make a source mod diff for it, but not today.

I got these compile warnings
1>d:hercsrcpluginspscript.c(1273): error C2065: 'CM_LESS' : undeclared identifier1>d:hercsrcpluginspscript.c(1275): error C2065: 'CM_EQU' : undeclared identifier1>d:hercsrcpluginspscript.c(1277): error C2065: 'CM_MORE' : undeclared identifier1>d:hercsrcpluginspscript.c(1279): error C2065: 'CM_BETWEEN' : undeclared identifier1>d:hercsrcpluginspscript.c(1281): error C2065: 'CM_EXCLUDE' : undeclared identifier1>d:hercsrcpluginspscript.c(1375): error C2065: 'CM_LESS' : undeclared identifier1>d:hercsrcpluginspscript.c(1377): error C2065: 'CM_EQU' : undeclared identifier1>d:hercsrcpluginspscript.c(1379): error C2065: 'CM_MORE' : undeclared identifier1>d:hercsrcpluginspscript.c(1381): error C2065: 'CM_BETWEEN' : undeclared identifier1>d:hercsrcpluginspscript.c(1383): error C2065: 'CM_EXCLUDE' : undeclared identifier1>d:hercsrcpluginspscript.c(1431): error C2065: 'CM_LESS' : undeclared identifier1>d:hercsrcpluginspscript.c(1431): error C2065: 'CM_LESS' : undeclared identifier1>d:hercsrcpluginspscript.c(1432): error C2065: 'CM_EQU' : undeclared identifier1>d:hercsrcpluginspscript.c(1432): error C2065: 'CM_EQU' : undeclared identifier1>d:hercsrcpluginspscript.c(1433): error C2065: 'CM_MORE' : undeclared identifier1>d:hercsrcpluginspscript.c(1433): error C2065: 'CM_MORE' : undeclared identifier1>d:hercsrcpluginspscript.c(1434): error C2065: 'CM_BETWEEN' : undeclared identifier1>d:hercsrcpluginspscript.c(1436): error C2065: 'CM_BETWEEN' : undeclared identifier1>d:hercsrcpluginspscript.c(1441): error C2065: 'CM_EXCLUDE' : undeclared identifier1>d:hercsrcpluginspscript.c(1443): error C2065: 'CM_EXCLUDE' : undeclared identifier1>d:hercsrcpluginspscript.c(1493): error C2065: 'CM_LESS' : undeclared identifier1>d:hercsrcpluginspscript.c(1493): error C2065: 'CM_LESS' : undeclared identifier1>d:hercsrcpluginspscript.c(1494): error C2065: 'CM_EQU' : undeclared identifier1>d:hercsrcpluginspscript.c(1494): error C2065: 'CM_EQU' : undeclared identifier1>d:hercsrcpluginspscript.c(1495): error C2065: 'CM_MORE' : undeclared identifier1>d:hercsrcpluginspscript.c(1495): error C2065: 'CM_MORE' : undeclared identifier1>d:hercsrcpluginspscript.c(1496): error C2065: 'CM_BETWEEN' : undeclared identifier1>d:hercsrcpluginspscript.c(1498): error C2065: 'CM_BETWEEN' : undeclared identifier1>d:hercsrcpluginspscript.c(1503): error C2065: 'CM_EXCLUDE' : undeclared identifier1>d:hercsrcpluginspscript.c(1505): error C2065: 'CM_EXCLUDE' : undeclared identifier========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
Edited by Angelmelody

Share this post


Link to post
Share on other sites

I see that you copied it into some kind of bigger plugin for scripting, maybe you missed the enum part? Make sure it's there:

enum compare_method {	CM_NONE = 0x00,	CM_LESS = 0x01,	CM_EQU = 0x02,	CM_MORE = 0x04,	CM_BETWEEN = 0x10,	CM_EXCLUDE = 0x20,	CM_MAX = 0x37,} c_m;

Otherwise I'm somewhat at a loss why it'd throw that at you.

Share this post


Link to post
Share on other sites

 

I see that you copied it into some kind of bigger plugin for scripting, maybe you missed the enum part? Make sure it's there:

enum compare_method {	CM_NONE = 0x00,	CM_LESS = 0x01,	CM_EQU = 0x02,	CM_MORE = 0x04,	CM_BETWEEN = 0x10,	CM_EXCLUDE = 0x20,	CM_MAX = 0x37,} c_m;
Otherwise I'm somewhat at a loss why it'd throw that at you.

Nope,I'm pretty sure that enum exists....

 

I try to replace CM_  with CMP ,then those compile warnings dispear ,but still have another warnings

enum compare_method {    CM_NONE = 0x00,    CM_LESS = 0x01,    CM_EQU = 0x02,    CM_MORE = 0x04,    CM_BETWEEN = 0x10,    CM_EXCLUDE = 0x20,    CM_MAX = 0x37,} c_m;
enum compare_method {    CMP_NONE = 0x00,    CMP_LESS = 0x01,    CMP_EQU = 0x02,    CMP_MORE = 0x04,    CMP_BETWEEN = 0x10,    CMP_EXCLUDE = 0x20,    CMP_MAX = 0x37,} ;

 

another warnings :

 

1>------ Rebuild All started: Project: plugin-script, Configuration: Debug Win32 ------

1> pscript.c

1> Creating library ..pluginsplugin-script.lib and object ..pluginsplugin-script.exp

1>pscript.obj : error LNK2019: unresolved external symbol _assert_report referenced in function _clif_set_unit_idle_hooked

1>..pluginsplugin-script.dll : fatal error LNK1120: 1 unresolved externals

========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

 

Edited by Angelmelody

Share this post


Link to post
Share on other sites

Hmm, try adding this

#define pcdb_checkid_sub(class_) ( 	( (class_) <  JOB_MAX_BASIC ) ||	( (class_) >= JOB_NOVICE_HIGH    && (class_) <= JOB_DARK_COLLECTOR ) ||	( (class_) >= JOB_RUNE_KNIGHT    && (class_) <= JOB_MECHANIC_T2    ) ||	( (class_) >= JOB_BABY_RUNE      && (class_) <= JOB_BABY_MECHANIC2 ) ||	( (class_) >= JOB_SUPER_NOVICE_E && (class_) <= JOB_SUPER_BABY_E   ) ||	( (class_) >= JOB_KAGEROU        && (class_) <= JOB_OBORO          ) ||	( (class_) >= JOB_REBELLION      && (class_) <  JOB_MAX            ) )#define pcdb_checkid(class_) pcdb_checkid_sub((unsigned int)(class_))

inside. What version are you using to compile?

Share this post


Link to post
Share on other sites

 

Hmm, try adding this

#define pcdb_checkid_sub(class_) ( 	( (class_) <  JOB_MAX_BASIC ) ||	( (class_) >= JOB_NOVICE_HIGH    && (class_) <= JOB_DARK_COLLECTOR ) ||	( (class_) >= JOB_RUNE_KNIGHT    && (class_) <= JOB_MECHANIC_T2    ) ||	( (class_) >= JOB_BABY_RUNE      && (class_) <= JOB_BABY_MECHANIC2 ) ||	( (class_) >= JOB_SUPER_NOVICE_E && (class_) <= JOB_SUPER_BABY_E   ) ||	( (class_) >= JOB_KAGEROU        && (class_) <= JOB_OBORO          ) ||	( (class_) >= JOB_REBELLION      && (class_) <  JOB_MAX            ) )#define pcdb_checkid(class_) pcdb_checkid_sub((unsigned int)(class_))
inside. What version are you using to compile?

my git version is 9ab4f84 and compiling under MSVC 2010

 

I comment out all the nullpo_retv(bl) lines , compiling is successful now

 

edit :

report a bug

<new name> - name masking, if not provided will use empty name.

my test script

npcmask 1002,"abc",0x02,1,2,2;
Edited by Angelmelody

Share this post


Link to post
Share on other sites

That's odd, I thought it counts null string as a null and shouldn't pull this off. Find:

	if (flag && nm->nmask ) {		memcpy(WBUFP(buf,6), nm->nmask, NAME_LENGTH);	} else {		memcpy(WBUFP(buf,6), ((TBL_NPC*)bl)->name, NAME_LENGTH);	}

And replace with

    if (flag && nm->nmask != "0") {        memcpy(WBUFP(buf,6), nm->nmask, NAME_LENGTH);    } else {        memcpy(WBUFP(buf,6), ((TBL_NPC*)bl)->name, NAME_LENGTH);    }

 


EDIT: Updated upaste link in opening post.

Edited by Garr

Share this post


Link to post
Share on other sites

That's odd, I thought it counts null string as a null and shouldn't pull this off. Find:

	if (flag && nm->nmask ) {		memcpy(WBUFP(buf,6), nm->nmask, NAME_LENGTH);	} else {		memcpy(WBUFP(buf,6), ((TBL_NPC*)bl)->name, NAME_LENGTH);	}
And replace with
    if (flag && nm->nmask != "0") {        memcpy(WBUFP(buf,6), nm->nmask, NAME_LENGTH);    } else {        memcpy(WBUFP(buf,6), ((TBL_NPC*)bl)->name, NAME_LENGTH);    }
 

 

EDIT: Updated upaste link in opening post.

 

 

Thanks, but still display empty name if you dont provide param <new name>

 

 my method is to use nd->name

if ( script_hasdata(st,8) ) {if ( script_isstringtype(st,8) ) {varn2 = script_getstr(st,8);safestrncpy(nm->nmask, varn2, NAME_LENGTH);}} else {safestrncpy(nm->nmask, nd->name, NAME_LENGTH);}
 then
			if (flag && nm->nmask ) 				memcpy(WBUFP(buf,6), nm->nmask, NAME_LENGTH);			else				memcpy(WBUFP(buf,6), nd->name, NAME_LENGTH);
 

 

,and then I m a little bit nosy, and think it would be better if just use removeFromNPCD , hope you dont mind :)

 

 

BUILDIN(npcunmask) {	struct npc_mask *nm;	struct npc_data *nd;	if( script_hasdata(st,2) )		nd = npc->name2id(script_getstr(st,2));	else 		nd = map->id2nd(st->oid);	if( nd == NULL ) {		script_pushint(st,-1); //No such NPC;		return true;	}	if((nm = getFromNPCD(nd,0)))		removeFromNPCD(nd,0);	script_pushint(st,1);	return true;}

 

btw,hookstop must be inside an if-condition or you will cause unnecessary trouble

 

 

if ((nm = getFromNPCD(nd,0))) {............hookStop();}

 

 

for example

 

	if (bl->type == BL_NPC){		struct npc_data *nd = (TBL_NPC*)bl;		struct npc_mask *nm;		if ((nm = getFromNPCD(nd,0))) {			unsigned char buf[103];			int var;			bool flag = false;			WBUFW(buf,0) = 0x95;			WBUFL(buf,2) = bl->id;			var = pc_readglobalreg(sd, script->add_str(nm->varname));			if ( nm->masked && nm->compare) { //Not checking var or nm->value1/2 to make usage of variables resulting in 0 possible, or to compare with 0.				if (nm->compare&CMP_LESS && var < nm->value1)					flag = true;				if (nm->compare&CMP_EQU && var == nm->value1)					flag = true;				if (nm->compare&CMP_MORE && var > nm->value1)					flag = true;				if ( nm->compare&CMP_BETWEEN && var >= nm->value1 && var <= nm->value2 )					flag = true;				if ( nm->compare&CMP_EXCLUDE && (var < nm->value1 || var > nm->value2) )					flag = true;			}			if (flag && nm->nmask ) 				memcpy(WBUFP(buf,6), nm->nmask, NAME_LENGTH);			else				memcpy(WBUFP(buf,6), nd->name, NAME_LENGTH);				WFIFOHEAD(sd->fd, 30);			memcpy(WFIFOP(sd->fd, 0), buf, 30);			WFIFOSET(sd->fd, 30);			hookStop();				}	}

 

Edited by Angelmelody

Share this post


Link to post
Share on other sites

Updated links with your suggestions, thank you very much. It's first time I ever I make a plugin, not to mention I never really worked with C++ or C before. So had to go with guessing game sometimes.
 
Also, about last suggestion with it being inside if, won't the ifs before that prevent it from triggering by returning to main function before the hookStop()?
 
Because this:

if ( bl->type == BL_NPC ) { ...code with hookStop()...}return;

Seems same with:

if (bl->type != BL_NPC)	return;...code with hookStop()...

 
Also, found a solution for nullpo not linking:
RMB on project, Properties , and change Configuration to "Release" for this plugin.

2lmozsh.jpg

Share this post


Link to post
Share on other sites

I'd like report a  small typo bug ,That's the duplicate  'case 0x088A'  ,but it won't show any compile warnings

if your PACKETVER  <=20140402 ,or it will...

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.