Game Development Community

Simple resource manager built for the RTS Starter Kit

by Josh Williams · in RTS Starter Kit · 11/16/2004 (1:22 pm) · 11 replies

This resource was submitted by Jared Barger. I'm just copying the text into this new forum area. Thanks Jared!

--------------------
I threw this together for use with the rts kit but it could be used with anything. Just a simple setup to handle player collected resources that's all driven by script code.

First, the resource handler object. Exec this in the server init.cs

Continued next post...

#1
11/16/2004 (1:23 pm)
// Supply/Resource manager object

// Depends on interaction from player mobiles ie. the gatherer would make
// the calls to alter a supply value

// Assumes no supply can be negative

// Assumes you're using the "default" GuiTextProfile to derive from

function SupplyMan::Ctor(){
 // Text colors to represent our resource "standing"
 %dangerousLowColor = "255 0 0";
 %gettingLowColor = "128 128 0";
 %normalColor = "0 255 0";
 %gettingHighColor = "128 128 0";
 %dangerousHighColor = "255 0 0";
 
 if(!isObject(DangerousLowTextProfile)) new GuiControlProfile(DangerousLowTextProfile: GuiTextProfile){
   fontColor = %dangerousLowColor;
 };
 if(!isObject(GettingLowTextProfile)) new GuiControlProfile(GettingLowTextProfile: GuiTextProfile){
   fontColor = %gettingLowColor;
 };
  if(!isObject(NormalTextProfile)) new GuiControlProfile(NormalTextProfile: GuiTextProfile){
   fontColor = %normalColor;
 };
  if(!isObject(GettingHighTextProfile)) new GuiControlProfile(GettingHighTextProfile: GuiTextProfile){
   fontColor = %gettingHighColor;
 };
  if(!isObject(DangerousHighTextProfile)) new GuiControlProfile(DangerousHighTextProfile: GuiTextProfile){
   fontColor = %dangerousHighColor;
 };

 %supplyMan = new SimSet(SupplyMan);

 %so = new SimObject(Gold){
  count = 0;               // Current value
  min = 0;                 // Minimum allowed
  max = -1;                // Maximum allowed (-1 is infinite)
  gui = 0;                 // GuiTextCtrl to display the value in (0 = none)
  
  dangerousLow = 0;        // Resource is running very low...
  gettingLow = 10;         // running low..
  gettingHigh = -1;        // getting to much.. (-1 = can't have too high)
  dangerousHigh = -1;      // overdose time (-1 = can't have too high)
 };//gold
 %supplyMan.add(%so);
 
 %so = new SimObject(Food){
  count = 0;
  min = 0;
  max = 100;
  gui = 0;

  dangerousLow = 0;
  gettingLow = 0;
  gettingHigh = -1;
  dangerousHigh = -1;
 };//Food
 %supplyMan.add(%so);
 
 MissionCleanup.Add(%supplyMan);
 return %supplyMan;
}//Ctor

// Get Supply ------------------------------------------------------------------
function SupplyMan::GetSupply(%this, %supply){
 %clientSupply = SupplyMan::FindSupply(%this, %supply);

 if(%clientSupply == -1){
  Error("SupplyMan::GetSupply - Bad supply requested: " @ %supply);
  return -1;
 }//if

 return %clientSupply.count;
}//GetSupply

// Set Supply ------------------------------------------------------------------
function SupplyMan::SetSupply(%this, %supply, %val){
 %clientSupply = SupplyMan::FindSupply(%this, %supply);
 if(%clientSupply == -1){
  Error("SupplyMan::SetSupply - Bad supply requested: " @ %supply);
  return -1;
 }//if
 
 %clientSupply.count = %val;
 SupplyMan::JustifySupply(%this, %supply);
 SupplyMan::UpdateGui(%clientSupply);
}//SetSupply

// Find Supply -----------------------------------------------------------------
function SupplyMan::FindSupply(%this, %supply){
 %supplyMan = %this.client.SupplyMan;

 for(%supplyIndex = 0; %supplyIndex < %supplyMan.getCount(); %supplyIndex++){
  if(%supplyMan.getObject(%supplyIndex).getName() $= %supply)
   return %supplyMan.getObject(%supplyIndex);
 }//for
 
 return -1;
}//FindSupply

