Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   NPC Scripting (https://forums.graalonline.com/forums/forumdisplay.php?f=8)
-   -   Rescripting default baddies (https://forums.graalonline.com/forums/showthread.php?t=78383)

DustyPorViva 01-18-2008 06:25 AM

Rescripting default baddies
 
Well, I think every classic server would benefit from the default baddies being rescripted in GS2... so I thought I would discuss some here.
My main curiosity is whether they should be serverside or clientside. I'll post my opinions about both:

serverside:
- Baddies will be able to be taken down with others
- baddies will be, of course, 'synced' for all players. If you see a baddy there, so will everyone else.
- can be used for 'multi-player' dungeons, where it takes more than one player to beat it. On the clientside... this can be done, but everyone will be doing their own thing when it comes to killing the baddies.
- Jumpy movement. Since there is a min 0.1 timeout on serverside, movement wouldn't be as smooth.
- Biggest factor: because it's on the serverside, lagging will have a big effect on how the baddy operates. If you lag, the experience can be easily ruined as things like attacks and such are delayed from server to client.

clientside:
- one person won't be able to clear the way for others
- usages will be much more 'one-player' type of feel.
- no walking through a whole dungeon without encountering a baddy because someone else killed them
- smoother movement, of course!
- you will be the only target. Could easily be scripted to chase other players, but since it's on the clientside... other players won't be seeing the same thing you are so it won't make sense.
- fast response. Even if you're lagging, since the baddy is operating on the clientside you won't notice any negative sideeffects(except for serverside things like drops).

I've also had an idea of syncing clientside and serverside info on movement/position so I could get the benefit of clientside and serverside... but since you can only send data to the clientside through attr's... I don't think that worked.
Anyways, I think getting these done will help a lot, and I'm willing to collaborate ideas with anyone here to get them done. I don't care about getting the details done, I can get the middle-stuff done... I'm more worried about creating a baddy that takes the best of both worlds, though feel free to discuss anything else about them. If you want me to post my details about what I've learned with baddies since I've been studying them, just post so and I will.

MrAnonymous_P2P 01-18-2008 06:54 AM

I am not really a scripter or anything but I get the basics.

From what your saying it sounds like the serverside has more pluses, it just seems like the player would have to not lag. And the majority of graal players don't lag so I would go with serverside.

Serverside +1

coreys 01-18-2008 07:28 AM

Quote:

Originally Posted by MrAnonymous_P2P (Post 1370315)
And the majority of graal players don't lag...

Noooot really...

And you should try out both! :)
If you're intending to make this public use than that's the obvious choice. The courteous choice, rather, since it would accommodate servers that might want either one, but since this an act of free will you don't HAVE to go through all that work. ;)

Inverness 01-18-2008 07:32 AM

Do clientside, just make it so when you kill a baddy it dies on other player's clients too. Its not hard.
Quote:

Originally Posted by DustyPorViva
but since you can only send data to the clientside through attr's...

When an npc is created on clientside it would have an ID variable which you can use to locate it from any client. Thats how you go from serverside to clientside.
PHP Code:

// Script in the NPC
public function sendserverkill(omitleveln) {
  for (
temp.iallplayers) {
    if (
i.account == omit || i.level.name != leveln)
      continue;
    
with (iSystem.clientfunction2(null"npcfunction"this.id"onServerKill");
  }
}
//#CLIENTSIDE
function onServerKill() {
  
// When the kill message is received from server.
}
function 
sendserverkill() {
  
System.serverfunction2(null"npcfunction"this.levelthis.id"sendserverkill"player.accountthis.level);


It is using this class:
PHP Code:

// Serverside to Clientside Function
public function clientfunction(fobjfnamep0p1p2p3p4p5p6p7p8p9) {
  
temp.out 0;

  
triggerclient("gui"this.name"clientfunction"fobjfnamep0p1p2p3p4p5p6p7p8p9);
  
waitfor(this"ClientFunctionEnd"5);
  
temp.out thiso.cfreturn;
  
thiso.cfreturn null;
  return 
temp.out;
}
public function 
clientfunction2(fobjfnamep0p1p2p3p4p5p6p7p8p9) {
  
triggerclient("gui"this.name"clientfunction2"fobjfnamep0p1p2p3p4p5p6p7p8p9);
}
public function 
npcfunction(p0p1p2p3p4p5p6p7p8p9) {
  
temp.obj findlevel(p0);
  for (
temp.iobj.npcs) {
    if (
i.id == p1) {
      
i.(@ p2)(p3p4p5p6p7p8p9);
      break;
    }
  }
}
function 
onActionServerSide() {
  if (
params[0] == "end") {
    
thiso.cfreturn params[1];
    
trigger("ClientFunctionEnd"null);
  }
  else if (
params[0] == "serverfunction") {    
    if (
params[1] != null)
      
triggerclient("gui"this.name"end"makevar(params[1] @ "." params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]));
    else 
      
triggerclient("gui"this.name"end"makevar(params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]));
  }
  else if (
params[0] == "serverfunction2") {
    if (
params[1] != null)
      
makevar(params[1] @ "." params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]);
    else 
      
makevar(params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]);
  }
}
//#CLIENTSIDE
function onActionClientSide() {
  if (
params[0] == "end") {
    
thiso.sfreturn params[1];
    
trigger("ServerFunctionEnd"null);
  }
  else if (
params[0] == "clientfunction") {    
    if (
params[1] != null)
      
triggerserver("gui"this.name"end"makevar(params[1] @ "." params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]));
    else 
      
triggerserver("gui"this.name"end"makevar(params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]));
  }
  else if (
params[0] == "clientfunction2") {
    if (
params[1] != null)
      
makevar(params[1] @ "." params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]);
    else 
      
