Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   NPC Scripting (https://forums.graalonline.com/forums/forumdisplay.php?f=8)
-   -   Npc to Npc (https://forums.graalonline.com/forums/showthread.php?t=134261937)

kingcj 02-03-2011 03:39 AM

Npc to Npc
 
I've been trying to get an NPC to communicate with another. (such as touching one affects the other) Trigger doesn't seem to work, and I am unable to get callnpc to work either. I don't know if it is the way I am doing it or how it's called...

ffcmike 02-03-2011 03:47 AM

PHP Code:

//Set a reference for the NPC
function onCreated(){
  
this.level.somename this;
}

function 
onPlayerTouchsMe(){
  
//this.level.someothername being the reference for the opposite NPC
  
this.level.someothername.wasTouched();
}

public function 
wasTouched(){
  
//stuff


Just have to make 2 npcs with this script and make sure to set the necessary variable names.

CallNPC is really a relic from pre npcserver/pre GS2 days, may still work Clientside but it's somewhat deprecated.

fowlplay4 02-03-2011 03:52 AM

You can use getareanpcs(float, float, float, float) and loop through and find the NPC by a unique id or joined class even.

Baddies find other baddies, I.e:

PHP Code:

// Loop through NPCs in a 64x64 square around the npc.
for (temp.ngetareanpcs(this.32this.326464)) {
  
// Check if NPC is part of the Baddy class
  
if (temp.n.joinedclasses.index("baddy") >= 0) {
    
// Add NPC to Baddies Array for Further Processing
    
temp.baddies.add(temp.n);
  }
}
for (
temp.baddytemp.baddies) {
  echo(
"Baddy Found: " temp.baddy.nick);


When you have the NPC object, you can simply send triggers or call public functions. I.e:

PHP Code:

// Loop through NPCs in a 64x64 square around the npc.
for (temp.ngetareanpcs(this.32this.326464)) {
  
temp.n.trigger("Found""");


then in the other NPCs:

PHP Code:

function onFound() {
  echo(
"Found: " this.nick);



kingcj 02-03-2011 04:09 AM

I believe ffcmike's explaination is sufficient, however I'm unsure of the this.level.var. Do i insert the level name here or npc? I'm confused as to how to implement in the level... I tried in the script and it comes back as it can't find this.level.someothername.wasTouched (I tried different names in my script, just guess and test with no luck)

ffcmike 02-03-2011 04:14 AM

"this.level" you leave the same, the "somename" part is up to you, you just need to make sure that whatever name is being referred to in one NPC is the specified reference name for the opposite NPC.

kingcj 02-03-2011 04:45 AM

Yes I understand that, but the reference name is confusing? I place the this.level.var which is what the player would touch, then in the other NPC this.level.var is triggered to hide the image? I'm still very confused, please enlighten me.

ffcmike 02-03-2011 04:46 AM

I believe "var" is a protected variable name, try something else.

kingcj 02-03-2011 04:48 AM

thats just in my example on forums

ffcmike 02-03-2011 04:55 AM

Maybe show your current script of the 2 NPCs?

Should be as simple as this:

NPC 1
PHP Code:

function onCreated(){
  
this.level.obj1 this;
}

function 
onPlayerTouchsMe(){
  
this.level.obj2.wasTouched();
}

public function 
wasTouched(){
  
this.hide();


NPC 2
PHP Code:

function onCreated(){
  
this.level.obj2 this;
}

function 
onPlayerTouchsMe(){
  
this.level.obj1.wasTouched();
}

public function 
wasTouched(){
  
this.hide();



kingcj 02-03-2011 05:10 AM

Yea thats how I was doing it, but I get this error and it's the same with mine and yours... : Script: Function obj2.wasTouched not found at line 6 of explodeswitch in script of npcs[0] (in level zie_scripttest.nw at pos (39, 32))

ffcmike 02-03-2011 05:37 AM

Strangest thing actually, I tried it myself and it seemed to be doing nothing at all despite all of my echo's suggesting it was working, I then reconnect to find that the NPC was indeed being hidden just for some reason this was not being sent to the player so it remained visible on my client, this is something Stefan should probably look into.

You can always just to this Clientside if this is a single player thing.

kingcj 02-03-2011 05:44 AM

lol.. I didn't think I was crazy.. so just clientside the whole script?

ffcmike 02-03-2011 05:47 AM

This definitely works clientside.

kingcj 02-03-2011 05:56 AM

Thanks mike, sucked it took like 2hrs to do something so simple lol

kingcj 02-03-2011 09:28 AM

Kinda on the same note I am now trying to lay an npc down and have it affect another npc while it is there. again should i trigger an action? I am unsure of this process, but I am trying to affect the npc clientside. I may have to do it serverside?

kingcj 02-03-2011 09:48 AM

Yeah I still can't get it to work. I have a custom bomb that explodes and when it explodes I want it to hit a switch that triggers something else. I'm just not sure how to send it...

Cubical 02-03-2011 09:50 AM

does this.gmap.blah work aswell so a variable can be pulled from anywhere on the gmap?

kingcj 02-03-2011 10:00 AM

i don't really know... I do know that this.level works (Clientside) but with the bomb I would think that it would be easier to just add a trigger? or a public function (which I'm not completely sure i know how or what to do with besides placing in all npcs involved). Since the bomb is added via putnpc2, but I don't really know..

adam 02-03-2011 05:05 PM

Quote:

Originally Posted by ffcmike (Post 1627521)
Strangest thing actually, I tried it myself and it seemed to be doing nothing at all despite all of my echo's suggesting it was working, I then reconnect to find that the NPC was indeed being hidden just for some reason this was not being sent to the player so it remained visible on my client, this is something Stefan should probably look into.

You can always just to this Clientside if this is a single player thing.

I've encountered that problem before. Try calling a function to force an update to all players. I think I used the move function without actually moving the npc. Just a hack, but it should work. Changing visibility should force the same update.... but it doesn't.

fowlplay4 02-03-2011 05:16 PM

Quote:

Originally Posted by adam (Post 1627563)
I've encountered that problem before. Try calling a function to force an update to all players. I think I used the move function without actually moving the npc. Just a hack, but it should work. Changing visibility should force the same update.... but it doesn't.

You can just use this.trigger("RandomUnknownEventExample", ""); to force an update of an NPC and DB-NPC to save it's flags/values.

I noticed this behaivor when I called public functions which should have updated the NPCs X, Y or hid them but nothing would happen. Adding a trigger causes it to update to players.

adam 02-03-2011 05:58 PM

Sounds great, thanks.

kingcj 02-03-2011 08:12 PM

Still unsure of how that would work.. I haven't really worked with DB NPCs, and I can't seem to get that trigger to function correctly.. set it clientside and check severside right?

fowlplay4 02-03-2011 11:22 PM

A simple bomb demonstration and how to use getareanpcs.

class: bomb

PHP Code:

function onCreated() {
  
this.image "wbomb1.png";
  
// Set Timer to Go Off in a Few Seconds
  
setTimer(int(random(37)));
}

function 
onTimeout() {
  
// Explode Bomb
  
explodeBomb();
}

function 
explodeBomb() {
  if (!
this.exploded) {
    
// Set Flag to Prevent Double Explosion
    
this.exploded true;
    
// Trigger/Notify NPCs around it in a 4 tile square that it exploded
    
for (temp.ngetareanpcs(this.4this.488)) {
      
temp.n.trigger("ExplosionHit""");
    }
    
// Destroy Bomb
    
destroy();
  }
}

function 
onExplosionHit() {
  
explodeBomb();


class: block_explodable

PHP Code:

function onCreated() {
  
this.image "block.png";
}

function 
onExplosionHit() {
  
// Make sure Block hasn't Exploded
  
if (!this.exploded) {
    
// Set Image to Fire
    
this.image "g4_animation_fire.gif";
    
// Set Flag to Exploded
    
this.exploded true;
    
// Set Timer to Go Off in 3 Seconds
    
setTimer(3);
  }
}

function 
onTimeout() {
  
// Destroy the Fire
  
destroy();


Lay a bunch of them in a level using a level script or putnpc2:

Level script for bomb:

PHP Code:

function onCreated() {
  
this.join("bomb");


Level script for explodable block:

PHP Code:

function onCreated() {
  
this.join("block_explodable");



kingcj 02-04-2011 01:39 AM

Ok so that all works, but stil working with the bomb, and I want to trigger client now because the this.level.whatever doesn't seem to work serverside. Also it would require every player to use a bomb here.
PHP Code:

function onExplode() { 
  if (!
this.exploded) { 
    
this.image "door.png"
    
this.exploded true;
    
setTimer(3);
    
triggerClient("boom");
  } 

//#CLIENTSIDE
function onActionClientSide(cmd) { 
  if (
cmd == "boom") { 
  echo(
"working");
  
this.level.j.wasExploded(); 
  } 



kingcj 02-04-2011 08:25 PM

Sorry for the double post, but is it required to triggerserver to be able to triggerclient?

Cubical 02-04-2011 08:34 PM

Quote:

Originally Posted by Cubical (Post 1627531)
does this.gmap.blah work aswell so a variable can be pulled from anywhere on the gmap?

bump

fowlplay4 02-04-2011 08:36 PM

Quote:

Originally Posted by kingcj (Post 1627873)
Sorry for the double post, but is it required to triggerserver to be able to triggerclient?

triggerserver allows you to send "messages" to the server from the client.

triggerclient allows the server to send "messages" to the client.

They aren't dependent on each other, so your script doesn't have to include both if they don't need to.

kingcj 02-05-2011 04:14 AM

ok so why won't this work?

PHP Code:

function onCreated() {
  
this.attr[1] = eswitch//switch name 
  
this.attr[2] = edoor//door name 
  
this.attr[3] = 3//hide time
  
this.image "block.png"


function 
onExplode() { 
  if (!
this.exploded) { 
    
this.image "door.png"
    
this.exploded true;
    
setTimer(3);
    
triggerclient(this.name"boom");
  } 


function 
onTimeout() { 
  
this.exploded false;
  
this.image "block.png"
}  

//#CLIENTSIDE

function onCreated(){ 
  
this.attr[1];
  
this.attr[2];
  
this.attr[3];
  
this.level.this
}

function 
onActionClientSide(cmd) {
  if (
cmd == "boom") {
    
this.chat "ClientSide works";
    
this.level.n.wasExploded();
  } 
}

public function 
wasExploded(){ 
  
this.hide(); 
  
sleep(o);
  
this.show();


onExplode is when the bomb explodes and it has a distance that it hits.
I just can't get the clientside to function correctly. This is a switch that when it explodes it sends the wasExploded() to do something in another npc in the same level. Maybe public function needs to be server side, but a different puublic function works fine in clientside with a touch switch?

fowlplay4 02-05-2011 04:27 AM

Only weapon scripts can receive messages from triggerclient.

Why not just hide and show on the server-side instead?

kingcj 02-05-2011 04:37 AM

this way everyone has to use a bomb to use the switch not just one person can hit the switch with the bomb and the rest get the effect.
So can I join this from a weapon script or is there another way to work around it?

fowlplay4 02-05-2011 05:11 AM

Well the client has the (+90%) same functions so you can apply the concepts of getareanpcs on the client-side of the script.

kingcj 02-05-2011 05:16 AM

So something like this would work? I had been trying to work with that as well but I can't seem to get it working either. Maybe my syntax is wrong? I dunno..

PHP Code:

function onCreated() {
    for (
temp.ilevel.findareanpcs(this.xthis.y33)) {
      if (
temp.i.isinclass("bomb")) continue;
      echo(
"bombs?");
      
      
temp.i.trigger("Bombover"this);

    }



kingcj 02-16-2011 01:42 AM

Bump (sorta)
This is what I am working with, and everything works Except calling the function from the SwitchDB to the door.

This is the Switch Database

PHP Code:

function onCreated() {
  
SwitchDB this;
  
this.switches = new TStaticVar();
  
this.doors = new TStaticVar();
  
this.connections = new TStaticVar(); 
  
this.connections.switch_a "door_a";
}

public function 
addSwitch(temp.snametemp.sobj) {
  
this.switches.(@temp.sname) = temp.sobj;
  echo(
"added touch "@temp.sname);
}

public function 
addDoor(temp.dnametemp.obj) {
  
this.doors.(@temp.dname) = temp.obj;
  echo(
"added door " @temp.dname);
}

public function 
switchHit(temp.switchName) {
  echo(@ 
temp.switchName);
   
temp.doorName this.connections.(@temp.switchName); 
  
temp.door this.doors.(@temp.doorName);   
  echo(@
temp.doorName);
  
temp.door.doorOpen();   


The Switch

PHP Code:

function onCreated() {
  
SwitchDB findnpc("SwitchDB");
  
SwitchDB.addSwitch("switch_a"this);
  
setshape(1,32,32);
}

function 
onPlayerTouchsMe() {
  
SwitchDB.switchHit("switch_a");
  
this.chat "touched!";
  
sleep(1);
  
this.chat "";


And the door

PHP Code:

function onCreated() {
  
SwitchDB findnpc("SwitchDB");
  
SwitchDB.addDoor("door_a"this);
}


public function 
doorOpen() {
  
this.hide();
  
sleep(3);
  
this.show();


I've placed the public function in both the door and switchDB but doesn't work any which way i place it. Any help would be appreciated.

fowlplay4 02-16-2011 01:52 AM

does it echo anything in doorOpen? I would also recommend opening the door with a trigger instead of a public function. trigger forces the NPC to update to clients and what not.

kingcj 02-16-2011 04:27 AM

right but i can't use trigger beecause i want this to be able to be clientside as well. It gives me an error and says it can't find function doorOpen.

MrOmega 02-16-2011 05:42 AM

Are you putting 'on' before the function name. You need to put that with trigger

Such as

PHP Code:

trigger"foo"""); 

Would call...
PHP Code:

function onFoo() 


kingcj 02-16-2011 05:57 AM

A trigger won't work clientside from the DB I don't think, but I don't really know. I don't understand why it won't pick this up as a function though? A trigger would be great if I could work it server to client and client to server without it being a weapon, unfortunately I have tried this.

kingcj 02-17-2011 12:14 AM

Quote:

Originally Posted by MrOmega (Post 1631097)
Are you putting 'on' before the function name. You need to put that with trigger

Such as

PHP Code:

trigger"foo"""); 

Would call...
PHP Code:

function onFoo() 


Sorry I mis-read your quote. I tried placing on before the function, and I still get the error message.

kingcj 02-17-2011 03:04 AM

Sorry for like the triple post, but this seems to call the echo just don't know how to update the object now...

PHP Code:

public function door.doorOpen() {
  echo(
"crap");
  
this.hide();
  
sleep(3);
  
this.show();


Also in the SwitchDB I echo temp.door and it returns a 0 in RC Chat

WhiteDragon 02-17-2011 03:57 AM

That last post is definitely going in the wrong direction.


One thing I can think of is that the onCreated() of the door or switch is getting called before the database's.

For debugging, echoing an object doesn't really make much sense, try echoing temp.door.type() instead to see if anything is actually there.


All times are GMT +2. The time now is 03:39 PM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2026, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.