Author Topic: [Solved] ScriptObject Confusion  (Read 2118 times)

Hey guys, I'm making a thing where you can start a tribe, or join a tribe. I'm pretty stumped on how to do this, though. I believe I should use ScriptObjects, which I have a minor understanding of. Basically, I was wondering how I'd be able to create a dynamic SO for each tribe that is created, and how to cycle through the existing tribe script objects (to check if a person creating a tribe isnt stealing the name of one already created). Would I create my own class? I'm kinda clueless.
« Last Edit: July 02, 2015, 03:20:16 PM by Johnny Blockhead »

Googling Torquescript Script Objects, here are a few guides:

http://docs.garagegames.com/tge/official/content/documentation/Reference/Introduction/Objects.html

http://tsforblockland.weebly.com/namespacing.html

The second link was created by me. Looking at it, I see it doesn't go too far into detail on how to utilize script objects, so I'll be updating it soon. Anyways, read through those, once you've done that and still have questions on certain things, we can help you out.

So, from what I understand I can do something like this:
function createTribe(%name, %owner)
{
   %tribe = new ScriptObject(%name @ "TribeObj")
   {
      class = TribeObj;
      owner = %owner;
      tribename = %name;
   };
   announce("The tribe" SPC %tribe.tribename SPC "was created by" SPC %tribe.owner @ "!");
}

And, I can assign functions to it:

//richards is the name of the tribe
function richardsTribeObj::Disband(%so)
{
   announce("The tribe" SPC %so.tribename SPC "has disbanded!");
   %so.delete();
}

But I still have no idea how to apply this to my situation. Here are some of the mysteries:
When I want to add a member to the tribe, what would I do? Would I just make a loop checking if member1 is defined, and if it is try member2, ect? Or is a better way just to make a big list-y string that has all of the member's IDs?
Another one is what exactly do classes do? I still haven't figured that one out.
Is there a way that I can make all TribeObjects inherit from something? Like, if I make a function such as the disband one, it'll work with richardsTribeObj but not NachoTribeObj.

When I want to add a member to the tribe, what would I do? Would I just make a loop checking if member1 is defined, and if it is try member2, ect? Or is a better way just to make a big list-y string that has all of the member's IDs?
You may want to look into SimSets, which are similiar to SimGroups (which is what things like ClientGroup are, with all their .add and .getcount and .getobject methods)

Another one is what exactly do classes do? I still haven't figured that one out.
Is there a way that I can make all TribeObjects inherit from something? Like, if I make a function such as the disband one, it'll work with richardsTribeObj but not NachoTribeObj.
These two kind of go together.
If you define function TribeObj::FunctionName then you can call richardsTribObj.FunctionName() or NachoTribeObj.FunctionName() and they'll both work, as long as both objects have class = TribeObj; set

You may want to look into SimSets, which are similiar to SimGroups (which is what things like ClientGroup are, with all their .add and .getcount and .getobject methods)

This was gonna be my suggestion. SimSets can have methods and variables on them just like SimObjects. SimSets are actually a type of SimObject. SimSets just also have the added bonus of holding member objects (SimSet::add(%obj1, %obj2, ...), SimSet::Remove(%obj1, %obj2, ...), SimSet::getCount(), SimSet::GetObject(%index)).

Thanks! I looked into simsets, and I tried to make the system. Due to it being really late, I haven't been able to test it out. If it makes no sense, tell me. I'll post any questions/concerns I get in the future relating to this here.
//Made by Piexes
function servercmdcreateTribe(%client, %name)
{
   if(%client.gold >= 200)
   {
      %tribe = new ScriptObject(%name @ "TribeObj")
      {
         class = Tribe;
         owner = %owner;
         tribename = %name;
         members = new SimSet();
      };
      announce("The tribe" SPC %name SPC "was created by" SPC %client @ "!");
   }
   else
   {
      %client.chatMessage("\c3You don't have enough gold to create a tribe!");
   }
}
function invite(%client, %target)
{
   if(%target $= "")
   {
      %client.chatMessage("\c3This command is for inviting people to your tribe.");
      %client.chatMessage("\c3You have to be the owner to do this. The syntax is /invite PersonToInvite");
   }
   else if(%client.tribe.owner != %client)
   {
      %client.chatMessage("\c3You either don't have a tribe, or you aren't the owner of that tribe!");
   }
   else
   {
      %target = findclientbyname(%target);
      if(%target $= "")
      {
         %client.chatMessage("\c3Target not found!");
         return;
      }
      if(%target.tribe == %client.tribe)
      {
         %client.chatMessage("\c3This person is already in the tribe!");
         return;
      }
      if(%target.hasPendingInvite == 1)
      {
         %client.chatMessage("\c3This person already has a pending invite.");
         return;
      }
      %target.chatMessage("\c3You have been invited to join the" SPC %client.tribe.tribename SPC "tribe. Use /accept to accept, and /deny to deny.");
      %target.hasPendingInvite = %client.tribe;
   }
}
function servercmdAccept(%client)
{
   if(%client.hasPendingInvite == 0 || %client.hasPendingInvite $= "")
   {
      %client.chatMessage("\c3You don't have a pending invite!");
   }
   else
   {
      //HasPendingInvite is secretly the ID for the tribe.
      %tribe = %client.hasPendingInvite;
      %client.chatMessage("\c3You have accepted the invite to the" SPC %tribe.tribename SPC "tribe.");
      %client.hasPendingInvite = "";
      %tribe.owner.chatMessage("\c2" @ %client.name SPC "has accepted the invite!");
      %tribe.members.add(%client);
   }
}
function servercmdDeny(%client)
{
   if(%client.hasPendingInvite == 0 || %client.hasPendingInvite $= "")
   {
      %client.chatMessage("\c3You don't have a pending invite!");
   }
   else
   {
      //HasPendingInvite is secretly the ID for the tribe.
      %tribe = %client.hasPendingInvite;
      %client.chatMessage("\c3You have denied the invite to the" SPC %tribe.tribename SPC "tribe.");
      %client.hasPendingInvite = "";
      %tribe.owner.chatMessage("\c0" @ %client.name SPC "has denied the invite.");
   }
}

