A better way to provide parameters to 'putnpc'

So I think this should be easy achievable. At current, to provide an npc with parameters after you place it with the putnpc command, you need to issue the putnpc command, then depending on server latency, wait a certain amount of time before issuing a ‘callnpc’ or triggeraction. This isn’t ideal at all.

My proposal is the introduction of a new triggerhack called gr.placenpc. Example usage is as follows

triggeraction x,y,gr.placenpc,params;

Once placed, the server will issue a callnpc with the flag ‘placed’ such that params can then be retrieved as follows.

if ( placed )
{
  setstring this.param0,#p(0);
  ....
  setstring this.paramN,#p(n); 
}

Where n is some arbitrary number.

You came up with something that should be possible this time! …except for the second part about a “callnpc” trigger. That would be a clientside thing in which any flag updates also stay local. The only thing the client sends to the server to synchronize is save[] data and server flags. (Possibly most #P and appearance-specific attributes as well, but I’m not sure, it’s been too long.)

If using callnpc wasn’t possible, how about a triggeraction generated by the server?

That could work, but I’m honestly not sure how the client and server handle triggeraction. But even if it’s doable, who’s going to make the change?

tricxta can do it

Aren’t the triggeraction hacks, just that?

from the looks of it, the triggeraction hacks are just intercepted on the serverside and handled appropriately, I don’t think there’s any kind of manipulation to the actual action itself.

___Merged doublepost__________________

It’s looking like it’ll go down that way. My only concern is I’ll effectively be hacking a solution given my lack of knowledge in the gserver domain. I hope if I document my methodology in this thread though that if I’ve made a wrong turn it’ll at least be picked up and corrected.

if (action.find("gr.placenc") == 0)
{
		int start = action.find(",");
		if (start != -1)
		{
			std::vector<CString> params = action.tokenize(",");
			CString code = server->getFileSystem(0)->load(params[1]);
			code.removeAllI("\\r");
			code.replaceAllI("\
", "\\xa7");

			// Add NPC to level
			TNPC* npc = server->addNPC(CString(), code, loc[0], loc[1], level, true, true);

			server->sendPacketToLevel(CString() >> (char)msgPLI_TRIGGERACTION >> npc->getId >> loc[0] >> loc[1] >> "placed" >> params, level, this);
		}
}

Not semantically correct, but this approach seems too trivial surely?

I’ve not really done a whole lot aside from fix the integer conversion functions in the server code. So I couldn’t even tell you if what you’re doing is right or wrong.

Couldn’t you use level.strings to temporarily send params to the placed NPC using the built-in command?

What if I want to send 3 different npcs simultaneously with 3 lots of different parameters. Sure, I can hack a solution, but… no one likes bugs, so that’s not a good idea.

___Merged doublepost__________________

I’ll see if I can get in touch with Nalin.

level.putnpcPoop=1,2,3,3,4,apple,orange,5,6,7
level.putnpcShit=tricxta
level.putnpcRetard=8,7,6,5,4,tyrant,3,2,1

How is the retard npc suppose to know its retarded instead of shit?

Good question… Given this thread is bringing little light to the subject, I suppose I’ll just further my attempts to develop a solution and post any further advancements.

You could do what spooon suggested if you use timestamps as identifiers.

… No, it’s just a hack, on top of that, it doesn’t actually meet the solution to the current problem I’m trying to solve. It’d also involve a whole heap of redundant code which I think is absolutely digusting. It’s nothing but horrible.
It’s in everyone’s best interests if hacks like this were avoided, unless you like the forever accumulating nature of bugs in server development?

What kind of stuff are you trying to place that you can’t use a string to send information to it?

Let’s say we want to place npcs and treat them as projectiles, thus we’re looking at placing quite a few(maybe 3) at in one time.

Using the method you proposed we’d need to set level variables such that it’d be something like

level.bullet1 = some number that's meant to be useful;
level.bullet2 = some number that's meant to be useful;
.....
level.bulletn = some number that's meant to be useful;

Then I need to have an npc script for each such that they run off their respective strings.

On top of this, it doesn’t even have to be at once which will present a problem given there’s a certain amount of latency between using putnpc and it actually being placed by the server.
Main point of the matter is it’s a dirty hack and if it could be avoided, why not invest the effort now instead of having to build a forever accumulating pile of disgusting scripts for that one problem you thought you’d “save time” on.

Hm.

Push param, place NPC, pop param.