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-05-2011, 10:27 AM
racycle racycle is offline
smooth as eggs
racycle's Avatar
Join Date: Jul 2008
Location: Chanko
Posts: 136
racycle will become famous soon enough
Send a message via AIM to racycle
How would you do this?

I am going to attempt at making this work. However I am rather bad at coding. I want to start a weapon system but am pretty lost in how it should be done. I am aware of the basic db setup. Every item should work differently so I know I can't use a list of variables to be sent to a master system.

So all items should have 1 thing in common , if they are primary(s key, right hand) and secondary(a key,left hand). Each item works differently then the next. Also each item can "upgrade". A shield would become stronger, sword would grow bigger/stronger. A hammer would gain the ability to break new things. Boomerang would go farther and so one. When one item is being used the other one should be disabled for that time.

Now onto the Question, What would you guys, the forum suggest for this? At the moment I'm thinking having every item its own weapon script with its way of working. How that would work , I have no clue. I'm not looking for any direct help or handouts, as that would just be lame of me :P. Just merely pointers on how i should handle this. Suggestions on the best ways to preform this are greatly appreciated.

-Killa Be
Reply With Quote
  #2  
Old 02-05-2011, 03:46 PM
Chompy Chompy is offline
¯\(º_o)/¯
Chompy's Avatar
Join Date: Sep 2006
Location: Norway
Posts: 2,815
Chompy is just really niceChompy is just really niceChompy is just really nice
Send a message via MSN to Chompy
There are some methods which you could take a look at instead of having each item having it's own weapon script.
  1. DBNPC (functions as a cache) -> Script
  2. Files (slow-cache) -> DBNPC (Loaded into a DBNPC to function as a "faster-cache") -> Script
  3. Files -> Script (DEPRECATED, do not use this method. File I/O alone is slow as hell compared to caching the items in a DBNPC)
Method 1 and 2 are the most used ones. DO NOT USE METHOD 3
Using method 2 you only need filebrowser to edit, create and remove items.
This could be good for staff who don't need NC or doesn't know how to script to make adjustments to items. Should only be handles by trusted persons or a System Administrator or something of that kind.

1)
You have a database with all the data for each item. Within this DB you create an API to include retrieving the wanted information. Something like this could work (Basic idea though)

PHP Code:
//DBNPC: ItemDatabase
function onInitialized() onCreated(); // redirect to onCreated() when server restarts etc

function onCreated() {
  
ItemDB this/* This will function as a global pointer serverside.
                          Scripts serverside can access this DB by doing
                          ItemDB.function() or ItemDB.variable etc */
  
this.init true;    // Scripts can check ItemDB.init to see if items are initialized

  
createItemData();
}

function 
createItemData() {
  
/* Here you can either give each item an unique numerical ID or
      a unique string ID. Possible to both as well though! */

   // Example of variable setup
  
this.vars = {"itemname""type""subtype""slot""customdata"};

  
// Numerical ID examples
  
this.item_1 = {"Big Sword""weapon""twohanded""primary", {"slow"}};
  
this.item_2 = {"Small Sword""weapon""onehanded""primary", {"fast"}};

  
// String ID examples
  
this.item_bigsword = {"Big Sword""weapon""twohanded""primary", {"slow"}};
  
this.item_smallsword = {"Small Sword""weapon""onehanded""primary", {"fast"}};

  
/* Important Notice!
      If you want something more flexible you can also store
      each item as an TStaticVar object */
}

// This is a simple way to get itemdata
/* Possible to do:
      temp.item = ItemDB.getitem("bigsword"); OR
      temp.item = ItemDB.getitem(1);

      You can now use temp.item to read info about said item.  */
public function getitem(id) {
  return 
makevar("this.item_" id);
}

/* Just need a variable from an item?
    temp.itemname = getitemvar(1, "itemname"); -> "Big Sword"

    This function will function faster (Not really noticed unless you have hundreds of variables) when using TStaticVar objects

    then you can just do:
      return makevar("this.item_" @ id @ "." @ var);
*/
public function getitemvar(id, var) {
  
temp.index this.vars.index(var);
  if (
temp.index > -1) {
    return 
makevar("this.item_" id)[temp.index];
  }else {
    return 
0;
  } 
By using this you can either create an WNPC or a create a class which you join to the player to handle all the item actions.
I would suggest joining a class to the player. Then you
access the player object by using this.var, this.function() etc

player.join("itemcontrol"); <- Do this on login in Control-NPC

PHP Code:
// WNPC: ItemControl OR class: ItemControl
// Make sure you have access to the player object when working
// with a WNPC serverside!

public function equipitem(id) {
  
temp.item ItemDB.getitem(id);

  
// Use the information gathered from the ItemDatabase
}


public function 
useitem(id) {
  
temp.item ItemDB.getitem(id);

  
// Act based on the information retrieved, should the item be equipped?
  // Summon something? Make you go super fast? Do that here
}

// ETC 
This is just an example of how it could be done using a DBNPC -> Script. Use it as a base
__________________
Reply With Quote
  #3  
Old 02-05-2011, 03:46 PM
Chompy Chompy is offline
¯\(º_o)/¯
Chompy's Avatar
Join Date: Sep 2006
Location: Norway
Posts: 2,815
Chompy is just really niceChompy is just really niceChompy is just really nice
Send a message via MSN to Chompy
2)