Edit: Thanks phlack! I edited it on the actual script.
« Last Edit: July 02, 2015, 01:50:41 AM by Johnny Blockhead »

might want to rethink this part
      if(%target.hasPendingInvite == 1)
and
      %target.hasPendingInvite = %client.tribe;

probably want to use %target.hasPendingInvite != 0
or just %target.hasPendingInvite

So I wrote up a little Library to add and remove Tribes. Also, adding users or removing users from Tribes. This is the basic skeleton I've provided. You can add on to it, remove stuff, or just use it as a reference to improve yours better. It saves data, loads data (In directory config/server/Tribes/*), etcetera. I've done minimal testing just to detect any memory leaks and or logic errors.

You can view the source code below:

Edit: Users weren't actually being added to the simset. That is fixed now.

Tribes
Tribes (Raw)



Now here's a little documentation on the provided functions which you can utilize to add additional functionality.

TribeContainer Functions

Creating a new Tribe:
     tribeContainer.newTribe("TribeName");
      Returns Boolean


Removing an existing Tribe:
    tribeContainer.removeTribe("TribeName");
     Returns Boolean


Finding a Tribe by name:
    tribeContainer.getTribeByName("TribeName");
     Returns a simSet object.




GameConnection Functions:

Adding a client to a Tribe:
    clientObject.addToTribe("TribeName");
     Returns Boolean


Removing a client from a Tribe:
    clientObject.removeFromTribe("TribeName");
     Returns Boolean


Get the simSet Tribe object associated with the client:
    clientObject.getTribe();
     Returns Tribe Object (simSet)


Get the Tribe name from the client:
    clientObject.getTribeName();
     Returns A String



« Last Edit: July 02, 2015, 02:59:39 AM by elm »

Woah. Awesome job Elm. One question, what exactly is the tribeContainer? A SimGroup?
Also I'm kinda confused about storing variables to SimSets. If I can do that, can I just completely remove the ScriptObject from my script? And store the stuff to the SimSet?
« Last Edit: July 02, 2015, 02:26:01 AM by Johnny Blockhead »


Woah. Awesome job Elm. One question, what exactly is the tribeContainer? A SimGroup?

It's a ScriptGroup, which is a SimSet with ::onAdd and ::onRemove callbacks. They're unimportant to this implementation, so you could effectively switch out SimSet and ScriptGroup.

EDIT: I meant SimSet, not SimGroup.


Also I'm kinda confused about storing variables to SimSets. If I can do that, can I just completely remove the ScriptObject from my script? And store the stuff to the SimSet?

Yep.
« Last Edit: July 02, 2015, 02:45:26 AM by $trinick »

The tribeContainer is a Script Group that stores Sim Sets (Tribes). View line 77, notice you can store more information like the owner, or anything else you prefer.

You'll probably need to either write up a function that saves the tribeContainer every time you modify/add a new value to a Tribe or simply call

tribeContainer.save("config/server/Tribes/TribeContainer/tribeContainer.cs");

after each value is modified/added to keep the tribeContainer's simsets (Tribes) up to date.

Edit: Also, the code itself is documented pretty well, so looking through it you should be able to have some idea on what's going on.
« Last Edit: July 02, 2015, 02:46:44 AM by elm »

Thanks for the huge help, Elm! I have everything figured out, and wrote my own system using yours as a guide.