Graal Forums  

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

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 02-21-2011, 12:46 PM
AlexanderK AlexanderK is offline
Registered User
AlexanderK's Avatar
Join Date: Mar 2006
Location: Germany
Posts: 79
AlexanderK is on a distinguished road
Send a message via MSN to AlexanderK
Iteration on an array of objects

Up to now, I have been using a hitbox-based sword system, like explained in this thread by adam: http://forums.graalonline.com/forums...hp?t=134258416.
It was way too slow though, my bush classes didn't really react to being cut quickly enough, so I thought I'd try out what xXziroXx said.
Quote:
We've been using a system like this on Maloria for quite a while. We first do the box detection clientside, and if there's any eligble target(s), proceed to serverside where it will just make sure that said target(s) are still within the box and take action accordingly.
So that's what I'm trying to do now.

On the clientside, if the sword key is pressed, I display the gani and use the findThings() function:
PHP Code:
function findThings() {
  
temp.objlist = {};
  for (
temp.objfindAreaPlayers(player.clientr.hbox[player.dir][0], player.clientr.hbox[player.dir][1], clientr.hbox[player.dir][2], clientr.hbox[player.dir][3], player.account)) {
    
temp.objlist.add(temp.obj);
  }
  for (
temp.objfindAreaNpcs(player.clientr.hbox[player.dir][0], player.clientr.hbox[player.dir][1], clientr.hbox[player.dir][2], clientr.hbox[player.dir][3])) {
    
temp.objlist.add(temp.obj);
  }
  if (@
temp.objlist != null)
    
triggerServer("gui"this.name"hitthings"temp.objlist);

And this is what my ActionServerSide looks like:
PHP Code:
function onActionServerside() {
  if (
params[0] == "hitthings") {
    
player.chat "hit:"params[1];
    for (
temp.objparams[1]) {
      
temp.obj.chat="hit";
      
temp.obj.hurt(clientr.sweapon.damageplayer.accountplayer.dir clientr.sweapon.typusclientr.sweapon.typus2);
    }
  }

That doesn't work... Neither does the NPC chat anything, nor does the hurt functon hurt the NPC, like it did when I did everything serverside.
Also, when there are NPCs to be hit, the player chats something like " hit:"","", "

My guess is that I cant iterate over the array with for like that and expect the elements to be objects.

How can I fix this?

I also wouldn't mind some hints on how to get my sword system faster. Right now it seems like it takes the player about half a second to chat "hit...".
Reply With Quote
  #2  
Old 02-21-2011, 01:01 PM
Demisis_P2P Demisis_P2P is offline
Kanto League Champion
Demisis_P2P's Avatar
Join Date: Jan 2005
Posts: 2,357
Demisis_P2P has much to be proud ofDemisis_P2P has much to be proud ofDemisis_P2P has much to be proud ofDemisis_P2P has much to be proud ofDemisis_P2P has much to be proud ofDemisis_P2P has much to be proud ofDemisis_P2P has much to be proud of
What is your latency?
Half a second seems about normal for serverside hit detection.
Doing the clientside check first doesn't seem like it would actually make it any faster, just more resource efficient for the server, I guess.
__________________
Reply With Quote
  #3  
Old 02-21-2011, 01:54 PM
AlexanderK AlexanderK is offline
Registered User
AlexanderK's Avatar
Join Date: Mar 2006
Location: Germany
Posts: 79
AlexanderK is on a distinguished road
Send a message via MSN to AlexanderK
Quote:
Originally Posted by Demisis_P2P View Post
What is your latency?
Half a second seems about normal for serverside hit detection.
Doing the clientside check first doesn't seem like it would actually make it any faster, just more resource efficient for the server, I guess.
No idea about my latency. How do I find out?
I guess making it more resource efficient for the server would be a good idea, too. In the thread I mentioned in the first post, someone said something about the script lagging the server.
Quote:
Originally Posted by ffcmike View Post
You can't pass clientside objects to the server like this, what we do on Classic is a similar area NPCs trigger but on both clientside and serverside, this also creates the illusion of no lag.
So the problem is that I can't handle Clientside objects on the Serverside?

If I used two checks like you described, I would need to hurt funcitons, one for Clientside and one for Serverside, right? And the bushes' hurt function would need to be clientside? There would still be some lag though as the bushes need to be hidden for everyone if they are slashed, which would need a trigger to the Serverside.

Man, this is really confusing.

What about xXziroXx's quote? There surely must be some way to check for the objects clientside and then pass them to the serverside.
Reply With Quote
  #4  
Old 02-21-2011, 01:09 PM
ffcmike ffcmike is offline
Banned
Join Date: Jul 2004
Location: London
Posts: 2,029
ffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond repute
Send a message via AIM to ffcmike Send a message via MSN to ffcmike
You can't pass clientside objects to the server like this, what we do on Classic is a similar area NPCs trigger but on both clientside and serverside, this also creates the illusion of no lag.
Reply With Quote
  #5  
Old 02-21-2011, 11:07 PM
ffcmike ffcmike is offline
Banned
Join Date: Jul 2004
Location: London
Posts: 2,029
ffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond repute
Send a message via AIM to ffcmike Send a message via MSN to ffcmike
It's much better to use the trigger function for this type of thing as opposed to public functions:

obj.trigger("Hit", param1);

As this would automatically be making the check as to whether the function "onHit" actually exists.

But yes you would need to do this both clientside (to make it appear instant to yourself), and serverside (for it to show to other players), for everyone else though this would be synced with your player, it's not a problem.

What I meant regarding the clientside objects is simply that the object on your client is not the same as the object on the server, for this type of thing to work you'd have to try something such as passing the name of the npc (if it was a local npc) or the coordinates of the npc to use with testnpcs(x, y);, which isn't really reliable.
Reply With Quote
  #6  
Old 02-21-2011, 11:08 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
Your latency is pretty high; you're in Germany and the servers are in Texas.

Here's how I would do it:
PHP Code:
// Weapon -Swords
function onActionServerSide(cmdsxsy) {
  if (
cmd == "slash") {
    
// security check: is the player too far away?
    
if (getDist(player.xplayer.ysxsy) > 4) {
      return; 
// player is too far away from the hit location
    
}
    
    
// security check: when was the last time they hit?
    
if (timevar2 player.lastHit 0.5) {
      return; 
// player last hit less than half a second ago
    
}

    
temp.radius 0.1;
    
temp.npcs player.level.findAreaNPCs(sx radiussy radiusradius 2radius 2);
    
    for (
temp.npc npcs) {
      
// it's good practice to pass the player object rather than
      // the account—it's just the object-oriented thing to do
      
npc.trigger("hitByPlayer"player);
    }
  }
}

function 
getDist(x1y1x2y2) {
  return (((
x1 x2) ^ 2) + ((y2 y1) ^ 2)) ^ 0.5;
}

//#CLIENTSIDE
function slashObjects(sxsy) {
  
temp.radius 0.1;
  
  for (
temp.npc findAreaNPCs(sx radiuxsy radiusradius 2radius 2)) {
    
npc.trigger("hitByPlayer"null); // second parameter is only needed for v5
  
}
  
  
triggerServer("gui"this.name"slash"sxsy);

This way, you don't have to worry about players tampering with a list of NPCs (it's also a pain to make that list since there's no easy way of identifying an NPC on clientside and serverside unless it's a putnpc2 or DB NPC; level NPCs don't have names and the IDs differ from clientside to serverside.)
__________________
Reply With Quote
  #7  
Old 02-22-2011, 03:17 AM
AlexanderK AlexanderK is offline
Registered User
AlexanderK's Avatar
Join Date: Mar 2006
Location: Germany
Posts: 79
AlexanderK is on a distinguished road
Send a message via MSN to AlexanderK
Thanks a lot you two! Very helpful.
I'll try doing it that way tomorrow.
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 03:27 AM.


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