This method includes having a textfile for each item

These textfiles you want to store under the levels/ somewhere. I'll state why later. Let's choose the folder: levels/itemdata

You'll probably also need to add levels/itemdata/*.txt into folder config.
It's also possible to use the file prefix .arc, but this is personal preference
as they are in the end, both text files.

It's also possible to use .ini files, then I suggest you lookup some of Inverness' scripts in the code gallery. I will not cover that though

In each textfile for each item you want to use a setup like this:

NPC Code:

itemname=Big Sword
type=weapon
subtype=twohanded
slot=primary
customdata=slow,common



This is because you can load all of the data needed by using obj.loadvars()
If you saved the above file as bigsword.txt you could do:

PHP Code:
temp.itemdata.loadvars("levels/itemdata/bigsword.txt");

echo(
temp.itemdata.itemname); // would echo Big Sword 
This we can use in a DBNPC to cache the items.
Here it would be better to use TStaticVar's to store the item data
Not using TStaticVar would mean extra work and opens for errors when going
file -> array

PHP Code:
// DBNPC: ItemDatabase

function onInitialized() onCreated();

function 
onCreated() {
  
this.itemDB this;

  
cacheItems();
}

function 
cacheItems() {
  
// Load the levels/itemdata/ folder
  
  
temp.folder.loadfolder("levels/itemdata/*.txt"0);
  for(
temp.file temp.folder) {
    
cacheItem(temp.file);
  }

  
// A simple failsafe, if one of the cacheItem() functions below
  // add anything into the this.errors array, display that here!

  
if (this.errors.size() < 1) {
    
this.cached true;
  }
  else {
    echo(
"[ItemDatabase]: There was an error when caching!");
    echo(
"-- Errors: "this.errors);
  }
}

function 
cacheItem(file) {
  
temp.data.loadvars("levels/itemdata/"file);
  
temp.dynamic_varnames temp.data.getdynamicvarnames(); // store it for reuse

  // Check if we actually got any data
  
if (temp.dynamic_varnames.size() > 0) {
    
temp.variable "this.item_" temp.id// Store the wanted variable name

    // Get string id by stripping the ending .txt from the file
    
temp.id file.substring(0file.length() - 4);

    
/* Go through each of the dynamic variables
        (This is excluding the default variables like timeout, scriptlogerrors etc) */
    
    
for(temp.var : temp.dynamic_varnames) {
      
makevar(temp.variable "." temp.var) = makevar("temp.data." temp.var);
    }
 
    
/* It is possible to use obj1.copyfrom(obj2), but I'm not using it
        since it does more than just copying the variables, and you don't
        need more than that. Personal Preference though.
        I've also experienced some oddities when using this while using
        custom object names */
  
}
  
// Found no dynamic variables, add an error into this.errors!
  
else {
    
this.errors.add("No data found for \""file @"\"");
  }
}

// Ways to retrieve item data

public function getitem(id) {
  return 
makevar("this.item_"id);
}

