Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   NPC Scripting (https://forums.graalonline.com/forums/forumdisplay.php?f=8)
-   -   Trash Spawning Script Problem (https://forums.graalonline.com/forums/showthread.php?t=134264816)

Gunderak 10-17-2011 11:42 AM

Trash Spawning Script Problem
 
What I am trying to accomplish is a script that spawns trash across the gmap and then the trash is pickupable but my script(s) seem to have an issue.
They seem to be spawning WAY more than its supposed to.
Anyway here are the scripts.

The npc trashspawner
PHP Code:

function onCreated() {
  
this.spawntime = 0.05;
  
onTimeout();
}

function 
onTimeout() {
  if (
server.trashspawned > 10) {
    
server.trashspawned = 10;
  }
  if (
server.trashspawned < 10) {
    
onSpawning();
  }
  
settimer(this.spawntime);
}

function 
onSpawning() {
  
this.spawn = int(random(1, 6));
  if (
this.spawn == "1") {
    
this.item = "Tire";
    
this.itemimage = "bc_trash-tire.png";
  }
  if (
this.spawn == "2") {
    
this.item = "Bottle";
    
this.itemimage = "bc_trash-bottle.png";
  }
  if (
this.spawn == "3") {
    
this.item = "Paper";
    
this.itemimage = "bc_trash-paper.png";
  }
  if (
this.spawn == "4") {
    
this.item = "Motherboard";
    
this.itemimage = "bc_trash-motherboard.png";
  }
  if (
this.spawn == "5") {
    
this.item = "Soda";
    
this.itemimage = "bc_trash-sodacan.png";
  }
  if (
this.spawn == "6") {
    
this.item = "Wires";
    
this.itemimage = "bc_trash-wires.png";
  }
  if (
server.trashspawned < 10) {
    
temp.spawnx = random(0, 448);
    
temp.spawny = random(0, 448);
    
temp.t = putnpc2(temp.spawnx, temp.spawny, null);
    
temp.t.itemimage = this.itemimage;
    
temp.t.itemname = this.item;
    
temp.t.join("gunderak_trashdrop");
  }
} 

The class gunderak_trashdrop
PHP Code:

function onCreated() {
  if (
server.trashspawned > 10) {
    
destroy();
  }
  
setshape(1, 32, 32);
  
setimg(this.itemimage);
}

function 
onActionGrab() {
  
client.trash += 1;
  
server.trashspawned -= 1;
  
triggerclient("gui", "-System/Message", "msg", "Server", "You gained [" @ this.itemname @ "]! You now have: " @ client.trash @ " Trash!", "orange");
  
destroy();
}

//#CLIENTSIDE
function onCreated() {
  if (
server.trashspawned > 10) {
    
destroy();
  }
  
triggerserver("weapon", "-System/Trash", "spawn");
  
dontblock();
  
drawunderplayer();
  
setshape(1, 32, 32);
  if (
onwall(this.x, this.y)) {
    
destroy();
    
triggerserver("weapon", "-System/Trash", "unspawn");
  }
} 

The weapon -System/Trash
PHP Code:


function onActionServerSide() {
  if (
params[0] == "unspawn") {
    if (
server.trashspawned > 0) {
      
server.trashspawned--;
    }
  }
  if (
params[0] == "spawn") {
    if (
server.trashspawned < 10) {
      
server.trashspawned++;
    }
  }
} 

Any help is appriciated ;)
PS: yes I know im probably doing this completely wrong, I cannot think of any other way to accomplish my goal.
If you would like put in an easier way your more than welcome.

Gunderak 10-17-2011 04:01 PM

I wonder how many people have stolen this half working script..

ffcmike 10-17-2011 05:49 PM

Quote:

Originally Posted by Gunderak (Post 1671054)
I wonder how many people have stolen this half working script..

It's a pretty poor and inefficient set of scripts.

Looking at NPC "trashspawner" you have multiple checks to determine the item where it's possible it will have already been determined.
This could be made more efficient by either using a switch statement or storing the item names and images within an array, and then retrieving this.array[this.spawn - 1];.
It also looks as if you're setting a 0.05 second timeout which shouldn't even work Serverside, where again you have a potentially unnecessary condition being checked where a conflicting condition could be true.

Within "gunderak_trashdrop" you are checking a server. variable Clientside when these are only readable Serverside.
It also appears as if you are communicating from Serverside to Clientside, and then back to Serverside just to increment a server. variable when this can be done at the point of dropping the NPC. Not only is this totally unnecessary and suggesting that you're not really aware of what you're doing, it will also result in a triggerserver for every single client that creates the NPC. It can also result in both the spawn and unspawn trigger being sent at the same time when (even if it was a good idea) you should only have one of these triggers occurring. Calling destroy(); Clientside will also only destroy the NPC on your client, you have no mechanism to permanently destroy the NPC and prevent it from loading on yours or other peoples clients.

You yet again within "-System/Trash" you have the potential for unnecessary condition checks where params[0] == "spawn" can be checked for despite params[0] == "unspawn" already being determined as true, albeit you don't need this trigger anyway.

Gunderak 10-17-2011 11:31 PM

Thankyou for the feedback I have taken alot of that into considoration and am going to re script it from scratch, may I ask if there would be any way to do like a triggerserver or a triggerclient on a NPC? this was one of my main problems.

0PiX0 10-17-2011 11:44 PM

http://forums.graalonline.com/forums...ad.php?t=87732

fowlplay4 10-18-2011 12:01 AM

You don't even need to use client-side or a timeout to spawn trash at all.

DB

PHP Code:

function onCreated() {
  
// Configuration
  
this.max_trash = 20;
  
// Initialize Trash DB
  
destroyTrash();
  
spawnTrash();
}

function 
destroyTrash() {
  
// Loop through each piece of Trash
  
for (temp.trash: this.spawned_trash) {
    
// Destroy Trash NPC
    
temp.trash.destroy();
  }
  
// Initialize Spawned Trash Array
  
this.spawned_trash = {};
}

function 
spawnTrash() {
  
// Spawn Trash until Maximum Reached
  
while (this.spawned_trash.size() < this.max_trash) {
    
// Create Trash
    
temp.trash = createTrash();
    
// Add Trash to DB
    
this.spawned_trash.add(temp.trash);
  }
}

function 
createTrash() {
  
// Create Trash NPC
  
temp.trash = putnpc2();
  
temp.trash.join("trash");
  return 
temp.trash;
}

public function 
trashInDB(obj) {
  return (
obj in this.spawned_trash);
}

public function 
pickedUpTrash(obj) {
  
// Remove and Destroy Trash
  
this.spawned_trash.remove(obj);
  
obj.destroy();
  
// Spawn More Trash
  
spawnTrash();
} 

Class: trash

PHP Code:

function onPlayerEnters() {
  
// Check if Trash in DB
  
if (!TrashDB.trashInDB(this)) {
    
// Not found so destroy it
    
destroy();
  }
}

function 
onActionGrab() {
  
// Notify DB of Trash Picked Up
  
TrashDB.pickedUpTrash(this);
} 


Gunderak 10-18-2011 07:36 AM

You make things so much simpler.
All I have to do now is add the images of random trash and presto.
Would you possible know how to put names and images in an array?
maybe something like.
PHP Code:

temp.trash = {
  {
"trashone.png", Name},
  {
"trashtwo.png", Name}
}; 

I believe this is how a "3D" array works?
But how would you read the information from that and pick a random trash object O_O
PHP Code:

this.chosen = random(0, temp.trash.size()); 

Yet again im probably horribly wrong.
I was just thinking doing an array would make it look much nicer and be easier to add more items, rather than doing this.
PHP Code:

temp.chosen = random(1, 3);
if (
temp.chosen == "1") {
  
this.item = "Garbage 1";
  
this.image = "Image for it";
}
if (
temp.chosen == "2") {
  
this.item = "Garbage 2";
  
this.image = "Image for it";
}
if (
temp.chosen == "3") {
  
this.item = "Garbage 3";
  
this.image = "Image for it";
} 


Tolnaftate2004 10-18-2011 07:58 AM

Quote:

Originally Posted by Gunderak (Post 1671100)
PHP Code:

this.chosen = random(0, temp.trash.size()); 

Yet again im probably horribly wrong.
I was just thinking doing an array would make it look much nicer and be easier to add more items, rather than doing this.
PHP Code:

temp.chosen = random(1, 3);
if (
temp.chosen == "1") {
   ...
} 


The return value of random is a float. The probability that it returns a particular value is (almost) zero. So try int(random(...)).

Gunderak 10-18-2011 08:08 AM

wont using int(random(0, 5)); return 0, 1, 2, 3, 4 or 5 instead of random numbers like 4.719827 and 5.827591?
I shall have to see if it returns words xD

Gunderak 10-18-2011 09:58 AM

@Fowlplay i have made a few modifications to your system, it now works perfectly except for one slight problem. the items spawn on walls.
ive tried to put a if(onwall(this.x, this.y)){ and then destroy it but it does absolutely nothing.

Twinny 10-18-2011 10:24 AM

Quote:

Originally Posted by Gunderak (Post 1671107)
@Fowlplay i have made a few modifications to your system, it now works perfectly except for one slight problem. the items spawn on walls.
ive tried to put a if(onwall(this.x, this.y)){ and then destroy it but it does absolutely nothing.

Try using onwall2 with this.height and this.width

ffcmike 10-18-2011 10:31 AM

Quote:

Originally Posted by Gunderak (Post 1671107)
@Fowlplay i have made a few modifications to your system, it now works perfectly except for one slight problem. the items spawn on walls.
ive tried to put a if(onwall(this.x, this.y)){ and then destroy it but it does absolutely nothing.

Quote:

Originally Posted by Twinny (Post 1671108)
Try using onwall2 with this.height and this.width

Is it possible that onwall(); may be detecting the NPC itself as blocking?
Within the original script dontblock(); is used Clientside, so on Serverside it would still be blocking.
It could always be made to do an onwall() check before dropping the NPC rather than destroying it afterwards.

Gunderak 10-18-2011 01:06 PM

the script is serverside and an onwall check skews it up.
so I can't put it in that particular script.

cbk1994 10-18-2011 01:24 PM

Quote:

Originally Posted by Gunderak (Post 1671110)
the script is serverside and an onwall check skews it up.

How? You need to be more specific than "skews it up" or we can't help you.

Gunderak 10-18-2011 02:34 PM

if you do if onwall serverside it sais it is onwall constantly.

xXziroXx 10-18-2011 02:46 PM

Regarding the random string, you could do this:

PHP Code:

// List of available trash
temp.listOfTrash = {
  { 
"Trash #1", "nameofimage" },
  { 
"Trash #2", "nameofimage" },
  { 
"Trash #2", "nameofimage" }
};

// Generates a random trash entity from the trash array
temp.trashToSpawn = randomstring(temp.listOfTrash);

// Sets temporary vars to increase code readability
temp.trashName = temp.trashToSpawn[0];
temp.trashImage = temp.trashToSpawn[1]; 


Quote:

Originally Posted by Gunderak (Post 1671113)
if you do if onwall serverside it sais it is onwall constantly.

Are you using a custom tiletype 1 (newtiles) tileset on the server? Sounds like you are. To fix it you need to add the levels to newtilesetlevels in the serveroptions.

Example:

PHP Code:

newtilesetlevels=mylevelname1.nw,overworld1_,mylevelname2.nw,mylevels_,mal 

As you can see it doesn't have to be exact level names.

Gunderak 10-19-2011 08:20 AM

thanks for the random trash choser, works like a charm.
and no, we are using the default tile types, we are however using a custom tileset.


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

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