Help with hunger bar scripting *Learning Torque*

Author Topic: Help with hunger bar scripting *Learning Torque*  (Read 1887 times)

I haven't found many answers to how the function works, but I have been told it's a repeating one that loops

Specifics: I'm trying to make a hunger bar that decreases every x amount of seconds/min but I'm kind of stuck...

Correct me I I'm wrong because I probably am

Function Applydamage

Errrrr.. yep I get stuck there...

Yes, I have made about 3 helps before this one, and yes I have been trying to learn from guides, but alas I couldn't find anything I'm not giving up I just need specific examples instead of others telling me what to do so I can have a visual representation and learn from it..
« Last Edit: July 29, 2017, 02:41:50 PM by woof :3 »

so for a basic timed loop, other languages you can just do some form of
Code: [Select]
while(true)
{
//dostuff
sleep(1000);
}

Torque is single threaded, so doing something like that would cause your game to hang
instead in Torque, for a general time delayed loop, use
Code: [Select]
function loopingFunction()
{
cancel($loop);
//dostuff
$loop = schedule(1000, 0, loopingFunction);
}

but that uses a global variable, so only one loop would run on the server at the time
since you're doing a hunger thing, you may want to have either one global loop which then loops through players and does stuff to them, or a loop per client
Code: [Select]
function loopingFunction()
{
cancel($loop);
for(%i = 0; %i < ClientGroup.getCount(); %i++)
{
%client = ClientGroup.getObject(%i);
//dostuff
}
$loop = schedule(1000, 0, loopingFunction);
}
or
Code: [Select]
function loopingFunction(%client)
{
cancel(%client.loop);
//dostuff
%client.loop = schedule(1000, 0, loopingFunction, %client);
}

do note that you can find all of this in previous addons and/or by searching coding help

What you need to do is learn how to create a function and then a schedule.

So to start you’ll need a function that decreases your hunger every time it’s called. Since you’re keeping track of a players hunger it makes most sense to create the function on the player class. This can be done like this:

function player::hungerTick(%this)
{
    %this.hungerLevel += 1;
    %this.bottomPrint(%this.hungerLevel);
    %this.schedule(100, hungerTick);
}

This is very basic but it should help you understand how a schedule works somewhat and how to store variables on a player. You should look into finding out how to call this function when a player spawns. This will start at 0 and keep increasing the players hunger every 100 ms. You can do checks in the function like if(%this.hungerLevel == 100) %this.kill(); or whatever.

I wrote a simple hunger mod for some guy a while ago, I guess you can take a look at the code. I'm not really going to explain whats going on though, sorry:



$hydra::hungerTickTime = 30000;

function gameConnection::hunger_start(%this)
{
   %this.hunger = 100;
   %this.hungerTick();
}

function gameConnection::hunger_end(%this)
{
   cancel(%this.hungerTick);
}

function gameConnection::hungerTick(%this)
{
   cancel(%this.hungerTick);
   
   %player = %this.player;
   if(isObject(%player))
   {
      %this.hunger--;
      
      if(%this.hunger <= 0)
      {
         //do dmg
         %this.hunger = 0;
         %this.player.addHealth(-5);
         bottomPrint(%this,"\c0Hunger: \c2" @ %this.hunger @ "\c0% - Taking Damage.",5);   
      }
      else
      {
         bottomPrint(%this,"\c6Hunger: \c2" @ %this.hunger @ "\c6%",5);   
      }
   }
   %this.hungerTick = %this.schedule($hydra::hungerTickTime,hungerTick);
}

commented version of elm's code. it should help you learn what each part of the code does

$hydra::hungerTickTime = 30000; //time in milliseconds (a thousandth of a second) between each hunger decrease

//function that starts the hunger loop. gameconnection is the client being called to.
//if you want to test this on yourself, do findclientbyname(yourname).hunger_start();

function gameConnection::hunger_start(%this)
{
   %this.hunger = 100; //field for starting hunger amount.
   %this.hungerTick(); //calls the loop that will decrease hunger
}

//function that cancels the loop for decreasing hunger. when called, it will stop decreasing
function gameConnection::hunger_end(%this)
{
   cancel(%this.hungerTick); //cancels the field that is equal to the loop
}

//this is the primary function
//this is a loop, which means that as long as it exists, the function will keep calling itself over and over
//in order to loop it, a schedule(); function is set. schedules will execute functions after a certain delay

