259 lines
7.6 KiB
C#
259 lines
7.6 KiB
C#
|
//-----------------------------------------------------------------------------
|
||
|
// Torque Game Engine
|
||
|
//
|
||
|
// Copyright (c) 2001 GarageGames.Com
|
||
|
// Portions Copyright (c) 2001 by Sierra Online, Inc.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
// This inventory system is totally scripted, no C++ code involved.
|
||
|
// It uses object datablock names to track inventory and is generally
|
||
|
// object type, or class, agnostic. In other words, it will inventory
|
||
|
// any kind of ShapeBase object, though the throw method does assume
|
||
|
// that the objects are small enough to throw :)
|
||
|
//
|
||
|
// For a ShapeBase object to support inventory, it must have an array
|
||
|
// of inventory max values:
|
||
|
//
|
||
|
// %this.maxInv[GunAmmo] = 100;
|
||
|
// %this.maxInv[SpeedGun] = 1;
|
||
|
//
|
||
|
// where the names "SpeedGun" and "GunAmmo" are datablocks.
|
||
|
//
|
||
|
// For objects to be inventoriable, they must provide a set of inventory
|
||
|
// callback methods, mainly:
|
||
|
//
|
||
|
// onUse
|
||
|
// onThrow
|
||
|
// onPickup
|
||
|
//
|
||
|
// Example methods are given further down. The item.cs file also contains
|
||
|
// example inventory items.
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Inventory server commands
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
function serverCmdUse(%client,%data)
|
||
|
{
|
||
|
%client.getControlObject().use(%data);
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// ShapeBase inventory support
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
function ShapeBase::use(%this,%data)
|
||
|
{
|
||
|
// Use an object in the inventory.
|
||
|
if (%this.getInventory(%data) > 0)
|
||
|
return %data.onUse(%this);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
function ShapeBase::throw(%this,%data,%amount)
|
||
|
{
|
||
|
// Throw objects from inventory. The onThrow method is
|
||
|
// responsible for decrementing the inventory.
|
||
|
if (%this.getInventory(%data) > 0) {
|
||
|
%obj = %data.onThrow(%this,%amount);
|
||
|
if (%obj) {
|
||
|
%this.throwObject(%obj);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
function ShapeBase::pickup(%this,%obj,%amount)
|
||
|
{
|
||
|
// This method is called to pickup an object and add it
|
||
|
// to the inventory. The datablock onPickup method is actually
|
||
|
// responsible for doing all the work, including incrementing
|
||
|
// the inventory.
|
||
|
%data = %obj.getDatablock();
|
||
|
|
||
|
// Try and pickup the max if no value was specified
|
||
|
if (%amount $= "")
|
||
|
%amount = %this.maxInventory(%data) - %this.getInventory(%data);
|
||
|
|
||
|
// The datablock does the work...
|
||
|
if (%amount < 0)
|
||
|
%amount = 0;
|
||
|
if (%amount)
|
||
|
return %data.onPickup(%obj,%this,%amount);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
function ShapeBase::maxInventory(%this,%data)
|
||
|
{
|
||
|
// If there is no limit defined, we assume 0
|
||
|
return %this.getDatablock().maxInv[%data.getName()];
|
||
|
}
|
||
|
|
||
|
function ShapeBase::incInventory(%this,%data,%amount)
|
||
|
{
|
||
|
// Increment the inventory by the given amount. The return value
|
||
|
// is the amount actually added, which may be less than the
|
||
|
// requested amount due to inventory restrictions.
|
||
|
%max = %this.maxInventory(%data);
|
||
|
%total = %this.inv[%data.getName()];
|
||
|
if (%total < %max) {
|
||
|
if (%total + %amount > %max)
|
||
|
%amount = %max - %total;
|
||
|
%this.setInventory(%data,%total + %amount);
|
||
|
return %amount;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
function ShapeBase::decInventory(%this,%data,%amount)
|
||
|
{
|
||
|
// Decrement the inventory by the given amount. The return value
|
||
|
// is the amount actually removed.
|
||
|
%total = %this.inv[%data.getName()];
|
||
|
if (%total > 0) {
|
||
|
if (%total < %amount)
|
||
|
%amount = %total;
|
||
|
%this.setInventory(%data,%total - %amount);
|
||
|
return %amount;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
function ShapeBase::getInventory(%this,%data)
|
||
|
{
|
||
|
// Return the current inventory amount
|
||
|
return %this.inv[%data.getName()];
|
||
|
}
|
||
|
|
||
|
function ShapeBase::setInventory(%this,%data,%value)
|
||
|
{
|
||
|
// Set the inventory amount for this datablock and invoke
|
||
|
// inventory callbacks. All changes to inventory go through this
|
||
|
// single method.
|
||
|
|
||
|
// Impose inventory limits
|
||
|
if (%value < 0)
|
||
|
%value = 0;
|
||
|
else {
|
||
|
%max = %this.maxInventory(%data);
|
||
|
if (%value > %max)
|
||
|
%value = %max;
|
||
|
}
|
||
|
|
||
|
// Set the value and invoke object callbacks
|
||
|
%name = %data.getName();
|
||
|
if (%this.inv[%name] != %value)
|
||
|
{
|
||
|
%this.inv[%name] = %value;
|
||
|
%data.onInventory(%this,%value);
|
||
|
%this.getDataBlock().onInventory(%data,%value);
|
||
|
}
|
||
|
return %value;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
function ShapeBase::clearInventory(%this)
|
||
|
{
|
||
|
// To be filled in...
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
function ShapeBase::throwObject(%this,%obj)
|
||
|
{
|
||
|
// Throw the given object in the direction the shape is looking.
|
||
|
// The force value is hardcoded according to the current default
|
||
|
// object mass and mission gravity (20m/s^2).
|
||
|
%throwForce = %this.throwForce;
|
||
|
if (!%throwForce)
|
||
|
%throwForce = 20;
|
||
|
|
||
|
// Start with the shape's eye vector...
|
||
|
%eye = %this.getEyeVector();
|
||
|
%vec = vectorScale(%eye, %throwForce);
|
||
|
|
||
|
// Add a vertical component to give the object a better arc
|
||
|
%verticalForce = %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,%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's
|
||
|
// thrower.
|
||
|
%obj.setCollisionTimeout(%this);
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Callback hooks invoked by the inventory system
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// ShapeBase object callbacks invoked by the inventory system
|
||
|
|
||
|
function ShapeBase::onInventory(%this, %data, %value)
|
||
|
{
|
||
|
// Invoked on ShapeBase objects whenever their inventory changes
|
||
|
// for the given datablock.
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// ShapeBase datablock callback invoked by the inventory system.
|
||
|
|
||
|
function ShapeBaseData::onUse(%this,%user)
|
||
|
{
|
||
|
// Invoked when the object uses this datablock, should return
|
||
|
// true if the item was used.
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
function ShapeBaseData::onThrow(%this,%user,%amount)
|
||
|
{
|
||
|
// Invoked when the object is thrown. This method should
|
||
|
// construct and return the actual mission object to be
|
||
|
// physically thrown. This method is also responsible for
|
||
|
// decrementing the user's inventory.
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
function ShapeBaseData::onPickup(%this,%obj,%user,%amount)
|
||
|
{
|
||
|
// Invoked when the user attempts to pickup this datablock object.
|
||
|
// The %amount argument is the space in the user's inventory for
|
||
|
// this type of datablock. This method is responsible for
|
||
|
// incrementing the user's inventory is something is addded.
|
||
|
// Should return true if something was added to the inventory.
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
function ShapeBaseData::onInventory(%this,%user,%value)
|
||
|
{
|
||
|
// Invoked whenever an user's inventory total changes for
|
||
|
// this datablock.
|
||
|
}
|