Graal Forums  

Go Back   Graal Forums > Development Forums > NPC Scripting > Code Gallery
FAQ Members List Calendar Today's Posts

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 03-29-2011, 04:09 PM
PhilSmith PhilSmith is offline
Workin' on It
PhilSmith's Avatar
Join Date: Mar 2011
Location: Chicago
Posts: 38
PhilSmith is on a distinguished road
Simple Warp/Summon

I just created this script and thought it was nice. It is my first actual code so I come here seeking advice, suggestions, and perhaps ways to make the script simpler. I am in no way trying to show off the usefulness of this script, I was merely making it for practice. I know it may be pointless, however, that is not what is in question here. Save yourself some time and a post if you are going to say that

Functions:
-Obvious summon and warping ability ("/warp name" or "/summon name")
-Can find players based on partial names (instead of "PhilSmith" it could work with "Phil" or "P")
-when using a partial name, it logs all the names found in an array. If one name is found, it warps/summons. If zero names are found, it says"No Players Found". If more than one name are found, it pms the array to the player.

PHP Code:
// Scripted by Phil Smith
function onActionServerSide(){
//for loop to find all players and their partial nicks
  
for(temp.pl allplayers){
    if(
params[0]==temp.pl.substring(0,params[0].length())|| params[0]==temp.pl.nick.substring(0,params[0].length())){
      if (
temp.pl.level!=NULL){ //if player is not on rc
        
this.fnd=temp.pl;
        
temp.foundplayer.add(temp.pl); //logs the player into the array
      
}
    }
  }
  if (
temp.foundplayer.size()==1){
    
onPlayerFound();
  }
  else if(
temp.playerfound.size==0){
    
player.chat="No Players Found!";
  }
  
//more than one players are found
  
else{ player.chat="More than one player found! Check your PM for options.";
    
player.sendPM(temp.foundplayer.size() SPC "players were found:" NL temp.foundplayer NL "" NL "" NL "Tip: Be sure to type in the player's name/account as specific as possible in order to find them easier!");
  }
}
//carries out the warp/summon
function onPlayerFound(){
  if (
params[1].starts("/summon")){
    
this.fnd.setlevel2(player.level,player.x,player.y);
    
updateboard(0,0,64,64);
    
this.fnd.chat="Summoned!";
  }
  if (
params[1].starts("/warp")){
    
setlevel2(this.fnd.level,this.fnd.x,this.fnd.y);
    
player.chat="Warped!";
  }
}
//#CLIENTSIDE
function onPlayerChats(){
  if(
player.chat.starts("/warp")){
    
tokens=player.chat.substring(6);
    
triggerserver("weapon",this.name,tokens,player.chat);
  }
  if(
player.chat.starts("/summon")){
    
tokens=player.chat.substring(8);
    
triggerserver("weapon",this.name,tokens,player.chat);
  }

Thanks for taking the time to submit useful feedback and suggestions!
__________________
Nothing to say...
Reply With Quote
  #2  
Old 03-29-2011, 04:25 PM
fowlplay4 fowlplay4 is offline
team canada
fowlplay4's Avatar
Join Date: Jul 2004
Location: Canada
Posts: 5,200
fowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond repute
It's not really a big deal but you can do the "search" processing on the client-side.

Then in the case of multiple results, you can just display a dialog and have the player select who they wanted to summon.

I would suggest using.. string.starts("text") or string.pos("text") for checking for partials. I.e:

PHP Code:
function onCreated() {
  
temp.str "loltextlmao";
  echo(
temp.str.pos("text")); // echos 3 (found == position >= 0)
  
echo(temp.str.pos("rofl")); // echos -1 (not found)
  
echo(temp.str.starts("lol")); // echos 1 (found)
  
echo(temp.str.starts("lmao")); // echos 0 (not found)

Also in your check... you should have community name support as well. Another thing when searching you should probably check them all in lowercase or uppercase. I.e:

PHP Code:
function onCreated() {
  
temp.exact "Phil";
  
temp.cond temp.exact.lower();
  
temp.matches = {};
  for (
aallplayers) {
    
// Skip RCs
    
if (a.level == NULL) continue;
    
// Check for Exact Match
    
if (a.account == temp.exact || a.communityname == temp.exact) {
      
temp.found a.account;
      break;
    }
    
// Check for Partials
    
if (a.account.lower().pos(temp.cond) >= || a.communityname.lower().pos(temp.cond) >= || a.nick.lower().pos(temp.cond) >= 0) {
      
temp.matches.add(a.account);
    } 
  }
  if (
temp.found != "") {
    echo(
"Found... " temp.found);
  } else {
    echo(
"Other matches... " temp.matches);
  }

__________________
Quote:
Reply With Quote
  #3  
Old 03-29-2011, 04:35 PM
PhilSmith PhilSmith is offline
Workin' on It
PhilSmith's Avatar
Join Date: Mar 2011
Location: Chicago
Posts: 38
PhilSmith is on a distinguished road
I did have just the dialog, but the problem was, was that the player.chat reset after like 2 seconds. I thought this was not enough time so i ended up pming it. if there is a way to keep the text from resetting, I'm all ears.

And just after i posted this i realized i forgot community names. I'm working on those
__________________
Nothing to say...
Reply With Quote
  #4  
Old 03-29-2011, 04:38 PM
WhiteDragon WhiteDragon is offline
Banned
Join Date: Feb 2007
Posts: 1,002
WhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to behold
PHP Code:
function onActionServerSide() {
  
temp.foundPlayers = {};
  for (
temp.pl allplayers) {
    if ( (     
params[0] == temp.pl.account.substring(0params[0].length())
            || 
params[0] == temp.pl.nick.substring(0params[0].length())
          ) && 
temp.pl.level != NULL) {
      
temp.foundPlayers.add(temp.pl);
    }
  }
  
temp.temp.foundPlayers.size();
  if (
temp.1) {
    
player.chat "More than one player found! Check your PM for options.";
    
player.sendPM("Multiple players were found:" NL temp.foundPlayers NL "" NL "" NL "Tip: Be sure to type in the player's name/account as specific as possible in order to find them easier!");
  } else if (
temp.== 1) {
    
playerFound(params[1], temp.foundPlayers[0]);
  } else {
    
player.chat "No Players Found!";
  }
}
function 
playerFound(temp.actionTypetemp.pl) {
  if (
temp.actionType == "summon") {
    
temp.pl.setlevel2(player.levelplayer.xplayer.y);
    
updateboard(006464);
    
temp.pl.chat "Summoned!";
  } else if (
temp.actionType == "warp") {
    
setlevel2(temp.pl.leveltemp.pl.xtemp.pl.y);
    
player.chat "Warped!";
  }
}

//#CLIENTSIDE
function onPlayerChats(){
  if (
player.chat.starts("/warp")) {
    
triggerserver("weapon"this.nameplayer.chat.substring(6), "warp");
  } else if (
player.chat.starts("/summon")) {
    
triggerserver("weapon"this.nameplayer.chat.substring(8), "summon");
  }

Here is my "code clarity" edit (I kept the logic the same). Feel free to ask any questions.


Note: interestingly enough, that loop at the beginning of the code has a name: filter. I have wrapped up some common patterns such as filter in this thread. With my code the first loop would simply be:
PHP Code:
  temp.= function (temp.pl) {
    return (
params[0] == temp.pl.account.substring(0params[0].length()) || params[0] == temp.pl.nick.substring(0params[0].length())) && temp.pl.level != NULL;
  };
  
temp.foundPlayers filter(temp.fallplayers); 

Last edited by WhiteDragon; 03-29-2011 at 05:16 PM..
Reply With Quote
  #5  
Old 03-29-2011, 04:41 PM
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
It's not bad at all, but there are some things that can be improved.

PHP Code:
if(params[0]==temp.pl.substring(0,params[0].length())|| params[0]==temp.pl.nick.substring(0,params[0].length())){ 
There are a couple of issues with this line.

You can improve the substring check by using str.starts(substring). I doubt it's really any more efficient but it's semantically better as it makes your purpose clearer to the reader.

PHP Code:
if(temp.pl.starts(params[0]) || temp.pl.nick.starts(params[0])){ 
The other problem is that temp.pl is referring to the actual player object right now, not their account. The reason it works as-is is that Graal internally converts objects to strings when necessary by using the object's name, which happens to be the player's account name. It's better practice to do it like so (note I'm using temp.pl.communityName):

PHP Code:
temp.pl.communityName.starts(params[0]) 
You should also fix this where you're sending a PM.

It's also better practice to pass parameters to functions instead of setting variables. For example, in your player found function:

PHP Code:
function onPlayerFound(){ 
you would use

PHP Code:
function onPlayerFound(playerFound) { 
When calling it you would pass the player object to it.

PHP Code:
  if (temp.foundplayer.size()==1){ 
    
onPlayerFound(temp.foundplayer[0]); 
  } 
Since setlevel2's first parameter is a level name, not a level object, you should do this (note player.level.name; this is similar to the issue with the account):

PHP Code:
this.fnd.setlevel2(player.level.name,player.x,player.y); 
I would also recommend reorganizing the script so that you're not sending the player's chat but rather the just the command ("summon" or "warp") and the account. Then you would want to do something like this:

PHP Code:
function onActionServerSide(cmdsearch) {
  if (
cmd == "warp") {
    
temp.pl searchForPlayer(search);
    
    if (
pl == null) {
      return 
pl.chat "Found multiple players!"// ends the function
    
}
    
    
player.setlevel2(pl.level.namepl.xpl.y);
  } else if (
cmd =="summon") {
    
temp.pl searchForPlayer(search);
    
    if (
pl == null) {
      return 
pl.chat "Found multiple players!"// ends the function
    
}
    
    
pl.setlevel2(player.level.nameplayer.xplayer.y);
  }
}

function 
searchForPlayer(search) {
  for (
temp.pl allplayers) {
    
// your search code here
  
}
  
  return 
temp.foundPlayer;

Let me know if any of this doesn't make sense.

edit: sorry for the repeats, all of the posts except the OP were while I wrote this

There is a way to keep a player's chat from resetting after a few seconds but it can only be done on clientside, so you would have to trigger back.

PHP Code:
shared.chat("chat here"); 
__________________
Reply With Quote
  #6  
Old 03-29-2011, 04:49 PM
PhilSmith PhilSmith is offline
Workin' on It
PhilSmith's Avatar
Join Date: Mar 2011
Location: Chicago
Posts: 38
PhilSmith is on a distinguished road
I'm not sure I understand this all right now, but I'll take a few more minutes to read it over and maybe absorb the information. If Ii have questions after that, I'll ask
__________________
Nothing to say...
Reply With Quote
  #7  
Old 03-29-2011, 07:29 PM
PhilSmith PhilSmith is offline
Workin' on It
PhilSmith's Avatar
Join Date: Mar 2011
Location: Chicago
Posts: 38
PhilSmith is on a distinguished road
I think i covered most of your edits. I was confused by two of them:

1) check in all lowercase. I'm not really sure what the point of this was. Could you elaborate a little more on its purpose please?

2) the filter. I understand that it is a quicker way of checking than mine, but i just couldnt get it to work.

aside from those, I corrected the other parts and added the community name and clientside shared.chat.

PHP Code:
// Scripted by Phil Smith
function onActionServerSide(searchtemp.action){
//for loop to find all players and their partial nicks
  
temp.foundPlayers.destroy();
  for(
temp.pl allplayers){
    if(
temp.pl.account.starts(search)|| temp.pl.communityName.starts(search) || temp.pl.nick.starts(search)){
      if (
temp.pl.level!=NULL){ //if player is not on rc
        
temp.foundPlayers.add(temp.pl); //logs the player into the array
      
}
    }
  } 
  if (
temp.foundPlayers.size()==1){
    
onPlayerFound(temp.actiontemp.foundPlayers[0]);
  }
  if(
temp.foundPlayers.size()<1){
    
player.chat="No Players Found!";
  }
  if(
temp.foundPlayers.size()>1){
    
triggerclient("weapon",this.name,"NoneFound",temp.foundPlayers);
  }
}
function 
onPlayerFound(temp.functemp.pl){
  if (
temp.func=="summon"){
    
temp.pl.setlevel2(player.level.name,player.x,player.y);
  }
  else if(
temp.func=="warp"){
    
setlevel2(temp.pl.level,temp.pl.x,temp.pl.y);
  }
}
//#CLIENTSIDE
function onActionClientSide(temp.actiontemp.chatarray){
  if(
temp.action=="NoneFound"){
    
shared.chat(temp.chatarray.size() SPC "Players Were Found!:");
    
sleep(2);
    for(
temp.i==0;temp.i<temp.chatarray.size();temp.i++){
      
shared.chat(temp.chatarray[temp.i]);
      
sleep(4);
    }
  }
}
function 
onPlayerChats(){
  if(
player.chat.starts("/warp")){
    
triggerserver("weapon",this.name,player.chat.substring(6),"warp");
  }
  if(
player.chat.starts("/summon")){

    
triggerserver("weapon",this.name,player.chat.substring(8),"summon");
  }

__________________
Nothing to say...
Reply With Quote
  #8  
Old 03-29-2011, 08:14 PM
Deas_Voice Deas_Voice is offline
Deas
Deas_Voice's Avatar
Join Date: Jun 2007
Location: Sweden
Posts: 2,264
Deas_Voice is a jewel in the roughDeas_Voice is a jewel in the rough
Send a message via AIM to Deas_Voice Send a message via MSN to Deas_Voice Send a message via Yahoo to Deas_Voice
Thread should be moved from CodeGallery, yes?
__________________
.
WTF is real life, and where do I Download it?
There is no Real Life, just AFK!
since 2003~
I Support~
ღAeonღ | ღTestbedღ | ღDelteriaღ

if you are going to rep me, don't be an idiot, leave your name!
I got nothing but love for you
Reply With Quote
  #9  
Old 03-29-2011, 08:25 PM
PhilSmith PhilSmith is offline
Workin' on It
PhilSmith's Avatar
Join Date: Mar 2011
Location: Chicago
Posts: 38
PhilSmith is on a distinguished road
It is a working code. I was just asking for thoughts & comments
__________________
Nothing to say...
Reply With Quote
  #10  
Old 03-29-2011, 08:58 PM
WhiteDragon WhiteDragon is offline
Banned
Join Date: Feb 2007
Posts: 1,002
WhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to beholdWhiteDragon is a splendid one to behold
Quote:
Originally Posted by PhilSmith View Post
[New Version]
Don't be afraid of using } else if {. It is best to be explicit about how your program 'branches' than force whoever is reading it to think about it themselves.

For example, temp.foundPlayers.size()==1 and temp.foundPlayers.size()<1 both clearly can never be true at the same time, but you should always make that clear just in case the conditions are not so clearly disjoint like they are here.


Also, temp.foundPlayers.destroy(); at the start of a function makes no sense. temp.foundPlayers won't even exist then. If you are going to use it as an array, it is best to create one at that point: temp.foundPlayers = {};


Regarding the filter thing, it's just an interesting note. Most people don't program like that in GS2, but I think more people should. The less code you write, the less that can go wrong.

If you're curious about it, let me know what you tried and I can hopefully tell you what went wrong.
Reply With Quote
  #11  
Old 03-29-2011, 09:52 PM
PhilSmith PhilSmith is offline
Workin' on It
PhilSmith's Avatar
Join Date: Mar 2011
Location: Chicago
Posts: 38
PhilSmith is on a distinguished road
First, I normally do use else ifs. I dont know what i was doing with this one, but i must have forgot.
Second, my temp.foundPlayers.destroy() was me being dumb. I looked up on the wiki what i actually needed to put and fixed it. Idk why it is still there in this one...
third, i believe i put something like this:
PHP Code:
temp.= function (temp.pl,search) {
    return (
temp.pl.account.starts(search)|| temp.pl.communityname.starts(search)|| temp.pl.nick.starts(search) && temp.pl.level != NULL;
  };
  
temp.foundPlayers filter(temp.fallplayers); 
search in this case was the string for the substring player.chat. In otherwords, the player i was searching for.
__________________
Nothing to say...
Reply With Quote
  #12  
Old 03-29-2011, 10:00 PM
fowlplay4 fowlplay4 is offline
team canada
fowlplay4's Avatar
Join Date: Jul 2004
Location: Canada
Posts: 5,200
fowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond repute
Quote:
Originally Posted by WhiteDragon View Post
Regarding the filter thing, it's just an interesting note. Most people don't program like that in GS2, but I think more people should. The less code you write, the less that can go wrong.
I would totally use functions like filter more if they were built-in or at least able to implemented un-obtrusively.
__________________
Quote:
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 09:19 AM.


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