function gameConnection::hungerTick(%this)
{
   cancel(%this.hungerTick); //this makes sure the loop doesn't overlap with itself if called twice
   
   %player = %this.player;
   if(isObject(%player)) //does the player exist? if yes then it continues, if no it skips over the rest
   {
      %this.hunger--; //decrement operation. %this.hunger will decrease by 1
      
      if(%this.hunger <= 0) //is the hunger level below 0? if yes, it continues. if no, it skips over this part
      {
         %this.hunger = 0;
         %this.player.addHealth(-5); //decreases player health by 5
         bottomPrint(%this,"\c0Hunger: \c2" @ %this.hunger @ "\c0% - Taking Damage.",5);
      }
      else
      {
         bottomPrint(%this,"\c6Hunger: \c2" @ %this.hunger @ "\c6%",5);   
      }
   }
        //here's the part that repeats the function in a loop
        //the syntax is %object.schedule(%timeinmilliseconds,%function,%anyparametersthatexist);
        //this will call any function provided with parameters after a certain amount of time
        //it's set to the field %this.hungertick so that it may be canceled at any given time
        //it is important that you set the loop to a field or variable otherwise it will go on indefinitely and cannot be canceled

    %this.hungerTick = %this.schedule($hydra::hungerTickTime,hungerTick);
}


Ok so where do you get these variables, are they made up or part of a function list? If they are made up, then it seems a bit better to understand, but if you use a function list, please give me a link to these functions

They are 'made up'.

$ denotes a global variable - it is set for any other function to use and does not disappear
% denotes a local variable - it is only set inside the function and disappears after the function ends

function quack(%duck)
{
   echo(%duck);
}
is the same as
function quack(%moo)
{
   echo(%moo);
}

I'm guessing you're mostly confused about %this.

When elm's functions get called they're not just by doing hunger_end(); they're used on a gameConnection (a client) object instead, so it's %client.hunger_end();. The first variable in a function being called on an object is the object itself, so you're able to access the object being used. You could name %this whatever you wanted.

From another topic, hope it belps

Here's how it works:

See the function declaration? The engine handles those arguments and the function calling, so all you have to do is find out what is being passed into your function that you made that the engine is able to implement.

If the engine calls: data::onMount(data, player, slotNum) you can make the 3 args of your function anything you want as long as you use them,
function data::onMount(%data, %player, %slotNum) is the same as function data::onMount(%image, %obj, %slot), it's just you have to use those passed argument names in your function.

If you make function data::onMount(%data, %obj, %slot, %something) the engine will not pass the 4th argument (%something) because the engine is only using 3 arguments to pass.
This is the same when making your own functions and passing your arguments to something else.

Example: We will use the first 4 arguments (args) and have them pass onto another function
abc("test 1", "test ABC", "test c", "useless argument");
Code: [Select]
function abc(%a, %b, %c, %d)
{
      cde(%a, %b, %c);
}

Arguments being passed but named differently, they will still work because they were passed from another function - note that %d will NEVER be passed from abc because this function only has 3 arguments.
Code: [Select]
function cde(%c, %d, %e) {}%c is now "test 1"
%d is now "test ABC"
%e is now "test c"

the 4th argument we tried to pass is now thrown away because we hit the max arguments in our passed function - the engine is like this too except it wants it perfect, if you are low on arguments or have too many the console will yell at you for it because they are engine functions directly in the game for torquescript (not torquescript functions)

Oh thanks I need this, I was confused the whole time, because I thought there wasn't a format, and the fact that the function variables were actually made up, but now that I understand these I think I can see how it works, but I'll keep trying.. I know I'm getting there, because I'm starting to understand. I'll try to make some of my own functions and I'll post them to see if I did them right, but thanks for all of these I can benifit from these. The code along with some explanations really helped thanks alot.

Ok so now the last thing I need to know is what are these and could you give a reference, because I see it most of the time and it's also the reason I get confused sometimes.

---> .  Eg: %this.hungerbar

And


----> :: Eg: Player::Hungerbar

"%this" is the object that was defined in the function - can be anything and named different as long as it was defined and used with the same name
the ".hungerbar" part is a variable on the object that stays there forever until the object is deleted or the "%this" variable is changed to something else

"Player::" is a class function, so doing things like %playerID.HungerBar(); will call it as Player::HungerBar(%playerID) - based on what the object's class is, it will call that function

%object.function(); calls the function

function Object::function(%this)
{

}
declares a function