KevinBlast/marble/server/scripts/inventory.cs

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.
}