Game Development Community

Coding error on Throw()!

by FruitBatInShades · in Torque Game Engine · 01/26/2005 (10:35 am) · 9 replies

I'm trying to implement throwable objects. I've implemeted the code but am missing something fairly obvious I think. Sorry this is a long post but i'm not sure what i'm missing so I though i'd include it all.
My problem is that I get error messages (god i wish the console allowed copy and paste) saying that %obj is null. I haven't created it anywhere which is probablt the reason. Any ideas where i create that first grenade?
Grenade.cs
datablock ItemData(Grenade)
{
   category = "Mine";
   shapeFile = "~/data/shapes/healthKit.dts";
   mass = 1;
   friction = 1;
   elasticity = 0.3;//use for bounce
   repairAmount = 50;
   maxDamage = 0.2;
   directDamage = 125;
   damageRadius = 20;
   radiusDamage = 150;
   dynamicType = $TypeMasks::DamagableItemObjectType;
       explosion = CrossbowExplosion;
         fadeIn = 0;
};
function Grenade::Explode( %data, %obj, %col )
{

   %obj.setDamageState(Destroyed);
   %obj.schedule(999, "delete");
}

function Grenade::onDestroyed(%data,%obj)
{
   radiusDamage(%obj,%pos,%data.damageRadius,%data.radiusDamage,"Mine",0);
}
function ShapeBase::throwItem(%this,%data,%client){
   // Construct item to throw from the given datablock
   // (with a random rotation around the z axis)
   %item = new Item() {
      dataBlock    = %data;
      rotation     = "0 0 1 " @ (getRandom() * 360);
      sourceObject   = %client.player;
      client       = %client;
   };
   MissionCleanup.add(%item);
    %item.schedule(5555, "explode"); //<------- explode in 5555 miliseconds
   // Call the workhorse throw method...
   %this.throwObject(%item);
}
function ShapeBase::throwObject(%this,%obj){
   // Throw the given object in the direction the shape is
   // looking.  The force values are hardcoded...
   %eye = %this.getEyeVector();
   %vec = vectorScale(%eye, 20);
   // Add a vertical component to give the item a better arc
   
   %dot = vectorDot("0 0 1",%eye);
      if (%dot < 0)
            %dot = -%dot;
      %vec = vectorAdd(%vec,vectorScale("0 0 7",1 - %dot));
      // Add the shape's velocity
      %vec = vectorAdd(%vec,%this.getVelocity());
      // Set the object's position and initial velocity
      %pos = getBoxCenter(%this.getWorldBox());
      %obj.setTransform(%pos);
      %obj.applyImpulse(%pos,%vec);
      // Since the object is thrown from the center of the
      // shape, the object needs to avoid colliding with it&#180;s
      // thrower.
      %obj.setCollisionTimeout(%this);
}

#1
01/26/2005 (10:36 am)
default.bind.cs
moveMap.bindCmd(keyboard, "g", "commandToServer(\'throwGrenade\');", "");

It always says 'throwGrenade:command unknown' but if i enter 'commandToServer('throwGrenade');' in the console it executes!

Somewhere here I think i need to create a grenade object to throw. I'm a complete newb so be gentle :)
#2
01/26/2005 (11:14 am)
I would setup a proxy function for this. ie:

function throwGrenade( %val )
{
   if( ! %val )
      commandToServer( 'throwGrenade' );
}

moveMap.bind( keyboard, "g", throwGrenade );
#3
01/26/2005 (11:36 am)
@Rob: thanks, that worked :)

I've been looking into the other problem and I'm beginning to think that player is not what is being passed to 'function ShapeBase::throwObject(%this,%obj)'.

Errors are as follows:-

Register object failed for object (null) of class item.

Unable to find object: '0' attempting to call function XXX

where XXX = schedule, setTransform, applyImpulse and setCollisionTimeout.
#4
01/26/2005 (3:21 pm)
Hold on
#5
01/26/2005 (3:46 pm)
Here is an example, not sure if this will work tho :)

for the client binds
function useGrenade( %val )
{
    if( %val )
        commandToServer('useGrenade');
}

moveMap.bind(keyboard, "g", useGrenade);

on the server
function serverCmdUseGrenade( %client )
{
    %force = 100;
    %clientObj = %client.getControlObject();
    if( isObject(%clientObj) )
    {
        %clientObj.throwForce = %force;
        %clientObj.throwObject(Grenade);
    }
}

function ShapeBase::throwObject( %this, %obj )
{
    %item = new Item()
    {
        datablock = %obj;
        rotation = "0 0 1 " @ (getRandom() * 360);
        sourceObject = %this;
        client = %this.client;
    };
    MissionGroup.add(%item);


    // -- Start with the shape's eye vector...
    %eye = %this.getEyeVector();
    %vec = vectorScale(%eye, %this.throwForce);

    // -- Add a vertical component to give the object a better arc
    %verticalForce = %this.throwForce / 2;
    %dot = vectorDot("0 0 1",%eye);
    if( %dot < 0 )
        %dot = -%dot;
    %vec = vectorAdd(%vec,vectorScale("0 0 " @ %verticalForce,1 - %dot));

    // -- Add the shape's velocity
    %vec = vectorAdd(%vec,VectorScale(%this.getVelocity(), %obj.mass));

    // -- Set the object's position and initial velocity
    %pos = getBoxCenter(%this.getWorldBox());
    //hobbs - little hack of sorts to make the flag or any other object for that matter
    //not stick to ceilings and floors and stuff
    %pos = setWord(%pos, 2, getWord(%pos, 2) - getWord(%item.getObjectBox(), 5) / 1.7);

    %item.setTransform(%pos);
    %item.applyImpulse(%pos,%vec);

    // -- Since the object is thrown from the center of the
    //    shape, the object needs to avoid colliding with it's
    //    thrower.
    %item.setCollisionTimeout(%this);
}

You'll need a datablock named Grenade too.
#6
01/27/2005 (1:25 am)
Thanks Robert. It seems that my problem is related to scope. My Grenade datablock doesn't seem to be found. If I use the healthKit datablock, it works. So i assume I'm missing a definition or not creating the grenade in the right place. I always get

Grenade is not a member of GameBaseData
#7
01/27/2005 (1:52 am)
I use projectiles for grenades, they work much better than items IMHO.
#8
01/27/2005 (3:07 am)
At last got it all working, but i'm not telling you what the problem was

@Josh: thanks for the idea but i've only just got this half working and don;t want to start again :) Plus we have 16 grenade types!
#9
01/27/2005 (11:44 am)
I hacked a 'thrown' projectile together some time ago, this method seemed to work pretty well, I had an impact explosive one and then a time delayed fuse type. Only goofyness was after it was 'thrown', the time delayed device[dynamite stick] had some weird spinning issues...ie, when the 'stick of tnt' hit and bounced off terrain, it spun wildly, like a cheerleaders baton??? Is there a parameter that will take this wild spin away? I had to adjust some projectile parameters to get it 'humanly distanced thrown', it had a 'normal' range for a handthrown item and nice ballistic trajectory, :), the higher I aimed, the closer it fell....! My final thrown weapon is intended to be somewhat like a mine; it's thrown, lands, and then triggers an animation sequence of 'arming' and then will 'wait' until it's triggered. I considered adding both Collision and LOS meshes to it, to allow it being 'triggered' with gunfire, effectively 'acitvating' it's attack/damage animation. This type of scripting has been sidetracked, while I'm back into character development.