Graal Forums  

Go Back   Graal Forums > Development Forums > NPC Scripting > Old Scripting Engine (GS1)
FAQ Members List Calendar Today's Posts

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 07-31-2017, 12:44 AM
maximus_asinus maximus_asinus is offline
RIP DarkCloud_PK
Join Date: Oct 2001
Location: Canada
Posts: 3,745
maximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond repute
Help me weed out bad practices.

So I was scripting in an online editor and was annoyed by the people popping into the level to see what I was working on. So I scripted a system to remove players froma level in the offline editor in GS1. As part of my practice learning GS2 I want input on mistakes I made, how to make the script more efficient, design security for the NPC, and finally convert the script into GS2. Any advice is appreciated.

PHP Code:
// Script to add/remove players from ban list
if (playerchats) {
  if (
strequals(#a,maximus_asinus)) {
    
if (startswith(/add,#c)) {
      
tokenize #c;
      
this.duplicate false;
      if (
strequals(#t(1),#a)) {
        
setplayerprop #c,You cannot ban yourself.;
      
}
      else {
        for (
i=0;i<sarraylen(server.warp);i++;) {
          if (
strequals(#I(server.warp,i),#t(1))) {
            
this.duplicate true;
          }
        }
        if (
this.duplicate == true) {
          
setplayerprop #c,"#t(1)" is already on the ban list.;
        
}
        else {
          
addstring server.warp,#t(1);
          
setplayerprop #c,Added "#t(1)" to the ban list.;
        
}
      }
    }
    if (
startswith(/remove,#c)) {
      
tokenize #c;
      
for (i=0;i<sarraylen(server.warp);i++;) {
        if (
strequals(#I(server.warp,i),#t(1))) {
          
deletestring server.warp,i;
          
setplayerprop #c,Removed "#t(1)" from the ban list.;
        
}
      }
    }
  }

PHP Code:
// Script that removes the player
if (createdtimeout 0.05;
if (
timeout) {
  for (
i=0;i<sarraylen(server.warp);i++;) {
    if (
strequals(#I(server.warp,i),#a)) {
      
setplayerprop #c,You're banned from this level.;
      
setlevel2 onlinestartlocal.nw,30,30;
    }
  }
  
timeout 0.05;

I'm assuming placing a for loop inside a never ending timeout is bad practice and possibly process intensive. Can you manipulate another player's level and coordinates through a script like this? That way I could remove the player when I add them to the list and only have a playerenters check to see if they're on the list which would eliminate the timeout completely. This would also help me understand how you can manipulate other players via script.

Also I think I read that variables can now be assigned text values in GS2 like how strings work in GS1. Can you manipulate those variables in the same way as I am doing it in my script? If so, how?
__________________
Save Classic!
Reply With Quote
  #2  
Old 07-31-2017, 01:26 AM
MysticalDragon MysticalDragon is offline
Global Administration
MysticalDragon's Avatar
Join Date: Oct 2002
Location: Lynn Ma
Posts: 883
MysticalDragon is a jewel in the roughMysticalDragon is a jewel in the rough
Send a message via AIM to MysticalDragon Send a message via MSN to MysticalDragon
Quote:
Originally Posted by maximus_asinus View Post
So I was scripting in an online editor and was annoyed by the people popping into the level to see what I was working on. So I scripted a system to remove players froma level in the offline editor in GS1. As part of my practice learning GS2 I want input on mistakes I made, how to make the script more efficient, design security for the NPC, and finally convert the script into GS2. Any advice is appreciated.

PHP Code:
// Script to add/remove players from ban list
if (playerchats) {
  if (
strequals(#a,maximus_asinus)) {
    
if (startswith(/add,#c)) {
      
tokenize #c;
      
this.duplicate false;
      if (
strequals(#t(1),#a)) {
        
setplayerprop #c,You cannot ban yourself.;
      
}
      else {
        for (
i=0;i<sarraylen(server.warp);i++;) {
          if (
strequals(#I(server.warp,i),#t(1))) {
            
this.duplicate true;
          }
        }
        if (
this.duplicate == true) {
          
setplayerprop #c,"#t(1)" is already on the ban list.;
        
}
        else {
          
addstring server.warp,#t(1);
          
setplayerprop #c,Added "#t(1)" to the ban list.;
        
}
      }
    }
    if (
startswith(/remove,#c)) {
      
tokenize #c;
      
for (i=0;i<sarraylen(server.warp);i++;) {
        if (
strequals(#I(server.warp,i),#t(1))) {
          
deletestring server.warp,i;
          
setplayerprop #c,Removed "#t(1)" from the ban list.;
        
}
      }
    }
  }

PHP Code:
// Script that removes the player
if (createdtimeout 0.05;
if (
timeout) {
  for (
i=0;i<sarraylen(server.warp);i++;) {
    if (
strequals(#I(server.warp,i),#a)) {
      
setplayerprop #c,You're banned from this level.;
      
setlevel2 onlinestartlocal.nw,30,30;
    }
  }
  
timeout 0.05;

I'm assuming placing a for loop inside a never ending timeout is bad practice and possibly process intensive. Can you manipulate another player's level and coordinates through a script like this? That way I could remove the player when I add them to the list and only have a playerenters check to see if they're on the list which would eliminate the timeout completely. This would also help me understand how you can manipulate other players via script.

Also I think I read that variables can now be assigned text values in GS2 like how strings work in GS1. Can you manipulate those variables in the same way as I am doing it in my script? If so, how?
Yea timeout is definitely not needed you can just invoke playerenters and kick them.

I would create a database and when you create it place it in your level.

PHP Code:
function onCreated() {
  
this.commandList = {
    
"account1",
    
"account2"
  
};
}

function 
onPlayerChats() {
  if(!(
player.account in this.commandList)) return;
  if(
player.chat == "/add") {
    
temp.user player.chat.substring(5);
    
player.chat "";
    
onAddPlayer(temp.user);
  }
  if(
player.chat == "/remove") {
    
temp.user player.chat.substring(8);
    
player.chat "";
    
onRemovePlayer(temp.user);
  }
}

function 
onAddPlayer(temp.user) {
  if(!(
temp.user in this.allowedUsers)) {
    
this.allowedUsers.add(temp.user); 
    
this.chat format("User %s has been added!"temp.user);   
  } else {
    
this.chat format("User %s already added!"temp.user);
  }
  
scheduleevent(3"onResetChat");
}

function 
onRemovePlayer(temp.user) {
  if(
temp.user in this.allowedUsers) {
    
this.allowedUsers.remove(temp.user); 
    
this.chat format("User %s has been removed!"temp.user);   
  } else {
    
this.chat format("User %s is not in allowlist!"temp.user);
  }
  
scheduleevent(3"onResetChat");
}

function 
onResetChat() {
  
this.chat "";
}

function 
onPlayerEnters() {
  if(!(
player.account in this.allowedUsers)) {
    
player.chat "I'm not allowed in this level!"
    
player.setlevel2("levelname.nw"xy);
  }

I didn't test this as I did it on the forums, but you should get a good idea on how to do it if it doesn't work. I added a couple methods that I normally wouldn't in such a small situation like format. But it does make your code cleaner and its good to learn it.
__________________
~Delteria Support
~Playerworld Support
~PWA Chief
http://support.toonslab.com
[email protected]



Reply With Quote
  #3  
Old 07-31-2017, 02:49 AM
maximus_asinus maximus_asinus is offline
RIP DarkCloud_PK
Join Date: Oct 2001
Location: Canada
Posts: 3,745
maximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond repute
Quote:
Originally Posted by MysticalDragon View Post
Yea timeout is definitely not needed you can just invoke playerenters and kick them.
I only used the timeout to remove the player as soon as they were added to the ban list. Otherwise they could stay in the level until they left or reconnected.

Quote:
Originally Posted by MysticalDragon View Post
Script
Okay so I understand how the script works, but I have a few questions. First, what is "ScheduleEvent"? Is that like how sleep worked in GS1? Second, what is "format"?

Thanks for replying.
__________________
Save Classic!
Reply With Quote
  #4  
Old 07-31-2017, 02:57 AM
MysticalDragon MysticalDragon is offline
Global Administration
MysticalDragon's Avatar
Join Date: Oct 2002
Location: Lynn Ma
Posts: 883
MysticalDragon is a jewel in the roughMysticalDragon is a jewel in the rough
Send a message via AIM to MysticalDragon Send a message via MSN to MysticalDragon
sleep(1) is more like waitfor(this, "none", 1) in GS2 the benefit of this it doesn't stop the execution of the script, that's my preferred method If its viable. scheduleevent can call a function on a timer basis. Basically It wont trigger the function immediately but when it hits the timer. Its better then timeout since it can be called once. Although I seen some people set there setTimer(0) (not sure if that even works, never tried it), which is ugly in my opinion. Reason I used this is because like your join classes, It's good to have one centralized place for repetitive code. instead of adding this.chat = "" after ever function its only in one place. Format just organized your code in a readability type way. Instead of doing things like,

PHP Code:
echo("test1:" SPC temp.test1 SPC "test2:"SPC temp.test2 SPC "test3:"SPC temp.test3
which looks horrible you could do

PHP Code:
echo(format("test1: %s test2: %s test3: %s"temp.test1temp.test2temp.test3)); 
It also can be used to replace parts of a string. Without using replacetext which could be intensive in some instances.

PHP Code:
   temp.copy_id player.account;
   
temp.level findlevel(format("mylevel-%s.nw"temp.copy_id)); 
__________________
~Delteria Support
~Playerworld Support
~PWA Chief
http://support.toonslab.com
[email protected]




Last edited by MysticalDragon; 07-31-2017 at 03:21 AM..
Reply With Quote
  #5  
Old 07-31-2017, 05:26 AM
maximus_asinus maximus_asinus is offline
RIP DarkCloud_PK
Join Date: Oct 2001
Location: Canada
Posts: 3,745
maximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond repute
Okay I'm having issues with the basics.

PHP Code:
function onPlayerChats() {
  if (
player.chat == "Hello") {
    
this.chat "true";
  }

This will only return true if player.chat is "Hello" but not when it is "Hello World". And reading the script this is how it should behave. But in your example above you made it sound as if it would catch everything. Am I using it wrong?
__________________
Save Classic!
Reply With Quote
  #6  
Old 07-31-2017, 06:07 AM
MysticalDragon MysticalDragon is offline
Global Administration
MysticalDragon's Avatar
Join Date: Oct 2002
Location: Lynn Ma
Posts: 883
MysticalDragon is a jewel in the roughMysticalDragon is a jewel in the rough
Send a message via AIM to MysticalDragon Send a message via MSN to MysticalDragon
Accident, I meant to do
if(player.chat.starts("/add")) {
and
if(player.chat.starts("/remove")) {
__________________
~Delteria Support
~Playerworld Support
~PWA Chief
http://support.toonslab.com
[email protected]



Reply With Quote
  #7  
Old 07-31-2017, 10:13 AM
maximus_asinus maximus_asinus is offline
RIP DarkCloud_PK
Join Date: Oct 2001
Location: Canada
Posts: 3,745
maximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond repute
Okay so I made an attempt at scripting the same system in GS2 using Carlito's example as my base, but I couldn't get format to work with player.chat. Also tried to do something like this.chat = temp.list "message" but I couldn't get it to work either. Does anyone know why?

Eventually I want to display the people on the blacklist. I know I could do something simple like this.chat = this.deniedList, but the output looks pretty ugly. Is there a better method of displaying the contents of the array?

PHP Code:
function onCreated() {
  
this.commandList = {"account1","account2"};
}
function 
onPlayerChats() {
  if (
player.account in this.commandList) {
    if (
player.chat.starts("/add")) {
      
temp.list = player.chat.tokenize()[1];
      
onAddPlayer(temp.list);
      
    }
    if (
player.chat.starts("/remove")) {
      
temp.list = player.chat.tokenize()[1];
      
onRemovePlayer(temp.list);
    }
  }
}
function 
onAddPlayer(temp.list) {
  if (
temp.list in this.commandList) {
    
player.chat "Cannot add admin to list";
  }
  else {    
    if (
temp.list in this.deniedList) {
      
player.chat "Account already on list.";
    }
    else {
      
this.deniedList.add(temp.list);
      
player.chat "Account added to list.";
    }
  }
}

function 
onRemovePlayer(temp.list) {
  if (
temp.list in this.deniedList) {
    
this.deniedList.remove(temp.list);
    
player.chat "Account removed from list.";
  }
  else {
    
player.chat "Account not on list.";
  }
}
function 
onPlayerEnters() {
  if (
player.account in this.deniedList) {
    
player.chat "You were removed from this level.";
    
player.setlevel2("levelname.nw",x,y);
  }

[EDIT]Also still need a method to remove players from the level if they're already inside.
__________________
Save Classic!
Reply With Quote
  #8  
Old 07-31-2017, 10:23 PM
maximus_asinus maximus_asinus is offline
RIP DarkCloud_PK
Join Date: Oct 2001
Location: Canada
Posts: 3,745
maximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond repute
So I'm trying to think of a method to warp other players but I can't think of anything. The closest I can come up with is using triggeraction passing on temp.list, and then doing something like:

PHP Code:
triggeraction("warp",temp.list); 
PHP Code:
function onActionWarp() {
  if (
player.account == temp.list) {
    
player.setlevel2("levelname.nw",x,y);
  }

And I could see this working if the player had this as a weapon, but I'm working with a single NPC in a level and can't add a weapon to the player.
__________________
Save Classic!
Reply With Quote
  #9  
Old 07-31-2017, 11:19 PM
DustyPorViva DustyPorViva is offline
Will work for food. Maybe
DustyPorViva's Avatar
Join Date: Sep 2003
Location: Maryland, USA
Posts: 9,589
DustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond repute
Send a message via AIM to DustyPorViva Send a message via MSN to DustyPorViva
In GS2 the most efficient way to warp players out of a level is to have a serverside NPC with a setshape that extends to the whole level, like so:

PHP Code:
function onCreated() {
  
// Set the NPCs shape to 1024x1024, or 64x64*16
  
setShape(1,1024,1024);
  
// You can still set an NPC to not block and it will retain its shape and trigger onPlayerTouchsme
  // This is useful for instances like this, while also not making the entire level return true for any serverside onwall() checks
  
dontblock();
}

// The player will trigger onPlayerTouchsme() as soon as they enter the level, and again if their position changes at all
// See below for explanation
function onPlayerTouchsme() {
  
// Don't warp out your account
  
if (player.account == "maximus_asinus") return;
  
// Don't warp out players who are in server.warp
  
if (player.account in server.warp) return;
  
// Warp player to the designated unstickme level
  
player.chat "You're banned from this level";
  
player.setlevel2(serveroptions.unstickmelevel,serveroptions.unstickmex,serveroptions.unstickmey);

No timeouts needed, no need to trigger the server. You can do the same thing on clientside as well but instead make the NPC block for players who aren't allowed in, denying them the ability to walk around. You can also do something like rendering a black showpoly on the screen so they can't see anything in the level.

The benefit of this method is letting the server do all the heavy-lifting so even if they are lagging they will still get warped out as soon as they enter the level.

Also, onPlayerTouchsme works differently on serverside and clientside. On serverside it will be triggered whenever the players position changes, not just when the player invokes movement. It will also be triggered multiple times, unlike clientside. Clientside onPlayerTouchsme will only trigger when the player himself moves and touches an NPC and it will won't trigger until the player moves away and touches the NPC again(save some glitchy methods). This means when dealing with serverside onPlayerTouchsme() it's fairly good at detecting players entering the level and moving without needing to loop or rely on clientside methods.
Reply With Quote
  #10  
Old 07-31-2017, 11:42 PM
Kamaeru Kamaeru is offline
G2k1
Kamaeru's Avatar
Join Date: Dec 2001
Posts: 1,040
Kamaeru has much to be proud ofKamaeru has much to be proud ofKamaeru has much to be proud ofKamaeru has much to be proud ofKamaeru has much to be proud ofKamaeru has much to be proud of
Quote:
Originally Posted by DustyPorViva View Post
onPlayerTouchsme
Cool, I had noticed some of those nuances about onPlayerTouchsme via trial and error but it's good to hear it from someone who has already figured it out.

Can you give the same rundown for onPlayerEnters()? Is it different clientside and serverside?

Alsowhat is the benefit of making the server do heavy lifting? I would assume everyone uses a supercomputer these days so making as much stuff clientside would be the smart thing to do. For 2k1's server, it doesn't seem to be allocated very much memory and I had to cut the amount of birds flying in half to stop server lag.
__________________
3DS friendcode: 1118-0226-7975
Reply With Quote
  #11  
Old 08-01-2017, 01:00 AM
maximus_asinus maximus_asinus is offline
RIP DarkCloud_PK
Join Date: Oct 2001
Location: Canada
Posts: 3,745
maximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond reputemaximus_asinus has a reputation beyond repute
Quote:
Originally Posted by DustyPorViva View Post
Serverside
Okay another novice question here. What is the difference between serverside and clientside NPCs? I assume that clientside NPCs are only run on locally and can have different behaviors for each person depending on the script, so does serverside run for everyone? How does the client know what NPCs are clientside or serverside? Is that the purpose of //#CLIENTSIDE?

And I still think it would be better to remove the player once I executed the command. Otherwise you could just stay still to prevent being warped. But maybe this is a limitation of not making it a weapon.
__________________
Save Classic!

Last edited by maximus_asinus; 08-01-2017 at 01:22 AM..
Reply With Quote
  #12  
Old 08-01-2017, 02:52 AM
DustyPorViva DustyPorViva is offline
Will work for food. Maybe
DustyPorViva's Avatar
Join Date: Sep 2003
Location: Maryland, USA
Posts: 9,589
DustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond repute
Send a message via AIM to DustyPorViva Send a message via MSN to DustyPorViva
Quote:
Originally Posted by Kamaeru View Post
Cool, I had noticed some of those nuances about onPlayerTouchsme via trial and error but it's good to hear it from someone who has already figured it out.

Can you give the same rundown for onPlayerEnters()? Is it different clientside and serverside?

Alsowhat is the benefit of making the server do heavy lifting? I would assume everyone uses a supercomputer these days so making as much stuff clientside would be the smart thing to do. For 2k1's server, it doesn't seem to be allocated very much memory and I had to cut the amount of birds flying in half to stop server lag.
onPlayerEnters() works the same both serverside and clientside I'm pretty sure, though it's finicky when you're dealing with gmaps.

What I mean about letting the server do the heavy lifting is that you don't need to worry about their computer, connection issues/lag, or things like that. The server will know they entered the level and they will trigger onPlayerTouchsme() and get warped out before their PC even gets the data. It's just faster and more efficient than detecting it clientside and then waiting for the data to get to the server and then sending it. And if they're lagging it may not happen for a while or at all. An event like onPlayerTouchsme() won't do much, while scripts like birds that are always running loops will be much more intensive.

By the way, NPCs running loops will continue to run loops even if a player is not in a level. I don't think the loop is stopped until the level is pulled from memory and cleaned up... and I think that's like 5-10 minutes. It's best to break any loops serverside(such as a timeout loop) when players.size() <= 0. Something like this:
PHP Code:
function onPlayerEnters() {
  
// Resume the loop, clear the idle flag.
  
if (this.idlesetTimer(.1);
  
this.idle false;
}
function 
onTimeout() {
  
// No players so don't waste time doing things
  
if (players.size() <= 0) {
    
this.idle true;
    return;
  }
  
// Do loop stuff
  
setTimer(.1);

It will cut down on a lot of unnecessary processing occurring in inactive levels. Anything that runs on a constant loop should implement this sort of check. The only downside is that players.size() can sometimes be faulty causing NPCs to stop working because it thinks there are no players around. You can get around this by trying players.size() <= 0 && this.level.findareaplayers(0,0,64,64).size() <= 0 but I don't think it's necessary.

Quote:
Originally Posted by maximus_asinus View Post
Okay another novice question here. What is the difference between serverside and clientside NPCs? I assume that clientside NPCs are only run on locally and can have different behaviors for each person depending on the script, so does serverside run for everyone? How does the client know what NPCs are clientside or serverside? Is that the purpose of //#CLIENTSIDE?

And I still think it would be better to remove the player once I executed the command. Otherwise you could just stay still to prevent being warped. But maybe this is a limitation of not making it a weapon.
Serverside script is run on the server, while clientside script is run on the players device. Anything clientside is being run on the players machine, therefor it can be accessed via memory editing and such. Anything secure should be done on the server. This is why it's better to do your player detection on the serverside instead of client, because depending on circumstances they might be able to bypass whether or not the script detects them there. Serverside doesn't need to worry about that, the player can't access anything there.

And yes, it works like this:
PHP Code:
function onCreated() {
  echo(
"This is serverside code. This will appear in RC, since it's being handled by the server.");
}
//#CLIENTSIDE
function onCreated() {
  echo(
"This is clientside code. This will appear in the F2 log window since it's being handled by the players machine.");

As you can see, even though you would normally not be able to have duplicate functions that will work fine because they're not even being parsed by the same machine. They work indepedently of each other, and in order to communicate between them you will need to send data to the server or have the server send data to the player via triggeraction()/triggerserver()/triggerclient(). Though there are other ways to communicate, via relying on synchronized variables like player.client/clientr.flags and player/npc.attr[1-30].

Anyways about the onPlayerTouchsme(). You don't need to worry about players entering the level and not moving. Like I said on serverside this gets called whenever the player position changes--that includes when they change position by entering the level. As soon as they enter the level it will trigger onPlayerTouchsme(). The good thing about this over onPlayerEnters() is that if for whatever reason it may fail, if they move at all they will trigger it again. And again, if you're that worried you can put a polygon on the clientside so they can't see anything anyways. Like so:

PHP Code:
function onCreated() {
  
// Set the NPCs shape to 1024x1024, or 64x64*16
  
setShape(1,1024,1024);
  
// You can still set an NPC to not block and it will retain its shape and trigger onPlayerTouchsme
  // This is useful for instances like this, while also not making the entire level return true for any serverside onwall() checks
  
dontblock();
}

// The player will trigger onPlayerTouchsme() as soon as they enter the level, and again if their position changes at all
// See below for explanation
function onPlayerTouchsme() {
  
// Don't warp out your account
  
if (player.account == "maximus_asinus") return;
  
// Don't warp out players who are in server.warp
  
if (player.account in server.warp) return;
  
// Warp player to the designated unstickme level
  
player.chat "You're banned from this level";
  
player.setlevel2(serveroptions.unstickmelevel,serveroptions.unstickmex,serveroptions.unstickmey);
}
//#CLIENTSIDE
function onCreated() {
  
setShape(1,1024,1024);
}

// Since onPlayerTouchsme() doesn't quit work like it does serverside it's best to just use onPlayerEnters()
function onPlayerEnters() {
  if (
player.account == "maximus_asinus" || player.account in server.warp) {
    
// Let's not block players who are allowed in the level
    
dontblock();
    
hideimg(200);
    return;
  }
  
// Anyone who gets to this part of the code isn't allowed in the level. The NPC will
  // continue to block the level. Let's also render a polygon to obscure their vision

  
with (findimg(200)) {
    
// A polygon shape that fills the entire screen
    
polygon = {0,0,screenwidth,0,screenwidth,screenheight,0,screenheight};
    
// Make it black
    
red green blue 0;
    
// A high layer
    
layer 10;
  }

Reply With Quote
  #13  
Old 08-01-2017, 06:07 AM
cbk1994 cbk1994 is offline
the fake one
cbk1994's Avatar
Join Date: Mar 2003
Location: San Francisco
Posts: 10,718
cbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond repute
Send a message via AIM to cbk1994
Quote:
Originally Posted by DustyPorViva View Post
In GS2 the most efficient way to warp players out of a level is to have a serverside NPC with a setshape that extends to the whole level, like so:
This is a really neat trick, but I'm curious why you'd prefer this over a serverside onPlayerEnters?
__________________
Reply With Quote
  #14  
Old 08-02-2017, 12:51 AM
DustyPorViva DustyPorViva is offline
Will work for food. Maybe
DustyPorViva's Avatar
Join Date: Sep 2003
Location: Maryland, USA
Posts: 9,589
DustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond repute
Send a message via AIM to DustyPorViva Send a message via MSN to DustyPorViva
Quote:
Originally Posted by cbk1994 View Post
This is a really neat trick, but I'm curious why you'd prefer this over a serverside onPlayerEnters?
Mostly picked it up from using it on gmaps, since I can throw it in a class and put it in levels on an overworld, snap it with x = int(this.x/64)*64; and it will still warp players out of specific levels on the gmap, since onPlayerEnters() doesn't work. I also just find it more reliable since it will persist even after the initial entering the level.
Reply With Quote
  #15  
Old 08-02-2017, 09:10 PM
Kamaeru Kamaeru is offline
G2k1
Kamaeru's Avatar
Join Date: Dec 2001
Posts: 1,040
Kamaeru has much to be proud ofKamaeru has much to be proud ofKamaeru has much to be proud ofKamaeru has much to be proud ofKamaeru has much to be proud ofKamaeru has much to be proud of
Quote:
Originally Posted by DustyPorViva View Post
Mostly picked it up from using it on gmaps, since I can throw it in a class and put it in levels on an overworld, snap it with x = int(this.x/64)*64; and it will still warp players out of specific levels on the gmap, since onPlayerEnters() doesn't work. I also just find it more reliable since it will persist even after the initial entering the level.
That's how zones are handled on 2k1 like event zones (survivor, CNR, etc), kingdoms zones, nopk zones, quest zones, etc.
__________________
3DS friendcode: 1118-0226-7975
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 05:35 AM.


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