makevar(params[2])(params[3], params[4], params[5], params[6], params[7], params[8], params[9], params[10], params[11], params[12]);
  }
}
public function 
npcfunction(p0p1p2p3p4p5p6p7p8p9) {
  
findnpcbyid(p0).(@ p1)(p2p3p4p5p6p7p8p9);
}
public function 
serverfunction(fobjfnamep0p1p2p3p4p5p6p7p8p9) {
  
temp.out 0;
  
  
triggerserver("gui"this.name"serverfunction"fobjfnamep0p1p2p3p4p5p6p7p8p9);
  
waitfor(this"ServerFunctionEnd"5);
  
out thiso.sfreturn;
  
thiso.sfreturn null;
  return 
out;
}
public function 
serverfunction2(fobjfnamep0p1p2p3p4p5p6p7p8p9) {
  
triggerserver("gui"this.name"serverfunction2"fobjfnamep0p1p2p3p4p5p6p7p8p9);


For some reason, clientside level objects don't have anything in their npcs variable, only on serverside.

You could also make your own system for keeping track of baddy objects by ID on clientside and serverside.

Tigairius 01-18-2008 05:15 PM

Quote:

Originally Posted by DustyPorViva (Post 1370313)
Well, I think every classic server would benefit from the default baddies being rescripted in GS2... so I thought I would discuss some here.
My main curiosity is whether they should be serverside or clientside. I'll post my opinions about both:

serverside:
- Jumpy movement. Since there is a min 0.1 timeout on serverside, movement wouldn't be as smooth.

Depending on how you use the move() function, it doesn't have to be jumpy at all.

DustyPorViva 01-18-2008 05:37 PM

I have tried and tried and tried move(), while not 'jumpy' in the same sense, it flies all over the place at times when there is any delay on the serverside; since it will continue to move in the last known direction it was heading, then suddenly update and appear at it's more updated location. If anyone can give me an example script of using move() correctly serverside, I'd appreciate it!

Tigairius 01-18-2008 05:41 PM

Quote:

Originally Posted by DustyPorViva (Post 1370352)
I have tried and tried and tried move(), while not 'jumpy' in the same sense, it flies all over the place at times when there is any delay on the serverside; since it will continue to move in the last known direction it was heading, then suddenly update and appear at it's more updated location. If anyone can give me an example script of using move() correctly serverside, I'd appreciate it!

You should calculate it's next move before it even starts moving, that way once it finishes the move function it doesn't have to calculate it and have those weird bugs. Calculate it based on the destination x and y, and where you want it to go from there, then do the first move function, repeat, and do the other move function, repeat, etc. Basically all of the calculations should be delayed by 1 move function.

DustyPorViva 01-18-2008 07:16 PM

I have tried that, but honestly I don't have much experience with move() so I doubt I was doing it properly...

coreys 01-20-2008 04:14 AM

I really do think we should be able to have quicker timeouts. Just restrict the amount of data that can be processed in quicker timeouts. But quite honestly, I've done serverside baddies before, and the .1 timeout limit really doesn't make it look choppy at all.

But yeah, I still say you should do both. ;(


All times are GMT +2. The time now is 04:13 AM.

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