// Alter Supply ----------------------------------------------------------------
function SupplyMan::AlterSupply(%this, %supply, %val){
 %clientSupply = SupplyMan::FindSupply(%this, %supply);
 if(%clientSupply == -1){
  Error("SupplyMan::AlterSupply - Bad supply requeseted: " @ %supply);
  return;
 }//if
 
 %clientSupply.count += %val;
 SupplyMan::JustifySupply(%this, %supply);
 SupplyMan::UpdateGui(%clientSupply);
}//AlterSupply

Continued next post...
#2
11/16/2004 (1:23 pm)
// Tie supply to gui -----------------------------------------------------------
function SupplyMan::TieSupplyToGui(%this, %supply, %gui){
 %clientSupply = SupplyMan::FindSupply(%this, %supply);
 if(%clientSupply == -1){
  Error("SupplyMan::TieSupplyToGui - Bad supply requested: " @ %supply);
  return;
 }//if
 
 %clientSupply.gui = 0;
 if(%gui.GetClassName() !$= "guiTextCtrl"){
  Error("SupplyMan::TieSupplyToGui - Supply must tie to a text control, attempted: " @ %supply);
  return;
 }//else if
 
 %clientSupply.gui = %gui;
 SupplyMan::UpdateGui(%clientSupply);
}//TieSupplyToGui

// Update gui ------------------------------------------------------------------
function SupplyMan::UpdateGui(%clientSupply){
 if(!IsObject(%clientSupply.gui)) return;

 %gui = %clientSupply.gui;
 %gui.SetValue(%clientSupply.count);
 
 if(%clientSupply.count <= %clientSupply.dangerousLow)
  %gui.SetProfile(DangerousLowTextProfile);
 else if(%clientSupply.count <= %clientSupply.gettingLow)
  %gui.SetProfile(GettingLowTextProfile);
 else if(%clientSupply.dangerousHigh != -1){
  if(%clientSupply.count >= %clientSupply.dangerousHigh)
   %gui.SetProfile(DangerousHighTextProfile);
 }//else if
 else if(%clientSupply.gettingHigh != -1){
  if(%clientSupply.count >= %clientSupply.gettingHigh)
   %gui.SetProfile(GettingHighTextProfile);
 }//else if
 else
  %gui.SetProfile(NormalTextProfile);
}//UpdateGui

// Init Gui --------------------------------------------------------------------
function SupplyMan::InitGui(%this){
 %supplyMan = %this.SupplyMan;

 for(%index = 0; %index < %supplyMan.GetCount(); %index++){
  SupplyMan::UpdateGui(%supplyMan.GetObject(%index));
 }//for
}//InitGui

// Justify Supply --------------------------------------------------------------
function SupplyMan::JustifySupply(%this, %supply){
 %clientSupply = SupplyMan::FindSupply(%this, %supply);
 if(%clientSupply == -1){
  Error("SupplyMan::JustifySupply - Bad supply requested: " @ %supply);
  return;
 }//if
 
 %count = %clientSupply.count;
 
 if(%count < %clientSupply.min) %count = %clientSupply.min;
 else if(%clientSupply.max != -1){
  if(%count > %clientSupply.max) %count = %clientSupply.max;
 }//else if
 
 %clientSupply.count = %count;
}//JustifySupply

Then in server/scriptes/core/gameconnection.cs at the end of RTSConnection::onClientEnterGame add

%this.SupplyMan = SupplyMan::Ctor();
SupplyMan::InitGui(%this);

Each function's %this param is the calling object which is assumed to be a building or avatar.

ie. farm blows up
in on destroy

SupplyMan::AlterSupply(%this, food, -8);

where food would be a declared SimObject in SupplyMan::Ctor
#3
11/16/2004 (9:22 pm)
You beat me to it hehe.

I gotta chalk this one up to jumping in before really understanding the engine well enough I suppose. I hadn't realized that sim objects were globally accessible until I was messing with this some. I'm sure it's mentioned in docs somewhere.

Some changes I've made since I threw this out...

Removing the FindSupply function completely. A call to IsObject(%supply) to verify it exists can replace the nasty for loops you'd hit with the way it is now every time you wanted to get at a resource. This also makes the %this parameter unnecessary for everything, unless you wanted to know what unit initiated things.