public function 
getitemvar(id, var) {
  return 
makevar("this.item_" id "." @ var);

We now have a cache for our textfiles. We can retrieve the item data by using

PHP Code:
temp.itemdata ItemDB.getitem("bigsword");

echo(
temp.itemdata.slot); // primary 
You can now use the ItemDatabase DBNPC to retrieve information about items you need info about.

Now, the reason you want all of your text files into levels/ is because of this one event which allows you to create automatic updating of itemcache when editing files!

PHP Code:
function onLevelFileUpdated(filename) {
  
// replace "itemdata/" with the folder you use
  
if (!filename.starts("itemdata/") || !filename.ends(".txt")) return;
  
  
// This expects to find something  on the first line.
  // No reason the leave the top line empty (Not sure if it reads linebreaks.. hm)

  // Edit the if statement below if you want another behavior chech for 
  // empty files

  
temp.testfile.loadlines("levels/"@filename);
  if (
temp.testfile[0] == NULL) {
    
// The file has been deleted, do something about that here!
  
}
  else {
    
// The files has been updated, do something about that here!
  
}
  
  
// Lets retrieve the updated file
  
temp.tokens filename.tokenize("/");
  
temp.file temp.tokens[temp.tokenst.size()-1]; // example: bigsword.txt
  
temp.item temp.file.substring(0temp.file.length()-4); // example: bigsword

  // Use the temp. files above to do something when an item's textfile has been
 // deleted or updated/edited! :)

  // CODE HERE


If the examples are a bit tough to follow, just give me a PM and I'll look into simplifying them

This is just an idea of how you can do it using files and a DBNPC!
(It's also possible to use a WNPC to cache items, just saying!)

All the scripts I have written from the top of my head, so look at it as "gs2 psuedocode" :v I have not tested the scripts and they are not finished ones. The Database scripts could probably work if pasted, but these two methods are just to give you an idea of how to do it.
__________________

Last edited by Chompy; 02-05-2011 at 06:57 PM.. Reason: fixed a small typo in one of the scripts
Reply With Quote
  #4  
Old 02-05-2011, 06:36 PM
Cubical Cubical is offline
Banned
Join Date: Feb 2007
Posts: 1,348
Cubical has a brilliant futureCubical has a brilliant futureCubical has a brilliant futureCubical has a brilliant futureCubical has a brilliant futureCubical has a brilliant futureCubical has a brilliant future
What about 'enchanting' and creating dynamic items? or would you have to make all the items ahead of time and just replace the current one with the enchanted one. I've made multiple item systems but this has always baffled me.
Reply With Quote
  #5  
Old 02-05-2011, 06:49 PM
Chompy Chompy is offline
¯\(º_o)/¯
Chompy's Avatar
Join Date: Sep 2006
Location: Norway
Posts: 2,815
Chompy is just really niceChompy is just really niceChompy is just really nice
Send a message via MSN to Chompy
Quote:
Originally Posted by Cubical View Post
What about 'enchanting' and creating dynamic items? or would you have to make all the items ahead of time and just replace the current one with the enchanted one. I've made multiple item systems but this has always baffled me.
http://forums.graalonline.com/forums...tem+enchanting

Take a look at the script I made further down on the page

when storing what items the player has, store the enchant together with the BASE of the item, and parse the item with the given enchant when the player logs on etc
__________________
Reply With Quote
  #6  
Old 02-05-2011, 06:58 PM
Cubical Cubical is offline
Banned
Join Date: Feb 2007
Posts: 1,348
Cubical has a brilliant futureCubical has a brilliant futureCubical has a brilliant futureCubical has a brilliant futureCubical has a brilliant futureCubical has a brilliant futureCubical has a brilliant future
What about creating random stats? I've always wondered that too?
Reply With Quote
  #7  
Old 02-05-2011, 07:04 PM
Chompy Chompy is offline
¯\(º_o)/¯
Chompy's Avatar
Join Date: Sep 2006
Location: Norway
Posts: 2,815
Chompy is just really niceChompy is just really niceChompy is just really nice
Send a message via MSN to Chompy
Then you edit the TStaticVar of the item afterwards to add the random stats. Since these random stats are not part of the base item, you need to store these variables together with their random values somewhere along with the base of the item, and then handle it from there.

Basically the system I described in the posts above handles the base of items. If you want to alter it, you do it to the TStaticVar afterwards and store the changes as well as the base of the item. Then when you login you retrieve the base of the item and then parse the custom variables into the TStaticVar. Then you eventually synchronize the items into clientr. strings or objects on the clientside so clientside scripts like inventories can access the parsed item data.

This is why TStaticVar's are more superior to arrays when you want something more flexible.
__________________
Reply With Quote
  #8  
Old 02-05-2011, 08:10 PM
Chompy Chompy is offline
¯\(º_o)/¯
Chompy's Avatar
Join Date: Sep 2006
Location: Norway
Posts: 2,815
Chompy is just really niceChompy is just really niceChompy is just really nice
Send a message via MSN to Chompy
I totally forgot about a method involving SQL -> Script
Thanks to Deas for pointing out. This is for the more advanced users though. If I recall there are documentation of how to do this already out there though, use the search function! I might write a small guide for SQL -> Script later

List of threads which can be helpful for the more advanced users:
http://forums.graalonline.com/forums...ad.php?t=76567
http://forums.graalonline.com/forums...ad.php?t=73396
http://forums.graalonline.com/forums...ad.php?t=81961
http://forums.graalonline.com/forums...ad.php?t=74162

AND FOR ALL YOU SCRIPTERS OUT THERE; DO NOT USE THE TERM MUDLIB FOR ITEM SYSTEMS
http://forums.graalonline.com/forums...ad.php?t=80450


EDIT;
If you're interested in using SQL, I suggest reading over these forum threads, there are probably more out there, but didn't bother to search more with this rediculous waiting time on searches.
http://forums.graalonline.com/forums...hp?t=134256362
http://forums.graalonline.com/forums...ad.php?t=86173
__________________

Last edited by Chompy; 02-05-2011 at 08:36 PM..
Reply With Quote
  #9  
Old 02-06-2011, 03:17 AM
racycle racycle is offline
smooth as eggs
racycle's Avatar
Join Date: Jul 2008
Location: Chanko
Posts: 136
racycle will become famous soon enough
Send a message via AIM to racycle
alright chompy and cubical , I don't think I explained the way this should act well enought , but this does give me a general idea.
Reply With Quote
  #10  
Old 02-06-2011, 06:43 AM
Chompy Chompy is offline
¯\(º_o)/¯
Chompy's Avatar
Join Date: Sep 2006
Location: Norway
Posts: 2,815
Chompy is just really niceChompy is just really niceChompy is just really nice
Send a message via MSN to Chompy
Quote:
Originally Posted by racycle View Post
alright chompy and cubical , I don't think I explained the way this should act well enought , but this does give me a general idea.
Answered your PM
__________________
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 04:39 AM.


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