Added some params to the "constructor" so that you can define resource limits based upon the current level you're playing.

Umm. There's a lot that could be updated, but I suppose the skeleton of things is there. It was done in about an hour (actually made me a few minutes late for work). I'm just jammering now so I'll just quit while I'm ahead.
#4
11/17/2004 (7:27 am)
@Jared:
Cool, thanks for the resource, I had a play with the above last night, but due to the fact I'm very new to TGE RTS etc, I couldn't understand how to (where and in which file) to add say(gold food) and remove (gold food) when a buliding got placed, or a unit(player) got spawned,
so being a bit on the cheaky side
could you add a quick example, say place this to add gold here in XXX file, and place this in XXX file when a building if placed to remove gold,
Once I can see it in place i can then understand it, I know it sounds like reverse engineering, but I can read code and understand it better than reading how to do it from a book, yes I have Kennith Finney's book
This may help other thickwits like me ;-)
Cheers
#5
11/17/2004 (7:35 am)
As an FYI (and please do not take this as a diss of the resource, it has nice functionality), I'm working on expanding and splitting the functionality into server and client side scripting, to make it a bit more authoritative.

Once I get that done, I'll provide some base examples (and a gui as well probably if someone wants to do some artwork for a gold icon, wood icon, food icon, etc.) on how to use it in more complex modes.

It's fun working with it so far, nice work, especially for an hour!
#6
11/17/2004 (10:55 am)
@Chris
Assuming nothing is changed like I mentioned above here's a quick rundown of how it could go.

In the Ctor have a food resource defined

in starter.rts/server/scripts/items/building.cs inside the datablock definition for the example building add
provideSupply = food; // defined supply
supplyCount = 10; // How much I add

then in serverCmdPlaceBuilding in the same file add
SupplyMan::AlterSupply(%this, %data.provideSupply, %data.supplyCount);

in starter.rts/server/scripts/avatars/player.cs inside the RTSUnitData::onDisabled function add
if(%this.getDataBlock().provideSupply)
SupplyMan::AlterSupply(%this, %this.getDataBlock().provideSupply, %this.getDataBlock().supplyCount * -1);

That'll create, add, and removed the supply counts.

@Stephen
No offense taken what so ever. I really enjoy programming and sometimes get to feeling like a little kid that just did some coloring where he almost stayed in the lines. I then proceed to rush off to call something "done" before it should be. I've done it before and I'm darn certain I'll do it again sometime.
#7
11/17/2004 (2:15 pm)
Stephen:
I can whip up the icons. What sizes do you want them to be? :)

Edit:
Actually, I already have them made. Just finished them. Currently they are 32x32. With tweaking, I could get them smaller.
#8
11/17/2004 (9:30 pm)
Sorry, tonight was my night off! 32x32 sounds fine, although we it might be nice to have a slightly "shorter" (y-axis) version for those that want a very thin but long/flat resource bar.

We'll have to play with it to see what looks good and is still usable.
#9
11/18/2004 (4:32 pm)
Stephen:
Here are the 32x32 icons. I hope they are useful. I'll work on a skinnier version, soon.

muro.ygingras.net/rts/icon_gold32.PNGGold

muro.ygingras.net/rts/icon_food32.PNGFood

muro.ygingras.net/rts/icon_wood32.PNGWood

muro.ygingras.net/rts/icon_stone32.PNGStone

Zip Containing All 32x32 Icons

Edit:
32x20 icons:

muro.ygingras.net/rts/icon_gold20.PNGGold

muro.ygingras.net/rts/icon_food20.PNGFood

muro.ygingras.net/rts/icon_wood20.PNGWood

muro.ygingras.net/rts/icon_stone20.PNGStone

Zip Containing All 32x20 Icons

(I may rework these later. It is late and these were something I thought I'd whip up quickly.)

Edit: Updated with stone icon.
#10
11/19/2004 (12:11 pm)
Yeah i'm a newb to i dont even know where the long texts go though you gave a short explanation :S
#11
07/31/2005 (2:39 am)
Ok I have done all above now how do I see how many resources I have/ how do I take away resources so if you build a new building 100 resources are taken away?