Initial commit

This commit is contained in:
Brian Beck 2025-09-11 16:56:30 -07:00
parent 2211ed7650
commit ebb3dc9cdd
10121 changed files with 801 additions and 4 deletions

View file

@ -0,0 +1,468 @@
// BonusCategories
// You can create CBonuses that arbitrarily combine any number of
// these categories. Pretty cool.
// Prefixes - tests a player's orientation relative to an object
// Noun - tests two players' heights and one player's speed
// Qualifier - tests an object's horizontal speed, vertical speed, and hangtime
// Description - very specific category for flag passes
//
exec("scripts/TR2Prefixes.cs");
exec("scripts/TR2Nouns.cs");
exec("scripts/TR2Qualifiers.cs");
exec("scripts/TR2Descriptions.cs");
exec("scripts/TR2WeaponBonuses.cs");
function BonusCategory::performEffects(%this, %component, %obj)
{
// DEBUG! Don't play dummy sounds
if (%component.sound $= "blah.wav")
return;
serverPlay2d(%component.sound);
// Particle effects
}
function BonusCategory::createCategoryData(%this, %p0, %p1, %p2, %p3, %p4)
{
// Add some dynamic info to the data before returning it. Save the parameter
// values for calculating variance.
%categoryData = %this.data.get(%p0, %p1, %p2, %p3, %p4);
%categoryData.numParameters = %this.dimensionality;
for (%i=0; %i<%categoryData.numParameters; %i++)
%categoryData.parameter[%i] = %p[%i];
return %categoryData;
}
// Nouns
new ScriptObject(Noun)
{
class = Noun;
superclass = BonusCategory;
dimensionality = 3;
passerSpeedLevels = 4;
grabberSpeedLevels = 4;
grabberHeightLevels = 4;
passerSpeedThreshold[0] = 10;
passerSpeedThreshold[1] = 35;
passerSpeedThreshold[2] = 57;
passerSpeedThreshold[3] = 85;
grabberSpeedThreshold[0] = 10;
grabberSpeedThreshold[1] = 35;
grabberSpeedThreshold[2] = 57;
grabberSpeedThreshold[3] = 85;
grabberHeightThreshold[0] = 5;
grabberHeightThreshold[1] = 30;
grabberHeightThreshold[2] = 90;
grabberHeightThreshold[3] = 230;
soundDelay = 0;
};
// Nouns play in 3D
function Noun::performEffects(%this, %component, %obj)
{
// DEBUG! Don't play dummy sounds
if (%component.sound $= "blah.wav")
return;
serverPlay2d(%component.sound);//, %obj.getPosition());
}
function Noun::evaluateold(%this, %grabber, %flag)
{
%passerSpeed = VectorLen(%flag.dropperVelocity);
%grabberSpeed = %grabber.getSpeed();
%grabberHeight = %grabber.getHeight();
// Don't award a Noun bonus if the flag is on a goal
if (%flag.onGoal)
return;
// Might be able to abstract these loops somehow
// Passer speed
for(%i=%this.passerSpeedLevels - 1; %i>0; %i--)
if (%passerSpeed >= %this.passerSpeedThreshold[%i])
break;
// Grabber speed
for(%j=%this.grabberSpeedLevels - 1; %j>0; %j--)
if (%grabberSpeed >= %this.grabberSpeedThreshold[%j])
break;
// Grabber height
for(%k=%this.grabberHeightLevels - 1; %k>0; %k--)
if (%grabberHeight >= %this.grabberHeightThreshold[%k])
break;
//echo("NOUN: passSpeed = " @ %passerSpeed @ " grabSpeed = " @ %grabberSpeed @ " grabHeight = " @ %grabberHeight);
//echo("NOUN: " SPC %i SPC %j SPC %k);
return %this.createCategoryData(%i, %j, %k);
}
function Noun::evaluate(%this, %player1, %player2, %flag)
{
if (%flag !$= "")
{
// Don't award a Noun bonus if the flag is on a goal
if (%flag.onGoal)
return %this.createCategoryData(0, 0, 0);
// If the flag thinks it is airborn, yet it's not moving...
if (%flag.getHeight() > 7 && %flag.getSpeed() < 3)
return %this.createCategoryData(0, 0, 0);
// Use a special Noun for water pickups
if (%flag.inLiquid)
return $WaterNoun;
%player1Speed = VectorLen(%flag.dropperVelocity);
}
else
%player1Speed = %player1.getSpeed();
%player2Speed = %player2.getSpeed();
%player2Height = %player2.getHeight();
// Might be able to abstract these loops somehow
// Passer speed
for(%i=%this.passerSpeedLevels - 1; %i>0; %i--)
if (%player1Speed >= %this.passerSpeedThreshold[%i])
break;
// Grabber speed
for(%j=%this.grabberSpeedLevels - 1; %j>0; %j--)
if (%player2Speed >= %this.grabberSpeedThreshold[%j])
break;
// Grabber height
for(%k=%this.grabberHeightLevels - 1; %k>0; %k--)
if (%player2Height >= %this.grabberHeightThreshold[%k])
break;
//echo("NOUN: passSpeed = " @ %passerSpeed @ " grabSpeed = " @ %grabberSpeed @ " grabHeight = " @ %grabberHeight);
//echo("NOUN: " SPC %i SPC %j SPC %k);
return %this.createCategoryData(%i, %j, %k);
}
// Qualifiers
new ScriptObject(Qualifier)
{
class = Qualifier;
superclass = BonusCategory;
dimensionality = 3;
horizontalFlagSpeedLevels = 2;
verticalFlagSpeedLevels = 3;
hangTimeLevels = 4;
horizontalFlagSpeedThreshold[0] = 10;
horizontalFlagSpeedThreshold[1] = 40;
verticalFlagSpeedThreshold[0] = 4;
verticalFlagSpeedThreshold[1] = 20;
verticalFlagSpeedThreshold[2] = 40;
hangTimeThreshold[0] = 500;
hangTimeThreshold[1] = 1200;
hangTimeThreshold[2] = 2500;
hangTimeThreshold[3] = 5000;
soundDelay = 0;
};
function Qualifier::evaluate(%this, %dropper, %grabber, %flag)
{
%flagSpeed = %flag.getSpeed();
if (%flag.inLiquid || %dropper $= "" || %flag.getSpeed() < 5)
return;
%dropperSpeed = VectorLen(%flag.dropperVelocity);
// Lock these down a bit
if (%grabber.getSpeed() < 13 && %dropperSpeed < 8)
return;
//if (getSimTime() - %flag.dropTime <= 500)
// return;
if (%flag.getHeight() < 7)
return;
%flagVel = %flag.getVelocity();
%horizontalFlagSpeed = VectorLen(setWord(%flagVel, 2, 0));
%verticalFlagSpeed = mAbs(getWord(%flagVel, 2));
// Test to see if the pass was good enough...it must have a sufficient
// horizontal speed, and failing that, it must either be midair or have
// a sufficient downward speed.
if (%horizontalFlagSpeed < %this.horizontalFlagSpeedThreshold[0])
if (%flag.getHeight() < 10)
if (%verticalFlagSpeed < %this.verticalFlagSpeedThreshold[0])
return "";
// Horizontal flag speed
for(%i=%this.horizontalFlagSpeedLevels - 1; %i>0; %i--)
if (%horizontalFlagSpeed >= %this.horizontalFlagSpeedThreshold[%i])
break;
// Vertical flag speed
for(%j=%this.verticalFlagSpeedLevels - 1; %j>0; %j--)
if (%verticalFlagSpeed >= %this.verticalFlagSpeedThreshold[%j])
break;
// Hangtime
%hangtime = getSimTime() - %flag.dropTime;
for(%k=%this.hangTimeLevels - 1; %k>0; %k--)
if (%hangTime >= %this.hangTimeThreshold[%k])
break;
//echo("QUALIFIER: horSpeed = " @ %horizontalFlagSpeed @ " verSpeed = " @ %verticalFlagSpeed @ " hang = " @ %hangtime);
//echo("QUALIFIER: " @ %i SPC %j SPC %k);
return %this.createCategoryData(%i, %j, %k);
}
// Descriptions
new ScriptObject(Description)
{
class = Description;
superclass = BonusCategory;
dimensionality = 3;
soundDelay = 1000;
};
function Description::evaluate(%this, %dropper, %grabber, %flag)
{
%flagVel = %flag.getVelocity();
// Return default description if the flag was dropped because the flag
// carrier died.
if (%dropper $= "" || %dropper.client.plyrDiedHoldingFlag
|| %flag.inLiquid)
return $DefaultDescription;
if (%grabber.getHeight() < 5 || %flag.getSpeed() < 5 || %flag.getHeight() < 5)
return $DefaultDescription;
// Make sure the pass was good enough to warrant a full bonus description.
// If it wasn't a high pass with decent speed, check the hangtime; if there
// wasn't lots of hangtime, don't give this bonus
if (%flag.getHeight() < 30 || %flag.getSpeed() < 15)
if (getSimTime() - %flag.dropTime <= 1000)
return $DefaultDescription;
%dropperSpeed = VectorLen(%flag.dropperVelocity);
// Don't give this bonus if they're both just standing/hovering around
if (%grabber.getSpeed() < 17 && %dropperSpeed < 12)
return $DefaultDescription;
// Determine passer's dominant direction (horizontal or vertical) at the
// time the flag was dropped.
%passerVertical = getWord(%flag.dropperVelocity, 2);
%passerHorizontal = VectorLen(setWord(%flag.dropperVelocity, 2, 0));
%passerDir = 0; // Horizontal dominance
if ( mAbs(%passerVertical) >= %passerHorizontal)
{
// Now decide if the passer was travelling mostly up or mostly down
if (%passerVertical >= 0)
%passerDir = 1; // Upward dominance
else
%passerDir = 2; // Downward dominance
}
//echo("DESCRIPTION: ver = " @ %passerVertical @ " hor = " @ %passerHorizontal);
// Based on the dominant direction, use either the xy-plane or the xz-plane
// for comparisons.
if (%passerDir == 0)
{
// Horizontal: use xy-plane
%dropperOrientationN = setWord(VectorNormalize(%flag.dropperOrientation), 2, 0);
%dropperVelocityN = setWord(VectorNormalize(%flag.dropperVelocity), 2, 0);
} else {
// Vertical: use xz-plane
%dropperOrientationN = setWord(VectorNormalize(%flag.dropperOrientation), 1, 0);
%dropperVelocityN = setWord(VectorNormalize(%flag.dropperVelocity), 1, 0);
}
// Determine passer's dominant orientation relative to velocity at the time
// the flag was dropped (forward pass, backward pass, or perpendicular pass).
%passDirectionDot = VectorDot(%dropperOrientationN, %dropperVelocityN);
%passDir = 0; // Forward pass
//echo("DESCRIPTION: passDirDot = " @ %passDirectionDot);
if (%passDirectionDot <= -0.42)
%passDir = 1; // Backward pass
else if (%passDirectionDot >= -0.29 && %passDirectionDot <= 0.29)
%passDir = 2; // Perpendicular pass
// Do the same for the flag's dominant direction.
%flagVertical = mAbs(getWord(%flagVel, 2));
%flagHorizontal = VectorLen(setWord(%flagVel, 2, 0));
%flagDir = (%flagHorizontal >= %flagVertical) ? 0 : 1;
%grabberVel = %grabber.getVelocity();
if (%flagDir == 0)
{
%flagVelocityN = setWord(VectorNormalize(%flagVel), 2, 0);
%grabberVelN = setWord(VectorNormalize(%grabberVel), 2, 0);
}
else
{
%flagVelocityN = setWord(VectorNormalize(%flagVel), 1, 0);
%grabberVelN = setWord(VectorNormalize(%grabberVel), 1, 0);
}
// Determine the flag's velocity relative to the grabber's velocity at the time
// the flag is grabbed, ie. now (into pass, with pass, perpendicular to pass).
%flagDirectionDot = VectorDot(%dropperOrientationN, %grabberVelN);
%flagDir = 0; // Default to travelling into the pass
//echo("DESCRIPTION: flagDirDot = " @ %flagDirectionDot);
if (%flagDirectionDot >= 0.7)
%flagDir = 1; // Travelling with the pass
else if (%flagDirectionDot >= -0.21 && %flagDirectionDot <= 0.21)
%flagDir = 2; // Travelling perpendicular to the pass
//echo("DESCRIPTION:"
// @ " passerDir = " @ %passerDir
// @ " passDir = " @ %passDir
// @ " flagDir = " @ %flagDir);
return %this.createCategoryData(%passerDir, %passDir, %flagDir);
}
// Prefixs
new ScriptObject(Prefix)
{
class = Prefix;
superclass = BonusCategory;
dimensionality = 1;
grabberOrientationLevels = 3;
grabberOrientationThreshold[0] = -0.1;
grabberOrientationThreshold[1] = -0.5;
grabberOrientationThreshold[2] = -0.85;
soundDelay = 0;
};
function Prefix::evaluate(%this, %dropper, %grabber, %flag)
{
// Determine if the grabber caught the flag backwards. Derive a
// relative position vector and calculate the dot product.
%flagPos = %flag.getPosition();
%grabberPos = %grabber.getPosition();
%grabberEye = %grabber.getEyeVector();
// If the flag is sliding around near the ground, only expect the grabber to
// be horizontally backwards...otherwise, he must be backwards in all dimensions.
if (%flag.getHeight() < 10 && getWord(%flag.getVelocity(), 2) < 17)
%flagPos = setWord(%flagPos, 2, getWord(%grabberPos, 2));
%relativePos = VectorNormalize(VectorSub(%flagPos, %grabberPos));
%relativeDot = VectorDot(%relativePos, %grabberEye);
//echo("PREFIX TEST: reldot = " @ %relativeDot);
// Should probably put this into a loop
if (%relativeDot <= %this.grabberOrientationThreshold[2])
%grabberDir = 2;
else if (%relativeDot <= %this.grabberOrientationThreshold[1])
%grabberDir = 1;
else if (%relativeDot <= %this.grabberOrientationThreshold[0])
%grabberDir = 0;
else
return "";
//echo("Prefix: " @ %grabberDir);
return %this.createCategoryData(%grabberDir);
}
// Weapon speed (speed of victim)
new ScriptObject(SpeedBonus)
{
class = SpeedBonus;
superclass = BonusCategory;
dimensionality = 1;
SpeedLevels = 3;
SpeedThreshold[0] = 20;
SpeedThreshold[1] = 65;
SpeedThreshold[2] = 100;
soundDelay = 0;
};
function SpeedBonus::evaluate(%this, %notUsed, %victim)
{
// A little trick to allow evaluation for either parameter
if (%victim $= "")
%victim = %notUsed;
%victimSpeed = %victim.getSpeed();
if (%victimSpeed < %this.SpeedThreshold[0])
return;
// Victim speed
for(%i=%this.SpeedLevels - 1; %i>0; %i--)
if (%victimSpeed >= %this.SpeedThreshold[%i])
break;
//echo("SB: " SPC %i SPC "speed =" SPC %victimSpeed);
return %this.createCategoryData(%i);
}
// Weapon height (height of victim)
new ScriptObject(HeightBonus)
{
class = HeightBonus;
superclass = BonusCategory;
dimensionality = 1;
heightLevels = 3;
HeightThreshold[0] = 15;
HeightThreshold[1] = 40;
HeightThreshold[2] = 85;
};
function HeightBonus::evaluate(%this, %notUsed, %victim)
{
// A little trick to allow evaluation for either parameter
if (%victim $= "")
%victim = %notUsed;
%victimHeight = %victim.getHeight();
if (%victimHeight < %this.HeightThreshold[0])
return;
// Victim height
for(%i=%this.HeightLevels - 1; %i>0; %i--)
if (%victimHeight >= %this.HeightThreshold[%i])
break;
//echo("HB: " SPC %i);
return %this.createCategoryData(%i);
}
// Weapon type
new ScriptObject(WeaponTypeBonus)
{
class = WeaponTypeBonus;
superclass = BonusCategory;
dimensionality = 1;
};
function WeaponTypeBonus::evaluate(%this, %shooter, %victim, %damageType)
{
// Determine shooter weapon type here
switch(%damageType)
{
case $DamageType::Disc: %i = 0;
case $DamageType::Grenade: %i = 1;
case $DamageType::Bullet: %i = 2;
}
//echo("WTB: " SPC %i);
return %this.createCategoryData(%i);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,464 @@
// TR2 Bonuses
// This file execs the entire bonus infrastructure, and also contains all the
// evaluate() and award() functions for bonuses.
exec("scripts/TR2BonusSounds.cs");
exec("scripts/TR2BonusCategories.cs");
exec("scripts/TR2OtherBonuses.cs");
$TR2::teamColor[1] = "<color:CCCC00>"; // Gold
$TR2::teamColor[2] = "<color:BBBBBB>"; // Silver
function initializeBonuses()
{
// Flag bonus
if (!isObject(FlagBonus))
{
new ScriptObject(FlagBonus)
{
class = FlagBonus;
superclass = Bonus;
history = FlagBonusHistory;
};
FlagBonus.addCategory(Prefix, $PrefixList);
FlagBonus.addCategory(Noun, $NounList);
FlagBonus.addCategory(Qualifier, $QualifierList);
FlagBonus.addCategory(Description, $DescriptionList);
//MissionCleanup.add(FlagBonus);
}
// Weapon kill bonus
if (!isObject(WeaponBonus))
{
new ScriptObject(WeaponBonus)
{
class = WeaponBonus;
superclass = Bonus;
instant = true;
history = "";
};
WeaponBonus.addCategory(HeightBonus, $WeaponHeightBonusList);
WeaponBonus.addCategory(SpeedBonus, $WeaponSpeedBonusList);
WeaponBonus.addCategory(WeaponTypeBonus, $WeaponTypeBonusList);
//MissionCleanup.add(WeaponBonus);
}
// Go-go Gadget Bonus
if (!isObject(G4Bonus))
{
new ScriptObject(G4Bonus)
{
class = G4Bonus;
superclass = Bonus;
history = "";
};
G4Bonus.addCategory(Noun, $NounList);
//MissionCleanup.add(G4Bonus);
}
// Midair Bonus
if (!isObject(MidairBonus))
{
new ScriptObject(MidairBonus)
{
class = MidairBonus;
superclass = Bonus;
history = "";
};
//MissionCleanup.add(MidairBonus);
}
// Collision Bonus
if (!isObject(CollisionBonus))
{
new ScriptObject(CollisionBonus)
{
class = CollisionBonus;
superclass = Bonus;
history = "";
};
//MissionCleanup.add(CollisionBonus);
}
// Creativity Bonus
if (!isObject(CreativityBonus))
{
new ScriptObject(CreativityBonus)
{
class = CreativityBonus;
superclass = Bonus;
instant = true;
lastVariance = 0;
lastVarianceLevel = 0;
varianceLevels = 4;
varianceThreshold[0] = 0;
varianceThreshold[1] = 17;
varianceThreshold[2] = 34;
varianceThreshold[3] = 51;
varianceValue[0] = 0;
varianceValue[1] = 25;
varianceValue[2] = 50;
varianceValue[3] = 75;
varianceSound[0] = "";
varianceSound[1] = Creativity1Sound;
varianceSound[2] = Creativity2Sound;
varianceSound[3] = Creativity3Sound;
history = "";
};
//MissionCleanup.add(CreativityBonus);
}
}
function Bonus::addCategory(%this, %newCategory, %data)
{
if (%this.numCategories $= "")
%this.numCategories = 0;
// A category can be used in multiple bonuses
%this.category[%this.numCategories] = %newCategory;
%this.category[%this.numCategories].data = %data;
%this.numCategories++;
}
function Bonus::evaluate(%this, %obj1, %obj2, %obj3, %obj4, %obj5)
{
// This is added to the bonus history and eventually deleted
%newBonusData = new ScriptObject()
{
class = BonusData;
};
MissionCleanup.add(%newBonusData);
%newBonusData.initialize(%this);
// Construct the bonus by iterating through categories
for (%i=0; %i<%this.numCategories; %i++)
{
%newCategoryData = %this.category[%i].evaluate(%obj1, %obj2, %obj3, %obj4);
if (%newCategoryData > 0)
{
%newBonusData.addCategoryData(%newCategoryData, %i);
// Perform audiovisual effects
%delay = %this.category[%i].soundDelay;
%this.category[%i].schedule(%delay, "performEffects", %newCategoryData, %obj2);
}
}
// Award the bonus
if (%newBonusData.getValue() != 0)
%this.award(%newBonusData, %obj1, %obj2, %obj3);
else
%newBonusData.delete();
return true;
}
////////////////////////////////////////////////////////////////////////////////
// BonusData
// This class stores an instance of a dynamically constructed bonus.
function BonusData::initialize(%this, %bonus)
{
%this.bonus = %bonus;
%this.time = GetSimTime();
%this.maxCategoryDatas = %bonus.numCategories;
for (%i=0; %i < %this.numCategoryDatas; %i++)
%this.categoryData[%i] = "";
%this.totalValue = 0;
}
function BonusData::addCategoryData(%this, %newCategoryData, %index)
{
// This little trick allows a BonusData instance to mirror its
// Bonus type...it allows a BonusData to have empty component
// slots. Empty slots are needed so that successive Bonuses "line up"
// for calculating variance. There's likely a better way to do this.
%this.categoryData[%index] = %newCategoryData;
%this.totalValue += %newCategoryData.value;
}
function BonusData::getString(%this)
{
%str = %this.categoryData[0].text;
for (%i=1; %i < %this.maxCategoryDatas; %i++)
if (%this.categoryData[%i] !$= "")
%str = %str SPC %this.categoryData[%i].text;
return %str;
}
function BonusData::getValue(%this)
{
return %this.totalValue;
}
////////////////////////////////////////////////////////////////////////////////
// Bonus history and variance
new ScriptObject(FlagBonusHistory)
{
class = FlagBonusHistory;
superclass = BonusHistory;
bonusType = FlagBonus;
numBonuses = 0;
variance = 0;
};
function BonusHistory::initialize(%this)
{
for (%i=0; %i<%this.numBonuses; %i++)
%this.bonus[%i].delete();
%this.numBonuses = 0;
%this.variance = 0;
}
function BonusHistory::add(%this, %newBonus)
{
%this.bonus[%this.numBonuses] = %newBonus;
%this.numBonuses++;
// Calculate the new variance
return %this.calculateIncrementalVariance();
}
// An incremental way of calculating the creativity within a bonus
// history as new bonuses are added (incremental approach used for efficiency)
function BonusHistory::calculateIncrementalVariance(%this)
{
if (%this.numBonuses <= 1)
return 0;
%i = %this.numBonuses - 1;
for(%j=0; %j<%this.bonus[%i].maxCategoryDatas; %j++)
{
%categoryData = %this.bonus[%i].categoryData[%j];
// Don't count empty component slots
if(%categoryData !$= "")
for(%k=0; %k<%categoryData.numParameters; %k++)
%this.variance += mAbs(%categoryData.parameter[%k] -
%this.bonus[%i-1].categoryData[%j].parameter[%k]);
}
return %this.variance;
}
// An instantaneous way of calculating the creativity within a bonus
// history (inefficient and not intended to be used; for informational
// and debugging purposes only)
function BonusHistory::calculateVariance(%this)
{
if (%this.numBonuses <= 1)
return 0;
%this.variance = 0;
for(%i=1; %i<%this.numBonuses; %i++)
for(%j=0; %j<%this.bonus[%i].maxCategoryDatas; %j++)
{
%categoryData = %this.bonus[%i].categoryData[%j];
if (%categoryData !$= "")
for(%k=0; %k<%categoryData.numParameters; %k++)
%this.variance += abs(%categoryData.parameter[%k] -
%this.bonus[%i-1].categoryData[%j].parameter[%k]);
}
return %this.variance;
}
function BonusHistory::getVariance(%this)
{
return %this.variance;
}
function BonusHistory::getRecentRecipient(%this, %index)
{
if (%index $= "")
%index = 0;
return %this.bonus[%this.numBonuses-1-%index].recipient;
}
function Bonus::award(%this, %bonusData, %player1, %player2, %action, %suffix, %extraval, %sound)
{
// Handle instant bonuses (previously handled via subclassing)
if (%this.instant)
return %this.awardInstantBonus(%bonusData, %player1, %player2, %action, %suffix, %extraval, %sound);
if (%bonusData !$= "")
%val = %bonusData.getValue();
else
%val = 0;
if (%extraval !$= "")
%val += %extraval;
if (%val < 0)
%val = 0;
// Send message to bonus display mechanism
if (%val > 0)
Game.updateCurrentBonusAmount(%val, %player1.team);
if (%bonusData !$= "")
%text = %bonusData.getString();
if (%suffix !$= "")
%text = %text SPC %suffix;
if (%player1.team != %player2.team)
%actionColor = "<color:dd0000>";
else
%actionColor = "<color:00dd00>";
%player1Color = $TR2::teamColor[%player1.team];
%player2Color = $TR2::teamColor[%player2.team];
%summary = %player1Color @ getTaggedString(%player1.client.name)
SPC %actionColor @ %action
SPC %player2Color @ getTaggedString(%player2.client.name);
messageAll('MsgTR2Event', "", %summary, %text, %val);
if (%this.history !$= "")
// Add to BonusHistory and calculate variance
%this.history.add(%bonusData);
else if (%bonusData !$= "")
// Otherwise just get rid of it
%bonusData.delete();
}
function Bonus::awardInstantBonus(%this, %bonusData, %player1, %player2, %action, %suffix, %extraVal, %sound)
{
if (%bonusData !$= "")
%val = %bonusData.getValue();
else
%val = 0;
if (%extraVal !$= "")
%val += %extraVal;
if (%val < 0)
%val = 0;
if (%player2 !$= "")
%summary = getTaggedString(%player1.client.name) SPC %action SPC
getTaggedString(%player2.client.name);
//else if (%player1 !$= "")
// %summary = getTaggedString(%player1.client.name);
// Send message to bonus display mechanism
%scoringTeam = %player1.client.team;
$teamScore[%scoringTeam] += %val;
messageAll('MsgTR2SetScore', "", %scoringTeam, $teamScore[%scoringTeam]);
if (%bonusData !$= "")
%text = %bonusData.getString() SPC %suffix;
else
%text = %suffix;
%scoringTeam = %player1.team;
%otherTeam = (%scoringTeam == 1) ? 2 : 1;
//messageAll('MsgTR2Event', "", %summary, %text, %val);
messageTeam(%scoringTeam, 'MsgTR2InstantBonus', "\c4" @ %text SPC "\c3(+" @ %val @ ")");
messageTeam(%otherTeam, 'MsgTR2InstantBonus', "\c4" @ %text SPC "\c3(+" @ %val @ ")");
messageTeam(0, 'MsgTR2InstantBonus', "\c4" @ %text SPC "\c3(+" @ %val @ ")");
if (%sound !$= "")
serverPlay2D(%sound);
if (%this.history !$= "")
// Add to BonusHistory and calculate variance
%this.history.add(%bonusData);
else if (%bonusData !$= "")
// Otherwise just get rid of it
%bonusData.delete();
}
function FlagBonus::award(%this, %bonusData, %dropper, %grabber, %flag)
{
// Hmm, should update this to use Parent::
// Calculate bonus value
%val = %bonusData.getValue();
// Sneaky workaround so that some bonuses still display even though
// they're worth nothing
if (%val < 0)
%val = 0;
if (%val >= 20)
ServerPlay2D(CrowdCheerSound);
if (!%flag.atHome && !%flag.onGoal && !%flag.dropperKilled)
{
if (%flag.dropper.team == %grabber.team)
{
%actionColor = "<color:00dd00>";
%ppoints = mCeil(%val / 2);
%rpoints = mFloor(%val / 2);
%grabber.client.score += %rpoints;
%grabber.client.receivingScore += %rpoints;
%flag.dropper.client.score += %ppoints;
%flag.dropper.client.passingScore += %ppoints;
} else {
%actionColor = "<color:dd0000>";
%grabber.client.score += %val;
%grabber.client.interceptingScore += %val;
%this.history.initialize();
// If grabber was a goalie, count this as a save
if (%grabber.client.currentRole $= Goalie)
%grabber.client.saves++;
}
if (%flag.dropper.client !$= "")
{
%dropperColor = $TR2::teamColor[%dropper.team];
%grabberColor = $TR2::teamColor[%grabber.team];
%summary = %dropperColor @ getTaggedString(%dropper.client.name)
SPC %actionColor @ "to"
SPC %grabberColor @ getTaggedString(%grabber.client.name);
}
} else {
// Handle regular flag pickups
%summary = $TR2::teamColor[%grabber.team] @ getTaggedString(%grabber.client.name);
%this.history.initialize();
}
// Add to BonusHistory and calculate variance
%bonusData.recipient = %grabber;
%this.history.add(%bonusData);
// Use variance to calculate creativity
%variance = %this.history.getVariance();
CreativityBonus.evaluate(%variance, %grabber);
// Send message to bonus display mechanism
// <color:000000>
Game.updateCurrentBonusAmount(%val, %grabber.team);
messageAll('MsgTR2Event', "", %summary, %bonusData.getString(), %val);
}
function WeaponBonus::award(%this, %bonusData, %shooter, %victim)
{
%shooter.client.fcHits++;
if (%bonusData.getValue() >= 5)
ServerPlay2D(MonsterSound);
Parent::award(%this, %bonusData, %shooter, %victim, "immobilized", "Hit \c2(" @ getTaggedString(%shooter.client.name) @ ")");
}
function G4Bonus::award(%this, %bonusData, %plAttacker, %plVictim, %damageType, %damageLoc, %val)
{
Parent::award(%this, %bonusData, %plAttacker, %plVictim, "G4'd",
"Bionic Grab", %val);
}
function CollisionBonus::award(%this, %bonusData, %plPasser, %plReceiver, %action, %desc, %val)
{
Parent::award(%this, %bonusData, %plPasser, %plReceiver, %action, %desc, %val);
}

View file

@ -0,0 +1,248 @@
////////////////////////////////////////////////////////////////////////////////
// Special DescriptionDatas
$DefaultDescription = new ScriptObject() {
text = "Grab";
value = 0;
sound = "blah.wav";
class = DescriptionData;
numParameters = 0;
};
$G4Description = new ScriptObject() {
text = "Go-go Gadget Grab";
value = 5;
sound = "blah.wav";
class = DescriptionData;
numParameters = 0;
};
// DescriptionData components
// [Passer direction, pass direction, flag direction]
$DescriptionList = new ScriptObject() {
class = DescriptionList;
};
function DescriptionList::get(%this, %a, %b, %c)
{
return $DescriptionList[%a, %b, %c];
}
////////////////////////////////////////////////////////////////////////////////
// Horizontal dominance (straight pass)
$DescriptionList[0,0,0] = new ScriptObject() {
text = "Bullet";
value = 5;
sound = Description000Sound;
class = DescriptionData;
};
$DescriptionList[0,0,1] = new ScriptObject() {
text = "Heist";
value = 7;
sound = Description001Sound;
class = DescriptionData;
};
$DescriptionList[0,0,2] = new ScriptObject() {
text = "Smack Shot";
value = 9;
sound = Description002Sound;
class = DescriptionData;
};
////////////////////////////////////////////////////////////////////////////////
// Horizontal dominance (pass back)
$DescriptionList[0,1,0] = new ScriptObject() {
text = "Jab";
value = 9;
sound = Description010Sound;
class = DescriptionData;
};
$DescriptionList[0,1,1] = new ScriptObject() {
text = "Back Breaker";
value = 11;
sound = Description011Sound;
class = DescriptionData;
};
$DescriptionList[0,1,2] = new ScriptObject() {
text = "Leet Lob";
value = 12;
sound = Description012Sound;
class = DescriptionData;
};
////////////////////////////////////////////////////////////////////////////////
// Horizontal dominance (perpendicular pass)
$DescriptionList[0,2,0] = new ScriptObject() {
text = "Peeler";
value = 22;
sound = Description020Sound;
class = DescriptionData;
};
$DescriptionList[0,2,1] = new ScriptObject() {
text = "Blender";
value = 25;
sound = Description021Sound;
class = DescriptionData;
};
$DescriptionList[0,2,2] = new ScriptObject() {
text = "Glass Smash";
value = 28;
sound = Description022Sound;
class = DescriptionData;
};
////////////////////////////////////////////////////////////////////////////////
// Upward dominance (straight pass)
$DescriptionList[1,0,0] = new ScriptObject() {
text = "Ascension";
value = 7;
sound = Description100Sound;
class = DescriptionData;
};
$DescriptionList[1,0,1] = new ScriptObject() {
text = "Elevator";
value = 9;
sound = Description101Sound;
class = DescriptionData;
};
$DescriptionList[1,0,2] = new ScriptObject() {
text = "Rainbow";
value = 7;
sound = Description102Sound;
class = DescriptionData;
};
////////////////////////////////////////////////////////////////////////////////
// Upward dominance (pass back)
$DescriptionList[1,1,0] = new ScriptObject() {
text = "Bomb";
value = 9;
sound = Description110Sound;
class = DescriptionData;
};
$DescriptionList[1,1,1] = new ScriptObject() {
text = "Deliverance";
value = 11;
sound = Description111Sound;
class = DescriptionData;
};
$DescriptionList[1,1,2] = new ScriptObject() {
text = "Crank";
value = 12;
sound = Description112Sound;
class = DescriptionData;
};
////////////////////////////////////////////////////////////////////////////////
// Upward dominance (pass perpendicular)
$DescriptionList[1,2,0] = new ScriptObject() {
text = "Fling";
value = 18;
sound = Description120Sound;
class = DescriptionData;
};
$DescriptionList[1,2,1] = new ScriptObject() {
text = "Quark";
value = 20;
sound = Description121Sound;
class = DescriptionData;
};
$DescriptionList[1,2,2] = new ScriptObject() {
text = "Juggle Toss";
value = 22;
sound = Description122Sound;
class = DescriptionData;
};
////////////////////////////////////////////////////////////////////////////////
// Downward dominance (straight pass)
$DescriptionList[2,0,0] = new ScriptObject() {
text = "Yo-yo";
value = 7;
sound = Description200Sound;
class = DescriptionData;
};
$DescriptionList[2,0,1] = new ScriptObject() {
text = "Skydive";
value = 9;
sound = Description201Sound;
class = DescriptionData;
};
$DescriptionList[2,0,2] = new ScriptObject() {
text = "Jolt";
value = 11;
sound = Description202Sound;
class = DescriptionData;
};
////////////////////////////////////////////////////////////////////////////////
// Downward dominance (pass back)
$DescriptionList[2,1,0] = new ScriptObject() {
text = "Prayer";
value = 10;
sound = Description210Sound;
class = DescriptionData;
};
$DescriptionList[2,1,1] = new ScriptObject() {
text = "Mo-yo-yo";
value = 12;
sound = Description211Sound;
class = DescriptionData;
};
$DescriptionList[2,1,2] = new ScriptObject() {
text = "Rocket";
value = 14;
sound = Description212Sound;
class = DescriptionData;
};
////////////////////////////////////////////////////////////////////////////////
// Downward dominance (pass perpendicular)
$DescriptionList[2,2,0] = new ScriptObject() {
text = "Blast";
value = 20;
sound = Description220Sound;
class = DescriptionData;
};
$DescriptionList[2,2,1] = new ScriptObject() {
text = "Deep Dish";
value = 23;
sound = Description221Sound;
class = DescriptionData;
};
$DescriptionList[2,2,2] = new ScriptObject() {
text = "Bunny Bump";
value = 25;
sound = Description222Sound;
class = DescriptionData;
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,429 @@
exec("scripts/weapons/TR2disc.cs");
exec("scripts/weapons/TR2grenadeLauncher.cs");
exec("scripts/weapons/TR2chaingun.cs");
exec("scripts/weapons/TR2grenade.cs");
exec("scripts/weapons/TR2targetingLaser.cs");
exec("scripts/packs/TR2energypack.cs");
exec("scripts/weapons/TR2shocklance.cs");
exec("scripts/weapons/TR2mortar.cs");
datablock StaticShapeData(TR2DeployedBeacon) : StaticShapeDamageProfile
{
shapeFile = "beacon.dts";
explosion = DeployablesExplosion;
maxDamage = 0.45;
disabledLevel = 0.45;
destroyedLevel = 0.45;
targetNameTag = 'beacon';
deployedObject = true;
dynamicType = $TypeMasks::SensorObjectType;
debrisShapeName = "debris_generic_small.dts";
debris = SmallShapeDebris;
};
datablock ItemData(RedNexus)
{
catagory = "Objectives";
shapefile = "nexus_effect.dts";
mass = 10;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
icon = "CMDNexusIcon";
targetTypeTag = 'Nexus';
computeCRC = false;
};
datablock ItemData(YellowNexus)
{
catagory = "Objectives";
shapefile = "nexus_effect.dts";
mass = 10;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
icon = "CMDNexusIcon";
targetTypeTag = 'Nexus';
computeCRC = false;
};
function serverCmdStartFlagThrowCount(%client, %data)
{
%client.player.flagThrowStart = getSimTime();
}
function serverCmdEndFlagThrowCount(%client, %data)
{
if(%client.player.flagThrowStart == 0)
return;
%time = getSimTime();
%result = %time - %client.player.flagThrowStart;
if( %result >= $TR2::MaxFlagChargeTime )
{
%client.player.flagThrowStart = 0;
return;
}
// throwStrength will be how many seconds the key was held
%throwStrength = (getSimTime() - %client.player.flagThrowStart) / 1000;
// trim the time to fit between 0.2 and 1.2
if(%throwStrength > 1.2)
%throwStrength = 1.2;
else if(%throwStrength < 0.2)
%throwStrength = 0.2;
%client.player.flagThrowStrength = %throwStrength;
%client.player.flagThrowStart = 0;
}
datablock AudioProfile(LauncherSound)
{
volume = 1.0;
filename = "fx/misc/launcher.wav";
description = AudioClose3d;
preload = true;
};
datablock StaticShapeData(Launcher)
{
catagory = "Objectives";
className = "Launcher";
isInvincible = true;
needsNoPower = true;
shapeFile = "stackable3m.dts";
soundEffect = LauncherSound;
scale = "1 1 0.14";
};
function Launcher::onCollision(%this, %obj, %col)
{
//echo("LAUNCHER: " @ %col);
%newVel = %col.getVelocity();
%normVel = VectorNormalize(%newVel);
%speed = %col.getSpeed();
// If the player walks on it, boost him upward
if (%speed < 30)
{
%newVel = %normVel;
%newVel = VectorScale(%newVel, 10);
%newVel = setWord(%newVel, 2, 72);
}
// If he has decent speed, give him a static boost
else if (%speed < 100)
{
%newVel = %normVel;
%newVel = VectorScale(%newVel, 100);
// Otherwise, give him a slightly scaled boost
} else
%newVel = VectorScale(%newVel, 1.05);
//%newVel = setWord(%newVel, 2, getWord(%newVel, 2) * -1);
//%col.applyImpulse(%col.getWorldBoxCenter(), VectorScale(%newVel, 200));
%col.setVelocity(%newVel);
%obj.playAudio(0, %this.soundEffect);
}
datablock TriggerData(cannonTrigger)
{
tickPeriodMS = 1000;
};
datablock TriggerData(goalZoneTrigger)
{
tickPeriodMS = 1000;
};
datablock TriggerData(defenseZoneTrigger)
{
tickPeriodMS = 1000;
};
datablock AudioProfile(CannonShotSound)
{
volume = 1.0;
filename = "fx/misc/cannonshot.wav";
description = AudioClose3d;
preload = true;
};
datablock AudioProfile(CannonStartSound)
{
volume = 1.0;
filename = "fx/misc/cannonstart.wav";
description = AudioClose3d;
preload = true;
};
function cannonTrigger::onEnterTrigger(%this, %trigger, %obj)
{
if (%obj.getState $= "Dead")
return;
%client = %obj.client;
%obj.playAudio(0, CannonStartSound);
%obj.inCannon = true;
%obj.setInvincible(true);
%client.cannonThread = %this.schedule(500, "ShootCannon", %trigger, %obj);
}
function cannonTrigger::onLeaveTrigger(%this, %trigger, %obj)
{
%client = %obj.client;
%obj.setInvincible(false);
cancel(%client.cannonThread);
}
function cannonTrigger::onTickTrigger(%this, %trigger)
{
}
function cannonTrigger::shootCannon(%this, %trigger, %obj)
{
%obj.applyImpulse(%obj.getWorldBoxCenter(), "0 0 20000");
%obj.setInvincible(false);
%obj.inCannon = false;
%newEmitter = new ParticleEmissionDummy(CannonEffect) {
position = %trigger.position;
rotation = %trigger.rotation;
scale = "1 1 1";
dataBlock = "defaultEmissionDummy";
emitter = "CannonEmitter";
velocity = "1";
};
%obj.playAudio(0, CannonShotSound);
%newEmitter.schedule(%newEmitter.emitter.lifetimeMS, "delete");
}
function goalZoneTrigger::onEnterTrigger(%this, %trigger, %obj)
{
if (!$TR2::EnableRoles || %trigger.team != %obj.team)
return;
if (!%obj.client.enableZones)
return;
Game.trySetRole(%obj, Goalie);
}
function goalZoneTrigger::onLeaveTrigger(%this, %trigger, %obj)
{
if (!$TR2::EnableRoles)
return;
if (!%obj.client.enableZones)
return;
if (!Game.trySetRole(%obj, Defense))
Game.trySetRole(%obj, Offense);
}
function defenseZoneTrigger::onEnterTrigger(%this, %trigger, %obj)
{
if (!$TR2::EnableRoles || %trigger.team != %obj.team)
return;
if (!%obj.client.enableZones)
return;
Game.trySetRole(%obj, Defense);
}
function defenseZoneTrigger::onLeaveTrigger(%this, %trigger, %obj)
{
if (!$TR2::EnableRoles)
return;
if (!%obj.client.enableZones)
return;
if (!Game.trySetRole(%obj, Offense))
error("TR2 role change error: couldn't change to Offense");
}
datablock StaticShapeData(Goal)
{
className = "Goal";
catagory = "Objectives";
shapefile = "goal_panel.dts";
isInvincible = true;
needsNoPower = true;
};
datablock StaticShapeData(GoalPost)
{
className = "GoalPost";
catagory = "Objectives";
shapefile = "goal_side.dts";
isInvincible = true;
needsNoPower = true;
};
datablock StaticShapeData(GoalCrossbar)
{
className = "GoalCrossbar";
catagory = "Objectives";
shapefile = "goal_top.dts";
isInvincible = true;
needsNoPower = true;
};
datablock StaticShapeData(GoalBack)
{
className = "GoalBack";
catagory = "Objectives";
shapefile = "goal_back.dts";
isInvincible = true;
needsNoPower = true;
};
datablock StaticShapeData(GoldGoalPost)
{
className = "GoalPost";
catagory = "Objectives";
shapefile = "gold_goal_side.dts";
isInvincible = true;
needsNoPower = true;
};
datablock StaticShapeData(GoldGoalCrossbar)
{
className = "GoalCrossbar";
catagory = "Objectives";
shapefile = "gold_goal_top.dts";
isInvincible = true;
needsNoPower = true;
};
datablock StaticShapeData(GoldGoalBack)
{
className = "GoalBack";
catagory = "Objectives";
shapefile = "gold_goal_back.dts";
isInvincible = true;
needsNoPower = true;
};
datablock StaticShapeData(GoldPole)
{
className = "GoldPole";
catagory = "Objectives";
shapefile = "golden_pole.dts";
isInvincible = true;
needsNoPower = true;
};
datablock StaticShapeData(SilverPole)
{
className = "SilverPole";
catagory = "Objectives";
shapefile = "silver_pole.dts";
isInvincible = true;
needsNoPower = true;
};
datablock StaticShapeData(Billboard1)
{
className = "Billboard";
catagory = "Misc";
shapefile = "billboard_1.dts";
isInvincible = true;
needsNoPower = true;
};
datablock StaticShapeData(Billboard2)
{
className = "Billboard";
catagory = "Misc";
shapefile = "billboard_2.dts";
isInvincible = true;
needsNoPower = true;
};
datablock StaticShapeData(Billboard3)
{
className = "Billboard";
catagory = "Misc";
shapefile = "billboard_3.dts";
isInvincible = true;
needsNoPower = true;
};
datablock StaticShapeData(Billboard4)
{
className = "Billboard";
catagory = "Misc";
shapefile = "billboard_4.dts";
isInvincible = true;
needsNoPower = true;
};
function GoalCrossbar::onCollision(%this, %obj, %col)
{
return;
if (%col.getClassName() !$= "Player")
return;
if (getWord(%col.getPosition(), 2) > getWord(%obj.getPosition(), 2))
{
// Ooo...the quick 1-2 punch to defeat a potential exploit
%this.nudgeObject(%obj, %col, 10);
%obj.schedule(100, "nudgeObject", %obj, %col, -70);
}
}
function GoalCrossbar::nudgeObject(%this, %obj, %col, %vertNudge)
{
%center = $TheFlag.originalPosition;
// Determine if the object is on the front or back part of the crossbar
%colDist = VectorDist(%col.getPosition(), %center);
%goalDist = VectorDist(%obj.getPosition(), %center);
%nudgeDir = (%goalDist > %colDist) ? 1 : -1;
// Nudge the player towards the center of the map
%nudgeVec = VectorNormalize($TheFlag.originalPosition);
%nudgeVec = VectorScale(%nudgeVec, %nudgeDir);
%nudgeVec = VectorScale(%nudgeVec, 40);
%nudgeVec = setWord(%nudgeVec, 2, %vertNudge);
%col.setVelocity(%nudgeVec);
}
datablock ForceFieldBareData(TR2defaultForceFieldBare)
{
fadeMS = 1000;
baseTranslucency = 0.80;
powerOffTranslucency = 0.0;
teamPermiable = true;
otherPermiable = true;
color = "0.0 0.55 0.99";
powerOffColor = "0.0 0.0 0.0";
targetNameTag = 'Force Field';
targetTypeTag = 'ForceField';
texture[0] = "skins/forcef1";
texture[1] = "skins/forcef2";
texture[2] = "skins/forcef3";
texture[3] = "skins/forcef4";
texture[4] = "skins/forcef5";
framesPerSec = 10;
numFrames = 5;
scrollSpeed = 15;
umapping = 1.0;
vmapping = 0.15;
};

View file

@ -0,0 +1,494 @@
datablock AudioProfile(TR2TestNounDataSound)
{
volume = 2.0;
filename = "fx/bonuses/test-NounData-wildcat.wav";
description = AudioBIGExplosion3d;
preload = true;
};
// NounData components
// [Passer speed, grabber speed, grabber height]
$NounList = new ScriptObject() {
class = NounList;
};
function NounList::get(%this, %a, %b, %c)
{
return $NounList[%a, %b, %c];
}
$WaterNoun = new ScriptObject() {
text = "Shark's";
value = 2;
sound = NounSharkSound;
emitter = "Optional";
class = NounData;
};
////////////////////////////////////////////////////////////////////////////////
// Ground passes
$NounList[0,0,0] = new ScriptObject() {
text = "Llama's";
value = -1;
sound = NounLlamaSound;
emitter = "Optional";
class = NounData;
};
$NounList[1,0,0] = new ScriptObject() {
text = "Turtle's";
value = 1;
sound = NounTurtleSound;
emitter = "Optional";
class = NounData;
};
$NounList[2,0,0] = new ScriptObject() {
text = "Snake's";
value = 2;
sound = NounSnakeSound;
class = NounData;
};
$NounList[3,0,0] = new ScriptObject() {
text = "Iguana's";
value = 3;
sound = NounIguanaSound;
class = NounData;
};
$NounList[0,1,0] = new ScriptObject() {
text = "Puppy's";
value = 2;
sound = NounPuppySound;
class = NounData;
};
$NounList[1,1,0] = new ScriptObject() {
text = "Dog's";
value = 3;
sound = NounDogSound;
class = NounData;
};
$NounList[2,1,0] = new ScriptObject() {
text = "Coyote's";
value = 4;
sound = NounCoyoteSound;
class = NounData;
};
$NounList[3,1,0] = new ScriptObject() {
text = "Wolf's";
value = 4;
sound = NounWolfSound;
class = NounData;
};
$NounList[0,2,0] = new ScriptObject() {
text = "Donkey's";
value = 2;
sound = NounDonkeySound;
class = NounData;
};
$NounList[1,2,0] = new ScriptObject() {
text = "Cow's";
value = 3;
sound = NounCowSound;
class = NounData;
};
$NounList[2,2,0] = new ScriptObject() {
text = "Zebra's";
value = 3;
sound = NounZebraSound;
class = NounData;
};
$NounList[3,2,0] = new ScriptObject() {
text = "Horse's";
value = 4;
sound = NounHorseSound;
class = NounData;
};
$NounList[0,3,0] = new ScriptObject() {
text = "Tiger's";
value = 3;
sound = NounTigerSound;
class = NounData;
};
$NounList[1,3,0] = new ScriptObject() {
text = "Jaguar's";
value = 4;
sound = NounJaguarSound;
class = NounData;
};
$NounList[2,3,0] = new ScriptObject() {
text = "Cougar's";
value = 5;
sound = NounCougarSound;
class = NounData;
};
$NounList[3,3,0] = new ScriptObject() {
text = "Cheetah's";
value = 6;
sound = NounCheetahSound;
class = NounData;
};
///////////////////////////////////////////////////////////////////////////////
// Low passes
$NounList[0,0,1] = new ScriptObject() {
text = "Helicopter's";
value = 2;
sound = NounHelicopterSound;
emitter = "Optional";
class = NounData;
};
$NounList[1,0,1] = new ScriptObject() {
text = "Grasshopper's";
value = 3;
sound = NounGrasshopperSound;
emitter = "Optional";
class = NounData;
};
$NounList[2,0,1] = new ScriptObject() {
text = "Crow's";
value = 3;
sound = NounCrowSound;
class = NounData;
};
$NounList[3,0,1] = new ScriptObject() {
text = "Bee's";
value = 4;
sound = NounBeeSound;
class = NounData;
};
$NounList[0,1,1] = new ScriptObject() {
text = "Dragonfly's";
value = 3;
sound = NounDragonflySound;
class = NounData;
};
$NounList[1,1,1] = new ScriptObject() {
text = "Mosquito's";
value = 4;
sound = NounMosquitoSound;
class = NounData;
};
$NounList[2,1,1] = new ScriptObject() {
text = "Fly's";
value = 4;
sound = NounFlySound;
class = NounData;
};
$NounList[3,1,1] = new ScriptObject() {
text = "Parakeet's";
value = 5;
sound = NounParakeetSound;
class = NounData;
};
$NounList[0,2,1] = new ScriptObject() {
text = "Budgie's";
value = 3;
sound = NounBudgieSound;
class = NounData;
};
$NounList[1,2,1] = new ScriptObject() {
text = "Ostrich's";
value = 4;
sound = NounOstrichSound;
class = NounData;
};
$NounList[2,2,1] = new ScriptObject() {
text = "Wasp's";
value = 4;
sound = NounWaspSound;
class = NounData;
};
$NounList[3,2,1] = new ScriptObject() {
text = "Hornet's";
value = 5;
sound = NounHornetSound;
class = NounData;
};
$NounList[0,3,1] = new ScriptObject() {
text = "Bat's";
value = 4;
sound = NounBatSound;
class = NounData;
};
$NounList[1,3,1] = new ScriptObject() {
text = "Chickadee's";
value = 5;
sound = NounChickadeeSound;
class = NounData;
};
$NounList[2,3,1] = new ScriptObject() {
text = "Warnipple's";
value = 10;
sound = NounWarnippleSound;
class = NounData;
};
$NounList[3,3,1] = new ScriptObject() {
text = "Special's";
value = 12;
sound = NounSpecial1Sound;
class = NounData;
};
////////////////////////////////////////////////////////////////////////////////
// Medium-high passes
$NounList[0,0,2] = new ScriptObject() {
text = "Captain's";
value = 4;
sound = NounCaptainSound;
emitter = "Optional";
class = NounData;
};
$NounList[1,0,2] = new ScriptObject() {
text = "Major's";
value = 5;
sound = NounMajorSound;
emitter = "Optional";
class = NounData;
};
$NounList[2,0,2] = new ScriptObject() {
text = "Colonel's";
value = 6;
sound = NounColonelSound;
class = NounData;
};
$NounList[3,0,2] = new ScriptObject() {
text = "General's";
value = 7;
sound = NounGeneralSound;
class = NounData;
};
$NounList[0,1,2] = new ScriptObject() {
text = "Hurricane's";
value = 5;
sound = NounHurricaneSound;
class = NounData;
};
$NounList[1,1,2] = new ScriptObject() {
text = "Tornado's";
value = 6;
sound = NounHurricaneSound;
class = NounData;
};
$NounList[2,1,2] = new ScriptObject() {
text = "Dove's";
value = 6;
sound = NounDoveSound;
class = NounData;
};
$NounList[3,1,2] = new ScriptObject() {
text = "Flamingo's";
value = 7;
sound = NounFlamingoSound;
class = NounData;
};
$NounList[0,2,2] = new ScriptObject() {
text = "Goldfinch's";
value = 6;
sound = NounGoldfinchSound;
class = NounData;
};
$NounList[1,2,2] = new ScriptObject() {
text = "Owl's";
value = 6;
sound = NounOwlSound;
class = NounData;
};
$NounList[2,2,2] = new ScriptObject() {
text = "Pelican's";
value = 7;
sound = NounPelicanSound;
class = NounData;
};
$NounList[3,2,2] = new ScriptObject() {
text = "Jet's";
value = 8;
sound = NounJetSound;
class = NounData;
};
$NounList[0,3,2] = new ScriptObject() {
text = "Bluejay's";
value = 7;
sound = NounBluejaySound;
class = NounData;
};
$NounList[1,3,2] = new ScriptObject() {
text = "Swallow's";
value = 7;
sound = NounSwallowSound;
class = NounData;
};
$NounList[2,3,2] = new ScriptObject() {
text = "Joop's";
value = 14;
sound = NounSpecial2Sound;
class = NounData;
};
$NounList[3,3,2] = new ScriptObject() {
text = "Bluenose's";
value = 16;
sound = NounSpecial3Sound;
class = NounData;
};
///////////////////////////////////////////////////////////////////////////////
// High passes
$NounList[0,0,3] = new ScriptObject() {
text = "Astronaut's";
value = 8;
sound = NounAstronautSound;
emitter = "Optional";
class = NounData;
};
$NounList[1,0,3] = new ScriptObject() {
text = "Cloud's";
value = 9;
sound = NounCloudSound;
emitter = "Optional";
class = NounData;
};
$NounList[2,0,3] = new ScriptObject() {
text = "Atmosphere's";
value = 10;
sound = NounAtmosphereSound;
class = NounData;
};
$NounList[3,0,3] = new ScriptObject() {
text = "Moon's";
value = 10;
sound = NounMoonSound;
class = NounData;
};
$NounList[0,1,3] = new ScriptObject() {
text = "Ozone's";
value = 9;
sound = NounOzoneSound;
class = NounData;
};
$NounList[1,1,3] = new ScriptObject() {
text = "Balloon's";
value = 10;
sound = NounBalloonSound;
class = NounData;
};
$NounList[2,1,3] = new ScriptObject() {
text = "Blimp's";
value = 11;
sound = NounBlimpSound;
class = NounData;
};
$NounList[3,1,3] = new ScriptObject() {
text = "Zeppellin's";
value = 12;
sound = NounZeppellinSound;
class = NounData;
};
$NounList[0,2,3] = new ScriptObject() {
text = "Condor's";
value = 11;
sound = NounCondorSound;
class = NounData;
};
$NounList[1,2,3] = new ScriptObject() {
text = "Eagle's";
value = 12;
sound = NounBirdOfPreySound;
class = NounData;
};
$NounList[2,2,3] = new ScriptObject() {
text = "Hawk's";
value = 13;
sound = NounBirdOfPreySound;
class = NounData;
};
$NounList[3,2,3] = new ScriptObject() {
text = "Orlando's";
value = 18;
sound = NounSpecial1Sound;
class = NounData;
};
$NounList[0,3,3] = new ScriptObject() {
text = "Falcon's";
value = 12;
sound = NounBirdOfPreySound;
class = NounData;
};
$NounList[1,3,3] = new ScriptObject() {
text = "Jack's";
value = 16;
sound = NounSpecial2Sound;
class = NounData;
};
$NounList[2,3,3] = new ScriptObject() {
text = "Daunt's";
value = 20;
sound = NounSpecial3Sound;
class = NounData;
};
$NounList[3,3,3] = new ScriptObject() {
text = "Natural's";
value = 22;
sound = NounSpecial1Sound;
class = NounData;
};

View file

@ -0,0 +1,639 @@
// updated ObserverQueue
// Create queue container...
if( !isObject("ObserverQueue") )
{
new SimGroup("ObserverQueue");
//ObserverQueue.setPersistent(1); // whats this do..?
}
function validateQueue()
{
if( !$TR2::SpecLock && !$Host::TournamentMode )
{
%active = GetActiveCount();
%count = 12 - %active;
for( %i = 0; %i < %count && ObserverQueue.getCount() > 0; %i++ )
{
%cl = getClientFromQueue();
if( isObject(%cl) )
{
Game.assignClientTeam(%cl, $MatchStarted);
Game.spawnPlayer(%cl, $MatchStarted);
reindexQueue();
}
}
}
}
function getActiveCount()
{
%count = 0;
for( %i = 0; %i < ClientGroup.getCount(); %i++)
{
%cl = ClientGroup.getObject(%i);
if( %cl.team > 0 )
%count++;
}
return %count;
}
function addToQueue(%client)
{
if( %client.team > 0 )
return 0;
if( !isObject(%client) )
return 0;
%unique = 1;
%count = ObserverQueue.getCount();
for( %i = 0; %i < %count; %i++ )
{
%node = ObserverQueue.getObject(%i);
if( %node.id == %client )
{
%unique = 0;
}
}
reindexQueue();
if( %unique == 1 )
{
%node = new ScriptObject()
{
id = %client.getId();
name = %client.nameBase;
};
ObserverQueue.add(%node);
ObserverQueue.pushToBack(%node);
}
%client.allowedToJoinTeam = 1;
reindexQueue();
messageQueue();
return %unique; // 0 = client already added to queue, 1 = client successfully added
}
function removeFromQueue(%client)
{
// if( !isObject(%client) )
// return 0;
// we shouldn't have duplicates in the queue, but why take a chance..
%idx = 0;
%count = ObserverQueue.getCount();
for( %i = 0; %i < %count; %i++ )
{
%node = ObserverQueue.getObject(%i);
if( %node.id == %client.getId() )
{
ObserverQueue.pushToBack(%node);
%node.delete();
break;
}
}
reindexQueue();
messageQueue();
// schedule(100, 0, "reindexQueue");
// schedule(101, 0, "messageQueue");
return %idx; // 0 if client not found to remove
}
function messageQueue()
{
%total = reindexQueue();
%count = ObserverQueue.getCount();
for( %i = 0; %i < %count; %i++ )
{
%cl = ObserverQueue.getObject(%i).id;
if( !%cl.specOnly )
{
if( %cl.queueSlot == 1 )
messageClient(%cl, 'MsgTR2QueuePos', '\c0You are currently \c1NEXT\c0 of \c1%2\c0 in the Observer Queue.~wfx/misc/bounty_objrem2.wav', %cl.queueSlot, %total);
else
messageClient(%cl, 'MsgTR2QueuePos', '\c0You are currently \c1%1\c0 of \c1%2\c0 in the Observer Queue.', %cl.queueSlot, %total);
}
}
}
function messageQueueClient(%client)
{
if( %client.team != 0 )
{
messageClient(%client, 'MsgNotObserver', '\c0You are not currently in observer mode.~wfx/powered/station_denied.wav');
return;
}
if( %client.specOnly )
{
messageClient(%client, 'MsgSpecOnly', '\c0You are currently in individual spectator only mode.~wfx/powered/station_denied.wav');
return;
}
%total = reindexQueue();
%pos = %client.queueSlot;
if( %pos $= "" )
return;
if( %pos == 1 )
messageClient(%client, 'MsgTR2QueuePos', '\c0You are currently \c1NEXT\c0 of \c1%2\c0 in the Observer Queue.!~wfx/misc/bounty_objrem2.wav', %pos, %total);
else
messageClient(%client, 'MsgTR2QueuePos', '\c0You are currently \c1%1\c0 of \c1%2\c0 in the Observer Queue.', %pos, %total);
}
function reindexQueue()
{
// reassigns client 'slots' in the queue
// returns the current number of assigned 'slots'
// only people who are actively in the queue (not spec locked) are counted.
%slot = 0;
//%count = ObserverQueue.getCount();
for( %i = 0; %i < ObserverQueue.getCount(); %i++ )
{
%node = ObserverQueue.getObject(%i);
%client = %node.id;
if( !isObject(%client) )
{
error("Client " @ %client @ " does not exist!! Removing from queue.");
if( isObject(%node) )
{
ObserverQueue.pushToBack(%node);
%node.delete();
}
}
else
{
if( %node.id.team > 0 )
{
ObserverQueue.pushToBack(%node);
%node.delete();
}
else if( !%client.specOnly )
{
%slot++;
%client.queueSlot = %slot;
}
else
{
%client.queueSlot = "";
}
}
}
return %slot;
}
function getClientFromQueue()
{
reindexQueue();
%count = ObserverQueue.getCount();
%client = -1;
for( %i = 0; %i < %count; %i++ )
{
%cl = ObserverQueue.getObject(%i).id;
if( %cl.queueSlot == 1 )
{
%client = %cl;
break;
}
}
return %client;
}
function TR2Game::forceObserver(%game, %client, %reason)
{
//make sure we have a valid client...
if (%client <= 0 || %client.team == 0)
return;
// TR2
// First set to outer role (just to be safe)
%game.assignOuterMostRole(%client);
// Then release client's role
%game.releaseRole(%client);
// Get rid of the corpse after the force
%client.forceRespawn = true;
%client.inSpawnBuilding = true;
// first kill this player
if(%client.player)
%client.player.scriptKill(0);
// TR2: Fix observer timeouts; for some reason %client.player is already 0
// in that case, so scriptKill() won't get called
if (%client.playerToDelete !$= "")
{
%client.enableZones = false;
%client.playerToDelete.delete();
}
if( %client.respawnTimer )
cancel(%client.respawnTimer);
%client.respawnTimer = "";
// remove them from the team rank array
%game.removeFromTeamRankArray(%client);
// place them in observer mode
%client.lastObserverSpawn = -1;
%client.observerStartTime = getSimTime();
%adminForce = 0;
switch$ ( %reason )
{
case "playerChoose":
messageClient(%client, 'MsgClientJoinTeam', '\c2You have become an observer.', %client.name, %game.getTeamName(0), %client, 0 );
echo(%client.nameBase@" (cl "@%client@") entered observer mode");
%client.lastTeam = %client.team;
%client.specOnly = true; // this guy wants to sit out...
case "AdminForce":
messageClient(%client, 'MsgClientJoinTeam', '\c2You have been forced into observer mode by the admin.', %client.name, %game.getTeamName(0), %client, 0 );
echo(%client.nameBase@" (cl "@%client@") was forced into observer mode by admin");
%client.lastTeam = %client.team;
%adminForce = 1;
if($Host::TournamentMode)
{
if(!$matchStarted)
{
if(%client.camera.Mode $= "pickingTeam")
{
commandToClient( %client, 'processPickTeam');
clearBottomPrint( %client );
}
else
{
clearCenterPrint(%client);
%client.notReady = true;
}
}
}
case "spawnTimeout":
messageClient(%client, 'MsgClientJoinTeam', '\c2You have been placed in observer mode due to delay in respawning.', %client.name, %game.getTeamName(0), %client, 0 );
echo(%client.nameBase@" (cl "@%client@") was placed in observer mode due to spawn delay");
// save the team the player was on - only if this was a delay in respawning
%client.lastTeam = %client.team;
%client.specOnly = true; // why force an afk player back into the game?
case "specLockEnabled":
messageClient(%client, 'MsgClientJoinTeam', '\c2Spectator lock is enabled. You were automatically forced to observer.', %client.name, %game.getTeamName(0), %client, 0 );
%client.lastTeam = %client.team;
case "teamsMaxed":
messageClient(%client, 'MsgClientJoinTeam', '\c2Teams are at capacity. You were automatically forced to observer.', %client.name, %game.getTeamName(0), %client, 0 );
%client.lastTeam = %client.team;
case "gameForce":
messageClient(%client, 'MsgClientJoinTeam', '\c2You have become an observer.', %client.name, %game.getTeamName(0), %client, 0 );
%client.lastTeam = %client.team;
}
// switch client to team 0 (observer)
%client.team = 0;
%client.player.team = 0;
setTargetSensorGroup( %client.target, %client.team );
%client.setSensorGroup( %client.team );
// set their control to the obs. cam
%client.setControlObject( %client.camera );
commandToClient(%client, 'setHudMode', 'Observer');
// display the hud
//displayObserverHud(%client, 0);
updateObserverFlyHud(%client);
// message everyone about this event
if( !%adminForce )
messageAllExcept(%client, -1, 'MsgClientJoinTeam', '\c2%1 has become an observer.', %client.name, %game.getTeamName(0), %client, 0 );
else
messageAllExcept(%client, -1, 'MsgClientJoinTeam', '\c2The admin has forced %1 to become an observer.', %client.name, %game.getTeamName(0), %client, 0 );
updateCanListenState( %client );
// call the onEvent for this game type
%game.onClientEnterObserverMode(%client); //Bounty uses this to remove this client from others' hit lists
if( !%client.tr2SpecMode )
{
%client.camera.getDataBlock().setMode( %client.camera, "observerFly" );
}
else
{
if( $TheFlag.carrier.client !$= "" )
%game.observeObject(%client, $TheFlag.carrier.client, 1);
else
%game.observeObject(%client, $TheFlag, 2);
}
// Queuing...
if( %reason !$= "specLockEnabled" && %reason !$= "teamsMaxed" && !$Host::TournamentMode )
{
%vacant = ((6 * 2) - getActiveCount());
%nextCl = getClientFromQueue();
if( isObject(%nextCl) && %vacant > 0 && %nextCl.queueSlot <= %vacant )
{
%game.assignClientTeam(%nextCl, $MatchStarted );
%game.spawnPlayer(%nextCl, $MatchStarted);
}
}
addToQueue(%client);
%client.allowedToJoinTeam = 1;
}
function TR2Game::clientJoinTeam( %game, %client, %team, %fromObs )
{
//%game.assignClientTeam(%client, $MatchStarted);
if( (12 - getActiveCount()) > 0 || $Host::TournamentMode )
{
%client.allowedToJoinTeam = 1;
//first, remove the client from the team rank array
//the player will be added to the new team array as soon as he respawns...
%game.removeFromTeamRankArray(%client);
%pl = %client.player;
if(isObject(%pl))
{
if(%pl.isMounted())
%pl.getDataBlock().doDismount(%pl);
%pl.scriptKill(0);
}
// reset the client's targets and tasks only
clientResetTargets(%client, true);
// give this client a new handle to disassociate ownership of deployed objects
if( %team $= "" && (%team > 0 && %team <= %game.numTeams))
{
if( %client.team == 1 )
%client.team = 2;
else
%client.team = 1;
}
else
%client.team = %team;
// Set the client's skin:
if (!%client.isAIControlled())
setTargetSkin( %client.target, %game.getTeamSkin(%client.team) );
setTargetSensorGroup( %client.target, %client.team );
%client.setSensorGroup( %client.team );
// Spawn the player:
%game.spawnPlayer(%client, $MatchStarted);
if(%fromObs $= "" || !%fromObs)
{
messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 switched to team %2.', %client.name, %game.getTeamName(%client.team), %client, %client.team );
messageClient( %client, 'MsgClientJoinTeam', '\c1You switched to team %2.', $client.name, %game.getTeamName(%client.team), %client, %client.team );
}
else
{
messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined team %2.', %client.name, %game.getTeamName(%client.team), %client, %team );
messageClient( %client, 'MsgClientJoinTeam', '\c1You joined team %2.', $client.name, %game.getTeamName(%client.team), %client, %client.team );
}
updateCanListenState( %client );
// MES - switch objective hud lines when client switches teams
messageClient(%client, 'MsgCheckTeamLines', "", %client.team);
logEcho(%client.nameBase@" (cl "@%client@") switched to team "@%client.team);
removeFromQueue(%client);
}
else
{
//error("Forced to observer: " @%client.nameBase @ " via JoinTeam");
%game.forceObserver(%client, "gameForce");
}
}
// if( %client.allowedToJoinTeam == 1 )
// {
// DefaultGame::clientJoinTeam( %game, %client, %team, %respawn );
// removeFromQueue(%client);
// }
// else
// {
// %game.forceObserver(%client, "gameForce");
// }
function TR2Game::assignClientTeam(%game, %client, %respawn )
{
if( %client.team > 0 )
return;
%size[0] = 0;
%size[1] = 0;
%size[2] = 0;
%leastTeam = 0;
for( %i = 0; %i < ClientGroup.getCount(); %i++ )
{
%cl = ClientGroup.getObject(%i);
if( %cl != %client )
%size[%cl.team]++;
}
%playing = %size[1] + %size[2];
if( %playing < (6 << 1) ) // HEH HEH
{
%game.removeFromTeamRankArray(%client);
%leastTeam = (%size[1] <= %size[2]) ? 1 : 2;
removeFromQueue(%client);
%client.lastTeam = %client.team;
%client.team = %leastTeam;
// Assign the team skin:
if ( %client.isAIControlled() )
{
if ( %leastTeam & 1 )
{
%client.skin = addTaggedString( "basebot" );
setTargetSkin( %client.target, 'basebot' );
}
else
{
%client.skin = addTaggedString( "basebbot" );
setTargetSkin( %client.target, 'basebbot' );
}
}
else
setTargetSkin( %client.target, %game.getTeamSkin(%client.team) );
messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined %2.', %client.name, %game.getTeamName(%client.team), %client, %client.team );
messageClient( %client, 'MsgClientJoinTeam', '\c1You joined the %2 team.', %client.name, %game.getTeamName(%client.team), %client, %client.team );
updateCanListenState( %client );
clearBottomPrint(%client); // clear out the observer hud...
echo(%client.nameBase@" (cl "@%client@") joined team "@%client.team);
//error("Assigned: " @%client.nameBase @ " to team: " @ %team @ " via AssignTeam");
}
else
{
//error("Forced to observer: " @%client.nameBase @ " via AssignTeam");
%game.forceObserver(%client, "teamsMaxed");
}
// hes been checked for team join ability..
%client.allowedToJoinTeam = 1;
}
function TR2Game::ObserverOnTrigger(%game, %data, %obj, %trigger, %state)
{
//trigger types: 0:fire 1:altTrigger 2:jump 3:jet 4:throw
if (!$missionRunning)
{
return false;
}
%client = %obj.getControllingClient();
if (!isObject(%client))
{
return false;
}
// Knockdowns
// Moved up since players in the game should have a little priority over observers
// save a little execution time and effort :
if (%obj.mode $= "playerDeath")
{
if(!%client.waitRespawn && getSimTime() > %client.suicideRespawnTime)
{
commandToClient(%client, 'setHudMode', 'Standard');
if (%client.playerToDelete !$= "")
{
%client.enableZones = false;
%client.playerToDelete.delete();
}
// Use current flymode rotation
%transform = %client.camera.getTransform();
%oldTrans = %client.plyrTransformAtDeath;
%oldPos = getWord(%oldTrans, 0) SPC getWord(%oldTrans, 1) SPC getWord(%oldTrans, 2);
%newRot = getWord(%transform, 3) SPC getWord(%transform, 4) SPC getWord(%transform, 5) SPC getWord(%transform, 6);
%client.plyrTransformAtDeath = %oldPos SPC %newRot;
Game.spawnPlayer( %client, true );
%client.camera.setFlyMode();
%client.setControlObject(%client.player);
}
return false;
}
// Observer zoom
if( %obj.mode $= "followFlag" || %obj.mode $= "observerFollow" )
{
if( %trigger == 3 )
{
%client.obsZoomLevel++;
if (%client.obsZoomLevel >= $TR2::numObsZoomLevels)
%client.obsZoomLevel = 0;
// Move the camera
%game.observeObject(%client, %client.observeTarget, %client.observeType);
//%pos = %client.camera.getPosition();
//%rot = %client.camera
return false;
}
else
return false;
}
if( %obj.mode $= "observerFly" )
{
// unfortunately, it seems that sometimes the "observer speed up" thing doesn't always happen...
if (%trigger == 0)
{
clearBottomPrint(%client);
return false;
}
//press JET
else if (%trigger == 3)
{
%markerObj = Game.pickObserverSpawn(%client, true);
%transform = %markerObj.getTransform();
%obj.setTransform(%transform);
%obj.setFlyMode();
clearBottomPrint(%client);
return false;
}
//press JUMP
else if (%trigger == 2)
{
clearBottomPrint(%client);
return false;
}
}
if( %obj.mode $= "pre-game" )
{
return true; // use default action
}
if( %obj.mode $= "justJoined" )
{
if( !$TR2::SpecLock && !$Host::TournamentMode )
{
if( %client.team <= 0 )
{
if( getActiveCount() < ($TR2::DefaultTeamSize * 2) )
{
%game.assignClientTeam(%client, 0);
%game.spawnPlayer(%client, 0);
}
else
{
%game.forceObserver(%client, "teamsMaxed");
}
}
else if( %client.team >= 1 )
{
%game.spawnPlayer(%client, 0);
}
if( isObject(%client.player) ) // player was successfully created...
{
if(!$MatchStarted && !$CountdownStarted)
%client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player );
else if(!$MatchStarted && $CountdownStarted)
%client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player );
else
{
%client.camera.setFlyMode();
commandToClient(%client, 'setHudMode', 'Standard');
%client.setControlObject( %client.player );
}
}
}
else
{
// kind of weak, but tourney mode *is* a form of spec lock :/
%game.forceObserver(%client, "specLockEnabled");
}
return false;
}
// Queue
if( %trigger == 0 )
{
if( %obj.mode !$= "playerDeath" )
{
return false;
}
}
return true;
}

View file

@ -0,0 +1,234 @@
// Simple bonuses
$TR2::midairLevel[0] = 10;
$TR2::midairLevel[1] = 25;
function FlagBonus::evaluate(%this, %passer, %receiver, %flag)
{
if ($TheFlag.specialPass $= "" && !%flag.onGoal)
Parent::evaluate(%this, %passer, %receiver, %flag);
$TheFlag.specialPass = "";
}
//function WeaponBonus::evaluate(%this, %shooter, %victim, %damageType)
//{
//}
////////////////////////////////////////////////////////////////////////////////
// Damage bonus
function G4Bonus::evaluate(%this, %plAttacker, %plVictim, %flag, %damageType, %damageLoc)
{
if (%plVictim !$= %flag.carrier && %plAttacker !$= %flag.carrier)
return;
if (%plAttacker $= "" || %plVictim $= "" || %flag.carrier $= "")
return;
// Lock this down a bit
if (%plVictim.getSpeed() < 3)
return;
%clAttacker = %plAttacker.client;
%clVictim = %plVictim.client;
%victimHeight = %plVictim.getHeight();
if (%clVictim != %clAttacker &&
%damageType == $DamageType::Disc &&
%victimHeight > 13)
{
if (%plVictim.isAboveSomething(25))
return;
// MA effect
%newEmitter = new ParticleEmissionDummy(MidairDiscEffect) {
position = %plVictim.getTransform();
rotation = "1 0 0 0";
scale = "0.1 0.1 0.1";
dataBlock = "defaultEmissionDummy";
emitter = "MidairDiscEmitter";
velocity = "1";
};
%newEmitter.schedule(%newEmitter.emitter.lifetimeMS, "delete");
if (%plVictim == %flag.carrier)
{
//Game.playerDroppedFlag(%flag.carrier);
$TheFlag.specialPass = "MA";
%plVictim.throwObject(%plVictim.holdingFlag);
if (%plVictim.team == %plAttacker.team)
{
// G4
TR2Flag::onCollision("",%flag,%plAttacker);
//%plVictim.forceRespawn = true;
%plAttacker.gogoKill = true;
%plVictim.setDamageFlash(0.75);
%plVictim.applyDamage(1);
//%plVictim.blowup();
//Game.onClientKilled(%clVictim, 0, $DamageType::G4);
serverPlay2D(GadgetSound);
} else {
// Crazy flags here
%numFlags = mFloor(%victimHeight / 7);
if (%numFlags > 40)
%numFlags = 40;
Game.emitFlags(%plVictim.getWorldBoxCenter(), mFloor(%victimHeight / 5), %plVictim);
if (%numFlags >= 30)
ServerPlay2D(MA3Sound);
else if (%numFlags >= 13)
ServerPlay2D(MA2Sound);
else if (%numFlags >= 3)
ServerPlay2D(MA1Sound);
messageAll('msgTR2MA', '%1 MA\'s %2.', %clAttacker.name, %clVictim.name);
return;
}
}
// Otherwise, Rabid Rabbit
else {
ServerPlay3D(MonsterSound, %plAttacker.getPosition());
%plVictim.setDamageFlash(0.75);
%plVictim.applyDamage(1);
}
}
else return;
Parent::evaluate(%this, %plAttacker, %plVictim, "", %damageType, %damageLoc, 5);
}
function MABonus::evaluate(%this, %clAttacker, %clVictim, %damageType, %damageLoc)
{
// MA detection
%plAttacker = %clAttacker.Player;
%plVictim = %clVictim.Player;
%victimHeight = %plVictim.getHeight();
if (%clVictim != %clAttacker &&
%damageType == $DamageType::Disc &&
%victimHeight > 10)
{
// MA effect
%newEmitter = new ParticleEmissionDummy(MidairDiscEffect) {
position = %player.getTransform();
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "defaultEmissionDummy";
emitter = "MidairDiscEmitter";
velocity = "1";
};
%newEmitter.schedule(%newEmitter.emitter.lifetimeMS, "delete");
if (%plVictim == $TheFlag.carrier && %plVictim.team != %plAttacker.team)
{
Game.playerDroppedFlag($TheFlag.carrier);
// Crazy flags here
game.emitFlags(%plVictim, 10);
}
else if (%plAttacker == $TheFlag.carrier)
{
// Rabid Rabbit here
%plVictim.setDamageFlash(0.75);
%plVictim.applyDamage(1);
%plVictim.blowup();
}
}
}
function CollisionBonus::evaluate(%this, %obj, %col)
{
%client = %obj.client;
if ($TheFlag.carrier.client == %client)
{
// Kidney Thief Steal
if (%client.team != %col.team)
{
if (getSimTime() - $TheFlag.lastKTS >= 3 * 1000)
{
$TheFlag.specialPass = "KTS";
Game.playerDroppedFlag($TheFlag.carrier);
TR2Flag::onCollision("",$TheFlag,%col);
$TheFlag.lastKTS = getSimTime();
%action = "ROBBED";
%desc = "Kidney Thief Steal";
%val = 5;
serverPlay3D(EvilLaughSound, %col.getPosition());
} else return;
// Mario Grab
} else {
%carrierPos = %obj.getPosition();
%collidedPos = %col.getPosition();
%carrierz = getWord(%carrierPos, 2);
%collidez = getWord(%collidedPos, 2);
// Inverse
//if (%carrierz > %collidez && %carrierz - %collidez > 2.5)
//{
//%flagVel = $TheFlag.carrier.getVelocity();
//Game.playerDroppedFlag($TheFlag.carrier);
//%flagx = firstWord(%flagVel) * 4;
//%flagy = getWord(%flagVel, 1) * 4;
//%flagz = getWord(%flagVel, 2);
//%flagz = %flagz + 1500;
//$TheFlag.applyImpulse($TheFlag.getPosition(), %flagx SPC %flagy SPC %flagz);
//} else
// Standard
if (%carrierz < %collidez && %collidez - %carrierz > 2.8
&& getSimTime() - $TheFlag.lastMario >= 4 * 1000)
{
$TheFlag.specialPass = "Mario";
$TheFlag.lastMario = getSimTime();
Game.playerDroppedFlag($TheFlag.carrier);
TR2Flag::onCollision("",$TheFlag,%col);
%action = "TROUNCED";
%desc = "Plumber Butt";
%val = 4;
serverPlay2D(MarioSound);
} else return;
}
}
else return;
%this.award("", %col, %obj, %action, %desc, %val);
}
function CreativityBonus::evaluate(%this, %variance, %player)
{
if (%variance < %this.lastVariance)
{
%this.lastVariance = 0;
%this.lastVarianceLevel = 0;
return;
}
if (%variance == %this.lastVariance)
return;
%this.lastVariance = %variance;
for(%i=%this.varianceLevels - 1; %i>0; %i--)
if (%variance >= %this.varianceThreshold[%i])
break;
if (%i < %this.lastVarianceLevel)
{
%this.lastVarianceLevel = 0;
return;
}
if (%i == %this.lastVarianceLevel)
return;
%this.lastVarianceLevel = %i;
$teamScoreCreativity[%player.team] += %this.varianceValue[%i];
// Ugly..hmm
%this.schedule(1500, "award", "", %player, "", "",
"Level" SPC %i SPC "Creativity Bonus", %this.varianceValue[%i], %this.varianceSound[%i]);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,202 @@
datablock ParticleData(TR2FlagParticle)
{
dragCoefficient = 0.0;
gravityCoefficient = 0.3;
inheritedVelFactor = 0.8;
constantAcceleration = 0.3;
lifetimeMS = 5000;
lifetimeVarianceMS = 50;
textureName = "special/Smoke/bigSmoke"; // special/Smoke/bigSmoke special/droplet
colors[0] = "0.5 0.25 0 1";
colors[1] = "0 0.25 0.5 1";
sizes[0] = 0.80;
sizes[1] = 0.60;
};
datablock ParticleEmitterData(TR2FlagEmitter)
{
ejectionPeriodMS = 75;
periodVarianceMS = 0;
ejectionVelocity = 2;
velocityVariance = 1;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 5;
phiReferenceVel = 0;
phiVariance = 360;
lifetimeMS = 5000;
overrideAdvances = false;
particles = "TR2FlagParticle";
};
datablock ParticleData(GridjumpParticle)
{
dragCoefficient = 0;
gravityCoefficient = -0.017094;
inheritedVelFactor = 0.0176125;
constantAcceleration = -1.1129;
lifetimeMS = 258;
lifetimeVarianceMS = 60;
useInvAlpha = 1;
spinRandomMin = -200;
spinRandomMax = 200;
textureName = "special/Smoke/smoke_001";
colors[0] = "0.000000 0.877165 0.000000 1.000000";
colors[1] = "0.181102 0.981102 0.181102 1.000000";
colors[2] = "0.000000 0.800000 0.000000 0.000000";
colors[3] = "1.000000 1.000000 1.000000 1.000000";
sizes[0] = 0.991882;
sizes[1] = 2.99091;
sizes[2] = 4.98993;
sizes[3] = 1;
times[0] = 0;
times[1] = 0.2;
times[2] = 1;
times[3] = 2;
};
datablock ParticleEmitterData(GridjumpEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 100.25;
velocityVariance = 0.25;
ejectionOffset = 0;
thetaMin = 0;
thetaMax = 180;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = 0;
orientParticles= 0;
orientToNormal = 0;
orientOnVelocity = 1;
particles = "GridjumpParticle";
lifetimeMS = 1000;
};
datablock ParticleData(MidairDiscParticle)
{
dragCoefficient = 0;
gravityCoefficient = -0.017094;
inheritedVelFactor = 0.0176125;
constantAcceleration = -1.1129;
lifetimeMS = 2258;
lifetimeVarianceMS = 604;
useInvAlpha = 1;
spinRandomMin = -200;
spinRandomMax = 200;
textureName = "special/Smoke/smoke_001";
colors[0] = "0.000000 0.077165 0.700000 1.000000";
colors[1] = "0.181102 0.181102 0.781102 1.000000";
colors[2] = "0.000000 0.000000 0.600000 0.000000";
colors[3] = "1.000000 1.000000 1.000000 1.000000";
sizes[0] = 0.991882;
sizes[1] = 2.99091;
sizes[2] = 4.98993;
sizes[3] = 1;
times[0] = 0;
times[1] = 0.2;
times[2] = 1;
times[3] = 2;
};
datablock ParticleEmitterData(MidairDiscEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 10.25;
velocityVariance = 0.25;
ejectionOffset = 0;
thetaMin = 0;
thetaMax = 180;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = 0;
orientParticles= 0;
orientToNormal = 0;
orientOnVelocity = 1;
lifetimeMS = 1000;
particles = "MidairDiscParticle";
};
datablock ParticleData(CannonParticle)
{
dragCoefficient = 0;
gravityCoefficient = -0.017094;
inheritedVelFactor = 0.0176125;
constantAcceleration = -1.1129;
lifetimeMS = 258;
lifetimeVarianceMS = 60;
useInvAlpha = 1;
spinRandomMin = -200;
spinRandomMax = 200;
textureName = "special/Smoke/smoke_001";
colors[0] = "0.000000 0.0 0.000000 1.000000";
colors[1] = "0.181102 0.181102 0.181102 1.000000";
colors[2] = "0.8000000 0.800000 0.800000 0.000000";
colors[3] = "1.000000 1.000000 1.000000 1.000000";
sizes[0] = 2.991882;
sizes[1] = 4.99091;
sizes[2] = 6.98993;
sizes[3] = 1;
times[0] = 0;
times[1] = 0.2;
times[2] = 1;
times[3] = 2;
};
datablock ParticleEmitterData(CannonEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 20.25;
velocityVariance = 0.5;
ejectionOffset = 0;
thetaMin = 0;
thetaMax = 180;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = 0;
orientParticles= 0;
orientToNormal = 0;
orientOnVelocity = 1;
particles = "CannonParticle";
lifetimeMS = 2500;
};
datablock ParticleData( RoleChangeParticle )
{
dragCoefficient = 0;
gravityCoefficient = -1.0;
inheritedVelFactor = 0.2;
constantAcceleration = -1.4;
lifetimeMS = 300;
lifetimeVarianceMS = 0;
textureName = "special/droplet";
colors[0] = "0.7 0.8 1.0 1.0";
colors[1] = "0.7 0.8 1.0 0.5";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 10.5;
sizes[1] = 30.2;
sizes[2] = 30.2;
times[0] = 0.0;
times[1] = 0.15;
times[2] = 0.2;
};
datablock ParticleEmitterData( RoleChangeEmitter )
{
ejectionPeriodMS = 4;
periodVarianceMS = 0;
ejectionVelocity = 10;
velocityVariance = 0.0;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 50;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 800;
particles = "RoleChangeParticle";
};

View file

@ -0,0 +1,7 @@
// Penalties
new ScriptObject(TeamkillPenalty)
{
};

View file

@ -0,0 +1,653 @@
// Flag physics
$TR2_UpwardFlagThrust = 23;
$TR2_ForwardFlagThrust = 42.3;
$TR2_GeneralFlagBoost = 22.4;
$TR2_PlayerVelocityAddedToFlagThrust = 32;
$TR2_FlagFriction = 0.7;//0.7;//1.3;
$TR2_FlagMass = 30;
$TR2_FlagDensity = 0.25;
$TR2_FlagElasticity = 0.1;//0.2;
// This controls the range of possible strengths
$TR2_FlagThrowScale = 3.0;
$TR2::Gravity = -43;//-41;
// Misc
$TR2_BeaconStopScale = 0.7;
// Grid
$TR2_MinimumGridBoost = 80;
$TR2_GridVelocityScale = 1.15;
$TR2_MaximumGridSpeed = 310;
// Player camera
$TR2_player3rdPersonDistance = 7;
$TR2_playerObserveParameters = "1.0 18.0 18.0";
// Player physics (light armor only)
$TR2_playerNoFrictionOnSki = true;
$TR2_playerMass = 130;
$TR2_playerDrag = 0.003;//0.2; //
$TR2_playerMaxdrag = 0.005;//0.4;
$TR2_playerDensity = 1.2;//10;
$TR2_playerRechargeRate = 0.251;//0.256;
$TR2_playerJetForce = 7030;//4000;//26.21 * 90;
$TR2_playerUnderwaterJetForce = 5800;//26.21 * 90 * 1.75;
$TR2_playerUnderwaterVertJetFactor = 1.0;//1.5;
$TR2_playerJetEnergyDrain = 0.81;//0.8;
$TR2_playerUnderwaterJetEnergyDrain = 0.5;//0.6;
$TR2_playerMinJetEnergy = 5;//1;
$TR2_playerMaxJetHorizontalPercentage = 0.8;//0.8;
$TR2_playerRunForce = 12500;//12400;//4500;//55.20 * 90;
$TR2_playerMaxForwardSpeed = 25;//16;//15;
$TR2_playerMaxBackwardSpeed = 23;//16;//13;
$TR2_playerMaxSideSpeed = 23;//16;//13;
$TR2_playerMaxUnderwaterForwardSpeed = 16;
$TR2_playerMaxUnderwaterBackwardSpeed = 15;
$TR2_playerMaxUnderwaterSideSpeed = 15;
$TR2_playerJumpForce = 1800;//8.3 * 90;
$TR2_playerRecoverDelay = 0;//9;
$TR2_playerRecoverRunForceScale = 2;//1.2;
$TR2_playerMinImpactSpeed = 75;//45;
$TR2_playerSpeedDamageScale = 0.001;//0.004;
$TR2_playerBoundingBox = "2.4 2.1 4.6";//"3 3 4.0";//"1.2 1.2 2.3";
$TR2_playerRunSurfaceAngle = 90;//70;
$TR2_playerJumpSurfaceAngle = 90;//80;
$TR2_playerMinJumpSpeed = 600;
$TR2_playerMaxJumpSpeed = 700;//30;
$TR2_playerHorizMaxSpeed = 10000;
$TR2_playerHorizResistSpeed = 10000;//200;//445;//33 * 1.15;
$TR2_playerHorizResistFactor = 0.0;//0.15;//0.35;
$TR2_playerMaxJetForwardSpeed = 50;//57;//42;//30 * 1.5;
$TR2_playerUpMaxSpeed = 10000;//80;
$TR2_playerUpResistSpeed = 38;//200;//150;//25;
$TR2_playerUpResistFactor = 0.05;//0.15;//0.55;//0.30;
// Unused
$TR2_ForwardHandGrenadeThrust = 0;
$StaticTSObjects[$NumStaticTSObjects] = "PlayerArmors TR2LightMaleHumanArmorImage TR2light_male.dts";
$NumStaticTSObjects++;
$StaticTSObjects[$NumStaticTSObjects] = "PlayerArmors TR2LightFemaleHumanArmorImage TR2light_female.dts";
$NumStaticTSObjects++;
exec("scripts/TR2light_male.cs");
exec("scripts/TR2light_female.cs");
exec("scripts/TR2medium_male.cs");
exec("scripts/TR2medium_female.cs");
exec("scripts/TR2heavy_male.cs");
datablock AudioProfile(TR2SkiAllSoftSound)
{
filename = "fx/armor/TR2ski_soft.wav";
description = AudioClose3d;
preload = true;
};
datablock PlayerData(TR2LightMaleHumanArmor) : LightPlayerDamageProfile
{
// KP: Use this to turn ski friction on and off
noFrictionOnSki = $TR2_playerNoFrictionOnSki;
emap = true;
//offset = $TR2_playerOffset;
className = Armor;
shapeFile = "TR2light_male.dts";
cameraMaxDist = $TR2_player3rdPersonDistance;
computeCRC = false;
canObserve = true;
cmdCategory = "Clients";
cmdIcon = CMDPlayerIcon;
cmdMiniIconName = "commander/MiniIcons/TR2com_player_grey";
//targetTypeTag = 'Flag';
hudImageNameFriendly[0] = "gui/TR2hud_playertriangle";
hudImageNameEnemy[0] = "gui/TR2hud_playertriangle_enemy";
hudRenderModulated[0] = true;
hudRenderAlways[0] = true;
hudRenderCenter[0] = false;
hudImageNameFriendly[1] = "commander/MiniIcons/TR2com_flag_grey";
hudImageNameEnemy[1] = "commander/MiniIcons/TR2com_flag_grey";
hudRenderModulated[1] = true;
hudRenderAlways[1] = true;
hudRenderCenter[1] = true;
hudRenderDistance[1] = true;
hudImageNameFriendly[2] = "commander/MiniIcons/TR2com_flag_grey";
hudImageNameEnemy[2] = "commander/MiniIcons/TR2com_flag_grey";
hudRenderModulated[2] = true;
hudRenderAlways[2] = true;
hudRenderCenter[2] = true;
hudRenderDistance[2] = true;
cameraDefaultFov = 97.0;
cameraMinFov = 5.0;
cameraMaxFov = 120.0;
debrisShapeName = "debris_player.dts";
debris = playerDebris;
aiAvoidThis = true;
minLookAngle = -1.5;//-1.5;
maxLookAngle = 1.5;//1.5;
maxFreelookAngle = 3.5;//3.0;
// KP: Mass affects all forces...very important
mass = $TR2_playerMass;//90;
// KP: Drag affects movement through liquids
drag = $TR2_playerDrag;
maxdrag = $TR2_playerMaxDrag;
// KP: Density affects water buoyancy...water skiing is back!
density = $TR2_playerDensity;//10;
maxDamage = 0.62;
maxEnergy = 60;//60;
repairRate = 0.0033;
energyPerDamagePoint = 70.0; // shield energy required to block one point of damage
// KP: How fast your jets will charge
rechargeRate = $TR2_playerRechargeRate;
// KP: The force of your jets (critically important)
jetForce = $TR2_playerJetForce;
underwaterJetForce = $TR2_playerUnderwaterJetForce;
underwaterVertJetFactor = $TR2_playerUnderwaterVertJetFactor;
// KP: How quickly your energy drains
jetEnergyDrain = $TR2_playerJetEnergyDrain;
underwaterJetEnergyDrain = $TR2_playerUnderwaterJetEnergyDrain;
// KP: Minimum amount of energy you need in order to jet
minJetEnergy = $TR2_playerminJetEnergy;
// KP: Percentage of jets applied to strafing
maxJetHorizontalPercentage = $TR2_playerMaxJetHorizontalPercentage;
// KP: This seems to affect the speed at which you can come to a stop, but if
// it's too low, you slide all around the terrain.
runForce = $TR2_playerRunForce;
runEnergyDrain = 0;
minRunEnergy = 0;
// KP: These are your walking speeds
maxForwardSpeed = $TR2_playerMaxForwardSpeed;
maxBackwardSpeed = $TR2_playerMaxBackwardSpeed;
maxSideSpeed = $TR2_playerMaxSideSpeed;
maxUnderwaterForwardSpeed = $TR2_playerMaxUnderwaterForwardSpeed;
maxUnderwaterBackwardSpeed = $TR2_playerMaxUnderwaterBackwardSpeed;
maxUnderwaterSideSpeed = $TR2_playerMaxUnderwaterSideSpeed;
// KP: Your jump force
jumpForce = $TR2_playerJumpForce;
jumpEnergyDrain = 0;
minJumpEnergy = 0;
jumpDelay = 0;
// KP: Not 100% sure what this is...looking at Torque, it seems to affect
// your momentum when you land heavily on terrain
recoverDelay = $TR2_playerRecoverDelay;
recoverRunForceScale = $TR2_playerRecoverRunForceScale;
// KP: This controls the damage that you take on impact (most important for
// inserting another degree of skill into skiing)
minImpactSpeed = $TR2_playerMinImpactSpeed;
speedDamageScale = $TR2_playerSpeedDamageScale;
jetSound = ArmorJetSound;
wetJetSound = ArmorJetSound;
jetEmitter = HumanArmorJetEmitter;
jetEffect = HumanArmorJetEffect;
boundingBox = $TR2_playerBoundingBox;
pickupRadius = 1.5;//0.75;
// damage location details
boxNormalHeadPercentage = 0.83;
boxNormalTorsoPercentage = 0.49;
boxHeadLeftPercentage = 0;
boxHeadRightPercentage = 1;
boxHeadBackPercentage = 0;
boxHeadFrontPercentage = 1;
//Foot Prints
decalData = LightMaleFootprint;
decalOffset = 0.25;
footPuffEmitter = LightPuffEmitter;
footPuffNumParts = 15;
footPuffRadius = 0.25;
dustEmitter = LiftoffDustEmitter;
splash = PlayerSplash;
splashVelocity = 4.0;
splashAngle = 67.0;
splashFreqMod = 300.0;
splashVelEpsilon = 0.60;
bubbleEmitTime = 0.4;
splashEmitter[0] = PlayerFoamDropletsEmitter;
splashEmitter[1] = PlayerFoamEmitter;
splashEmitter[2] = PlayerBubbleEmitter;
mediumSplashSoundVelocity = 10.0;
hardSplashSoundVelocity = 20.0;
exitSplashSoundVelocity = 5.0;
// Controls over slope of runnable/jumpable surfaces
// KP: This seems to control your "stickiness" to surfaces. Can affect the
// fluidity of skiing when friction is enabled. Best used in
// conjunction with runForce.
runSurfaceAngle = $TR2_playerRunSurfaceAngle;
jumpSurfaceAngle = $TR2_playerJumpSurfaceAngle;
// KP: These don't seem to have an obvious effect, but might be useful
minJumpSpeed = $TR2_playerMinJumpSpeed;
maxJumpSpeed = $TR2_playerMaxJumpSpeed;
// KP: Max speed settings including resistance. High resistSpeed seems to
// result in faster movement. resistFactor determines the magnitude of
// the resistance.
horizMaxSpeed = $TR2_playerHorizMaxSpeed;
horizResistSpeed = $TR2_playerHorizResistSpeed;
horizResistFactor = $TR2_playerHorizResistFactor;
// KP: Limits how much your jets can affect your forward speed...very useful
// for balancing how much your speed can be increased by jets as opposed to
// pure skiing
maxJetForwardSpeed = $TR2_playerMaxJetForwardSpeed;
// KP: Same as horizontal counterparts. Should be set so that players can't
// go too high. Must be careful not to make it feel too "floaty"
upMaxSpeed = $TR2_playerUpMaxSpeed;
upResistSpeed = $TR2_playerUpResistSpeed;
upResistFactor = $TR2_playerUpResistFactor;
// heat inc'ers and dec'ers
heatDecayPerSec = 1.0 / 4.0; // takes 4 seconds to clear heat sig.
heatIncreasePerSec = 1.0 / 3.0; // takes 3.0 seconds of constant jet to get full heat sig.
footstepSplashHeight = 0.35;
//Footstep Sounds
LFootSoftSound = LFootLightSoftSound;
RFootSoftSound = RFootLightSoftSound;
LFootHardSound = LFootLightHardSound;
RFootHardSound = RFootLightHardSound;
LFootMetalSound = LFootLightMetalSound;
RFootMetalSound = RFootLightMetalSound;
LFootSnowSound = LFootLightSnowSound;
RFootSnowSound = RFootLightSnowSound;
LFootShallowSound = LFootLightShallowSplashSound;
RFootShallowSound = RFootLightShallowSplashSound;
LFootWadingSound = LFootLightWadingSound;
RFootWadingSound = RFootLightWadingSound;
LFootUnderwaterSound = LFootLightUnderwaterSound;
RFootUnderwaterSound = RFootLightUnderwaterSound;
LFootBubblesSound = LFootLightBubblesSound;
RFootBubblesSound = RFootLightBubblesSound;
movingBubblesSound = ArmorMoveBubblesSound;
waterBreathSound = WaterBreathMaleSound;
impactSoftSound = ImpactLightSoftSound;
impactHardSound = ImpactLightHardSound;
impactMetalSound = ImpactLightMetalSound;
impactSnowSound = ImpactLightSnowSound;
skiSoftSound = "";//TR2SkiAllSoftSound;
skiHardSound = "";//SkiAllHardSound;
skiMetalSound = SkiAllMetalSound;
skiSnowSound = SkiAllSnowSound;
impactWaterEasy = ImpactLightWaterEasySound;
impactWaterMedium = ImpactLightWaterMediumSound;
impactWaterHard = ImpactLightWaterHardSound;
// KP: Removed the annoying shaking upon impact
groundImpactMinSpeed = 30.0;//10.0;
groundImpactShakeFreq = "4.0 4.0 4.0";
groundImpactShakeAmp = "0.1 0.1 0.1";//"1.0 1.0 1.0";
groundImpactShakeDuration = 0.05;//0.8;
groundImpactShakeFalloff = 2.0;//10.0;
exitingWater = ExitingWaterLightSound;
maxWeapons = 3; // Max number of different weapons the player can have
maxGrenades = 1; // Max number of different grenades the player can have
maxMines = 1; // Max number of different mines the player can have
// Inventory restrictions
max[RepairKit] = 1;
max[Mine] = 3;
max[Grenade] = 5;
max[Blaster] = 1;
max[Plasma] = 1;
max[PlasmaAmmo] = 20;
max[Disc] = 1;
max[DiscAmmo] = 15;
max[SniperRifle] = 1;
max[GrenadeLauncher] = 1;
max[GrenadeLauncherAmmo]= 10;
max[Mortar] = 0;
max[MortarAmmo] = 0;
max[MissileLauncher] = 0;
max[MissileLauncherAmmo]= 0;
max[Chaingun] = 1;
max[ChaingunAmmo] = 100;
max[RepairGun] = 1;
max[CloakingPack] = 1;
max[SensorJammerPack] = 1;
max[EnergyPack] = 1;
max[RepairPack] = 1;
max[ShieldPack] = 1;
max[AmmoPack] = 1;
max[SatchelCharge] = 1;
max[MortarBarrelPack] = 0;
max[MissileBarrelPack] = 0;
max[AABarrelPack] = 0;
max[PlasmaBarrelPack] = 0;
max[ELFBarrelPack] = 0;
max[InventoryDeployable]= 0;
max[MotionSensorDeployable] = 1;
max[PulseSensorDeployable] = 1;
max[TurretOutdoorDeployable] = 0;
max[TurretIndoorDeployable] = 0;
max[FlashGrenade] = 5;
max[ConcussionGrenade] = 5;
max[FlareGrenade] = 5;
max[TargetingLaser] = 1;
max[ELFGun] = 1;
max[ShockLance] = 1;
max[CameraGrenade] = 2;
max[Beacon] = 3;
// TR2
max[TR2Disc] = 1;
max[TR2GrenadeLauncher] = 1;
max[TR2Chaingun] = 1;
max[TR2GoldTargetingLaser] = 1;
max[TR2SilverTargetingLaser] = 1;
max[TR2Grenade] = 5;
max[TR2DiscAmmo] = 15;
max[TR2GrenadeLauncherAmmo] = 10;
max[TR2ChaingunAmmo] = 100;
max[TR2EnergyPack] = 1;
observeParameters = "1.0 12.0 12.0";//$TR2_playerObserveParameters;//"1.0 32.0 32.0";//"0.5 4.5 4.5";
shieldEffectScale = "0.7 0.7 1.0";
};
datablock PlayerData(TR2LightFemaleHumanArmor) : TR2LightMaleHumanArmor
{
shapeFile = "TR2light_female.dts";
waterBreathSound = WaterBreathFemaleSound;
jetEffect = HumanMediumArmorJetEffect;
};
datablock ItemData(TR2DummyArmor)// : TR2LightMaleHumanArmor
{
shapeFile = "statue_lmale.dts";
};
datablock PlayerData(TR2MediumMaleHumanArmor) : TR2LightMaleHumanArmor
{
emap = true;
className = Armor;
shapeFile = "TR2medium_male.dts";
maxDamage = 1.55;//1.1;
jetSound = ArmorJetSound;
wetJetSound = ArmorWetJetSound;
jetEmitter = HumanArmorJetEmitter;
jetEffect = HumanMediumArmorJetEffect;
boundingBox = "2.9 2.3 5.2";
boxHeadFrontPercentage = 1;
//Foot Prints
decalData = MediumMaleFootprint;
decalOffset = 0.35;
footPuffEmitter = LightPuffEmitter;
footPuffNumParts = 15;
footPuffRadius = 0.25;
dustEmitter = LiftoffDustEmitter;
splash = PlayerSplash;
splashVelocity = 4.0;
splashAngle = 67.0;
splashFreqMod = 300.0;
splashVelEpsilon = 0.60;
bubbleEmitTime = 0.4;
splashEmitter[0] = PlayerFoamDropletsEmitter;
splashEmitter[1] = PlayerFoamEmitter;
splashEmitter[2] = PlayerBubbleEmitter;
mediumSplashSoundVelocity = 10.0;
hardSplashSoundVelocity = 20.0;
exitSplashSoundVelocity = 5.0;
footstepSplashHeight = 0.35;
//Footstep Sounds
LFootSoftSound = LFootMediumSoftSound;
RFootSoftSound = RFootMediumSoftSound;
LFootHardSound = LFootMediumHardSound;
RFootHardSound = RFootMediumHardSound;
LFootMetalSound = LFootMediumMetalSound;
RFootMetalSound = RFootMediumMetalSound;
LFootSnowSound = LFootMediumSnowSound;
RFootSnowSound = RFootMediumSnowSound;
LFootShallowSound = LFootMediumShallowSplashSound;
RFootShallowSound = RFootMediumShallowSplashSound;
LFootWadingSound = LFootMediumWadingSound;
RFootWadingSound = RFootMediumWadingSound;
LFootUnderwaterSound = LFootMediumUnderwaterSound;
RFootUnderwaterSound = RFootMediumUnderwaterSound;
LFootBubblesSound = LFootMediumBubblesSound;
RFootBubblesSound = RFootMediumBubblesSound;
movingBubblesSound = ArmorMoveBubblesSound;
waterBreathSound = WaterBreathMaleSound;
impactSoftSound = ImpactMediumSoftSound;
impactHardSound = ImpactMediumHardSound;
impactMetalSound = ImpactMediumMetalSound;
impactSnowSound = ImpactMediumSnowSound;
impactWaterEasy = ImpactMediumWaterEasySound;
impactWaterMedium = ImpactMediumWaterMediumSound;
impactWaterHard = ImpactMediumWaterHardSound;
exitingWater = ExitingWaterMediumSound;
maxWeapons = 4; // Max number of different weapons the player can have
maxGrenades = 1; // Max number of different grenades the player can have
maxMines = 1; // Max number of different mines the player can have
// Inventory restrictions
max[RepairKit] = 1;
max[Mine] = 3;
max[Grenade] = 6;
max[Blaster] = 1;
max[Plasma] = 1;
max[PlasmaAmmo] = 40;
max[Disc] = 1;
max[DiscAmmo] = 15;
max[SniperRifle] = 0;
max[GrenadeLauncher] = 1;
max[GrenadeLauncherAmmo]= 12;
max[Mortar] = 0;
max[MortarAmmo] = 0;
max[MissileLauncher] = 1;
max[MissileLauncherAmmo]= 4;
max[Chaingun] = 1;
max[ChaingunAmmo] = 150;
max[RepairGun] = 1;
max[CloakingPack] = 0;
max[SensorJammerPack] = 1;
max[EnergyPack] = 1;
max[RepairPack] = 1;
max[ShieldPack] = 1;
max[AmmoPack] = 1;
max[SatchelCharge] = 1;
max[MortarBarrelPack] = 1;
max[MissileBarrelPack] = 1;
max[AABarrelPack] = 1;
max[PlasmaBarrelPack] = 1;
max[ELFBarrelPack] = 1;
max[InventoryDeployable]= 1;
max[MotionSensorDeployable] = 1;
max[PulseSensorDeployable] = 1;
max[TurretOutdoorDeployable] = 1;
max[TurretIndoorDeployable] = 1;
max[FlashGrenade] = 6;
max[ConcussionGrenade] = 6;
max[FlareGrenade] = 6;
max[TargetingLaser] = 1;
max[ELFGun] = 1;
max[ShockLance] = 1;
max[CameraGrenade] = 3;
max[Beacon] = 3;
max[TR2Shocklance] = 1;
shieldEffectScale = "0.7 0.7 1.0";
};
datablock PlayerData(TR2MediumFemaleHumanArmor) : TR2MediumMaleHumanArmor
{
shapeFile = "TR2medium_female.dts";
};
datablock PlayerData(TR2HeavyMaleHumanArmor) : TR2LightMaleHumanArmor
{
emap = true;
mass = 245;
jetForce = 14000;
jumpForce = 3500;
runForce = 22000;
className = Armor;
shapeFile = "TR2heavy_male.dts";
cameraMaxDist = 14;
boundingBox = "6.2 6.2 9.0";
maxDamage = 6.0;//1.32;
// Give lots of energy to goalies
maxEnergy = 120;//60;
maxJetHorizontalPercentage = 1.0;
//Foot Prints
decalData = HeavyMaleFootprint;
decalOffset = 0.4;
footPuffEmitter = LightPuffEmitter;
footPuffNumParts = 15;
footPuffRadius = 0.25;
dustEmitter = LiftoffDustEmitter;
//Footstep Sounds
LFootSoftSound = LFootHeavySoftSound;
RFootSoftSound = RFootHeavySoftSound;
LFootHardSound = LFootHeavyHardSound;
RFootHardSound = RFootHeavyHardSound;
LFootMetalSound = LFootHeavyMetalSound;
RFootMetalSound = RFootHeavyMetalSound;
LFootSnowSound = LFootHeavySnowSound;
RFootSnowSound = RFootHeavySnowSound;
LFootShallowSound = LFootHeavyShallowSplashSound;
RFootShallowSound = RFootHeavyShallowSplashSound;
LFootWadingSound = LFootHeavyWadingSound;
RFootWadingSound = RFootHeavyWadingSound;
LFootUnderwaterSound = LFootHeavyUnderwaterSound;
RFootUnderwaterSound = RFootHeavyUnderwaterSound;
LFootBubblesSound = LFootHeavyBubblesSound;
RFootBubblesSound = RFootHeavyBubblesSound;
movingBubblesSound = ArmorMoveBubblesSound;
waterBreathSound = WaterBreathMaleSound;
impactSoftSound = ImpactHeavySoftSound;
impactHardSound = ImpactHeavyHardSound;
impactMetalSound = ImpactHeavyMetalSound;
impactSnowSound = ImpactHeavySnowSound;
impactWaterEasy = ImpactHeavyWaterEasySound;
impactWaterMedium = ImpactHeavyWaterMediumSound;
impactWaterHard = ImpactHeavyWaterHardSound;
maxWeapons = 5; // Max number of different weapons the player can have
maxGrenades = 1; // Max number of different grenades the player can have
maxMines = 1; // Max number of different mines the player can have
// Inventory restrictions
max[RepairKit] = 1;
max[Mine] = 3;
max[Grenade] = 8;
max[Blaster] = 1;
max[Plasma] = 1;
max[PlasmaAmmo] = 50;
max[Disc] = 1;
max[DiscAmmo] = 15;
max[SniperRifle] = 0;
max[GrenadeLauncher] = 1;
max[GrenadeLauncherAmmo]= 15;
max[Mortar] = 1;
max[MortarAmmo] = 10;
max[MissileLauncher] = 1;
max[MissileLauncherAmmo]= 8;
max[Chaingun] = 1;
max[ChaingunAmmo] = 200;
max[RepairGun] = 1;
max[CloakingPack] = 0;
max[SensorJammerPack] = 1;
max[EnergyPack] = 1;
max[RepairPack] = 1;
max[ShieldPack] = 1;
max[AmmoPack] = 1;
max[SatchelCharge] = 1;
max[MortarBarrelPack] = 1;
max[MissileBarrelPack] = 1;
max[AABarrelPack] = 1;
max[PlasmaBarrelPack] = 1;
max[ELFBarrelPack] = 1;
max[InventoryDeployable]= 1;
max[MotionSensorDeployable] = 1;
max[PulseSensorDeployable] = 1;
max[TurretOutdoorDeployable] = 1;
max[TurretIndoorDeployable] = 1;
max[FlashGrenade] = 8;
max[ConcussionGrenade] = 8;
max[FlareGrenade] = 8;
max[TargetingLaser] = 1;
max[ELFGun] = 1;
max[ShockLance] = 1;
max[CameraGrenade] = 3;
max[Beacon] = 3;
max[TR2Mortar] = 1;
max[TR2MortarAmmo] = 99;
max[TR2Shocklance] = 1;
shieldEffectScale = "0.7 0.7 1.0";
};
datablock PlayerData(TR2HeavyFemaleHumanArmor) : TR2HeavyMaleHumanArmor
{
className = Armor;
};

View file

@ -0,0 +1,44 @@
//datablock AudioProfile(TR2TestPrefixSound)
//{
// filename = "fx/bonuses/test-Prefix-brilliance.wav";
// description = AudioBIGExplosion3d;
// preload = true;
//};
$PrefixList = new ScriptObject() {
class = PrefixList;
};
function PrefixList::get(%this, %a)
{
return $PrefixList[%a];
}
// Somewhat backwards
$PrefixList[0] = new ScriptObject() {
text = "Angled";
value = 2;
sound = "blah.wav";
emitter = "Optional";
class = PrefixData;
};
// Nearly backwards
$PrefixList[1] = new ScriptObject() {
text = "Twisted";
value = 5;
sound = "blah.wav";
emitter = "Optional";
class = PrefixData;
};
// Completely backwards
$PrefixList[2] = new ScriptObject() {
text = "Deranged";
value = 8;
sound = "blah.wav";
emitter = "Optional";
class = PrefixData;
};

View file

@ -0,0 +1,221 @@
//datablock AudioProfile(TR2TestQualifierDataSound)
//{
// filename = "fx/bonuses/test-QualifierData-brilliance.wav";
// description = AudioBIGExplosion3d;
// preload = true;
//};
// QualifierData components
// [Horizontal flag speed, Vertical flag speed, hangtime]
$QualifierList = new ScriptObject() {
class = QualifierList;
};
function QualifierList::get(%this, %a, %b, %c)
{
return $QualifierList[%a, %b, %c];
}
////////////////////////////////////////////////////////////////////////////////
// No/low hangtime
$QualifierList[0,0,0] = "";
//new ScriptObject() {
// text = "Dull";
// value = 5;
// sound = "blah.wav";
// emitter = "Optional";
// class = QualifierData;
//};
$QualifierList[1,0,0] = new ScriptObject() {
text = "Sharp";
value = 1;
sound = Qualifier100Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[0,1,0] = new ScriptObject() {
text = "Spitting";
value = 1;
sound = Qualifier010Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[1,1,0] = new ScriptObject() {
text = "Whipped";
value = 2;
sound = Qualifier110Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[0,2,0] = new ScriptObject() {
text = "Popping";
value = 2;
sound = Qualifier020Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[1,2,0] = new ScriptObject() {
text = "Bursting";
value = 3;
sound = Qualifier120Sound;
emitter = "Optional";
class = QualifierData;
};
////////////////////////////////////////////////////////////////////////////////
// Medium hangtime
$QualifierList[0,0,1] = new ScriptObject() {
text = "Modest";
value = 3;
sound = Qualifier001Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[1,0,1] = new ScriptObject() {
text = "Ripped";
value = 4;
sound = Qualifier101Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[0,1,1] = new ScriptObject() {
text = "Shining";
value = 4;
sound = Qualifier011Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[1,1,1] = new ScriptObject() {
text = "Slick";
value = 5;
sound = Qualifier111Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[0,2,1] = new ScriptObject() {
text = "Sprinkling";
value = 5;
sound = Qualifier021Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[1,2,1] = new ScriptObject() {
text = "Brilliant";
value = 6;
sound = Qualifier121Sound;
emitter = "Optional";
class = QualifierData;
};
////////////////////////////////////////////////////////////////////////////////
// High hangtime
$QualifierList[0,0,2] = new ScriptObject() {
text = "Frozen";
value = 7;
sound = Qualifier002Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[1,0,2] = new ScriptObject() {
text = "Shooting";
value = 8;
sound = Qualifier102Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[0,1,2] = new ScriptObject() {
text = "Dangling";
value = 9;
sound = Qualifier012Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[1,1,2] = new ScriptObject() {
text = "Blazing";
value = 10;
sound = Qualifier112Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[0,2,2] = new ScriptObject() {
text = "Raining";
value = 11;
sound = Qualifier022Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[1,2,2] = new ScriptObject() {
text = "Falling";
value = 12;
sound = Qualifier122Sound;
emitter = "Optional";
class = QualifierData;
};
////////////////////////////////////////////////////////////////////////////////
// Wow hangtime
$QualifierList[0,0,3] = new ScriptObject() {
text = "Suspended";
value = 13;
sound = Qualifier003Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[1,0,3] = new ScriptObject() {
text = "Skeeting";
value = 14;
sound = Qualifier103Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[0,1,3] = new ScriptObject() {
text = "Hanging";
value = 15;
sound = Qualifier013Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[1,1,3] = new ScriptObject() {
text = "Arcing";
value = 16;
sound = Qualifier113Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[0,2,3] = new ScriptObject() {
text = "Pouring";
value = 17;
sound = Qualifier023Sound;
emitter = "Optional";
class = QualifierData;
};
$QualifierList[1,2,3] = new ScriptObject() {
text = "Elite";
value = 18;
sound = Qualifier123Sound;
emitter = "Optional";
class = QualifierData;
};

View file

@ -0,0 +1,317 @@
// Roles
$TR2::role[0] = Goalie;
$TR2::role[1] = Defense;
$TR2::role[2] = Offense;
$TR2::numRoles = 3;
// For some reason the above "strings" convert to all lowercase
$TR2::roleText[Goalie] = "Goalie";
$TR2::roleText[Defense] = "Defense";
$TR2::roleText[Offense] = "Offense";
$TR2::roleMax[Goalie] = 1;
$TR2::roleMax[Defense] = 2;
$TR2::roleMax[Offense] = 10;
$TR2::roleArmor[Goalie] = Heavy;
$TR2::roleArmor[Defense] = Medium;
$TR2::roleArmor[Offense] = Light;
// Roles are automated via concentric circles around goals
$TR2::roleDistanceFromGoal[Goalie] = 70;
$TR2::roleDistanceFromGoal[Defense] = 350;
$TR2::roleDistanceFromGoal[Offense] = 10000;
// Number of ticks needed before changing to this role
$TR2::roleTicksNeeded[Goalie] = 0;
$TR2::roleTicksNeeded[Defense] = 0;
$TR2::roleTicksNeeded[Offense] = 0;
// Extra items for roles
$TR2::roleExtraItem[Goalie0] = TR2Shocklance;
$TR2::roleExtraItemCount[Goalie0] = 1;
$TR2::roleExtraItem[Goalie1] = TR2Mortar;
$TR2::roleExtraItemCount[Goalie1] = 1;
$TR2::roleExtraItem[Goalie2] = TR2MortarAmmo;
$TR2::roleExtraItemCount[Goalie2] = 99;
$TR2::roleNumExtraItems[Goalie] = 3;
$TR2::roleExtraItem[Defense0] = TR2Shocklance;
$TR2::roleExtraItemCount[Defense0] = 1;
$TR2::roleNumExtraItems[Defense] = 1;
$TR2::roleNumExtraItems[Offense] = 0;
function debugPrintRoles()
{
echo("**********************************ROLE PRINT");
}
function TR2Game::resetPlayerRoles(%game)
{
%count = ClientGroup.getCount();
for (%i = 0; %i < %count; %i++)
{
%cl = ClientGroup.getObject(%i);
%game.releaseRole(%cl);
}
for (%i=0; %i<$TR2::numRoles; %i++)
%game.initRole($TR2::Role[%i]);
}
function TR2Game::initRole(%game, %role)
{
$numPlayers[%role @ 1] = 0;
$numPlayers[%role @ 2] = 0;
}
function TR2Game::validateRoles(%game)
{
// Recalculate role counts
%count = ClientGroup.getCount();
for (%i = 0; %i<$TR2::numRoles; %i++)
{
%role = $TR2::role[%i];
%newCount[1] = 0;
%newCount[2] = 0;
for (%j = 0; %j<%count; %j++)
{
%cl = ClientGroup.getObject(%j);
if (%cl.currentRole $= %role)
%newCount[%cl.team]++;
}
$numPlayers[%role @ 1] = %newCount[1];
$numPlayers[%role @ 2] = %newCount[2];
}
// Make sure that all players are in the armor they're supposed to be in
for (%i = 0; %i < %count; %i++)
{
%cl = ClientGroup.getObject(%i);
if (!isObject(%cl) || !isObject(%cl.player))
continue;
// If somehow the player is active, but has no role, set the outer role
if (%cl.currentRole $= "")
%game.assignOutermostRole(%cl);
// If for some reason that wasn't possible, skip this player
if (%cl.currentRole $= "")
continue;
%player = %cl.player;
%armor = "TR2" @ $TR2::roleArmor[%cl.currentRole] @ %cl.sex @ HumanArmor;
// Swap armors if necessary
if (%player.getDataBlock().getName() !$= %armor)
{
// Don't allow an armor change if the player recently did something that requires
// datablock access, such as impacting the terrain. There is a T2 UE bug related
// to concurrent datablock access.
%time = getSimTime();
if (%time - %player.delayRoleChangeTime <= $TR2::datablockRoleChangeDelay)
return false;
%damagePct = %player.getDamagePercent();
%energyPct = %player.getEnergyPercent();
%player.setDataBlock(%armor);
%player.setDamageLevel(%damagePct * %player.getDataBlock().maxDamage);
%player.setEnergyLevel(%energyPct * %player.getDataBlock().maxEnergy);
}
}
}
function TR2Game::trySetRole(%game, %player, %role)
{
// Check concentric circles
if (!isObject(%player))
return false;
// Don't allow an armor change if the player recently did something that requires
// datablock access, such as impacting the terrain. There is a T2 UE bug related
// to concurrent datablock access.
%time = getSimTime();
if (%time - %player.delayRoleChangeTime <= $TR2::datablockRoleChangeDelay)
return false;
%position = %player.getPosition();
%distanceToGoal = VectorLen(VectorSub(%position, $teamGoalPosition[%player.team]));
if (%distanceToGoal > $TR2::roleDistanceFromGoal[%role])
{
%player.client.roleChangeTicks[%role] = 0;
return false;
}
// See if a change is even necessary
if (%player.client.currentRole $= %role)
{
return true;
}
// Make sure a spot is available
if ($numPlayers[%role @ %player.team] >= $TR2::roleMax[%role])
{
//echo("****ROLES: No slots left for " @ %role);
return false;
}
// Make sure enough time has been spent in this zone
if (%player.client.roleChangeTicks[%role] < $TR2::roleTicksNeeded[%role])
{
%player.client.roleChangeTicks[%role]++;
return false;
}
%team = %player.team;
// Change roles
// First release the old role, if applicable
if (%player.client.currentRole !$= "")
{
//echo("TEAM " @ %player.team @ " ROLE CHANGE: "
// @ %player.client.currentRole
// @ "(" @ $numPlayers[%player.client.currentRole @ %team] @ ") "
// @ " to "
// @ %role
// @ "(" @ $numPlayers[%role @ %team] @ ")"
//);
$numPlayers[%player.client.currentRole @ %team]--;
// Debug the decrement
if ($numPlayers[%player.client.currentRole @ %team] < 0)
{
echo("**ROLE CHANGE ERROR: negative role count");
$numPlayers[%player.client.currentRole @ %team] = 0;
}
}
// Now switch to the new role
$numPlayers[%role @ %team]++;
%newArmor = "TR2" @ $TR2::roleArmor[%role] @ %player.client.sex @ HumanArmor;
%player.client.roleChangeTicks[%role] = 0;
%player.setInvincible(false);
// Swap armors if necessary
if (%player.getDataBlock().getName() !$= %newArmor)
{
%damagePct = %player.getDamagePercent();
%energyPct = %player.getEnergyPercent();
//echo(" ROLE: " @ %damagePct @ " damage");
//echo(" ROLE: " @ %energyPct @ " energy");
//echo(" ROLE: pre-armorSwitchSched = " @ %player.armorSwitchSchedule);
%player.setDataBlock(%newArmor);
//echo(" ROLE: post-armorSwitchSched = " @ %player.armorSwitchSchedule);
%player.setDamageLevel(%damagePct * %player.getDataBlock().maxDamage);
%player.setEnergyLevel(%energyPct * %player.getDataBlock().maxEnergy);
}
%player.client.currentRole = %role;
// Equipment changes
%game.equipRoleWeapons(%player.client);
messageClient(%player.client, 'TR2ArmorChange', "\c3ROLE CHANGE: \c4" @ $TR2::roleText[%role] @ ".");
serverPlay3D(RoleChangeSound, %player.getPosition());
// Particle effect too?
//%newEmitter = new ParticleEmissionDummy(RoleChangeEffect) {
//position = %player.getTransform();
//rotation = "1 0 0 0";
//scale = "1 1 1";
//dataBlock = "defaultEmissionDummy";
//emitter = "RoleChangeEmitter";
//velocity = "1";
//};
//%newEmitter.schedule(800, "delete");
return true;
}
function TR2Game::updateRoles(%game)
{
%count = ClientGroup.getCount();
for (%i = 0; %i < %count; %i++)
{
%cl = ClientGroup.getObject(%i);
if (%cl $= "" || %cl.player == 0 || %cl.player $= "")
continue;
%done = false;
for (%j = 0; %j < $TR2::numRoles && !%done; %j++)
{
if (%game.trySetRole(%cl.player, $TR2::role[%j]))
%done = true;
}
}
}
function TR2Game::equipRoleWeapons(%game, %client)
{
%player = %client.player;
// Get rid of existing extra weapon
for (%i=0; %i<%client.extraRoleItems; %i++)
{
%item = %client.extraRoleItem[%i];
// If the player is using the item we're about to take away, equip
// the disc launcher
%equippedWeapon = %player.getMountedImage($WeaponSlot).item;
if (%equippedWeapon $= %item)
%player.use(TR2Disc);
%player.setInventory(%item, 0);
}
// Clear HUD
%client.setWeaponsHudItem(TR2Shocklance, 0, 0);
%client.setWeaponsHudItem(TR2Mortar, 0, 0);
// Equip role items
%client.extraRoleItems = $TR2::roleNumExtraItems[%client.currentRole];
for (%i=0; %i<%client.extraRoleItems; %i++)
{
%item = $TR2::roleExtraItem[%client.currentRole @ %i];
%roleItemAmount = $TR2::roleExtraItemCount[%client.currentRole @ %i];
// Hmm, this actually works, but it remembers that you
// lose your mortar ammo after a role switch. Get rid of it
// for now since there's unlimited mortar ammo anyway.
//if (%client.restockAmmo || %roleItemAmount == 1)
%itemAmount = %roleItemAmount;
//else
// %itemAmount = %client.lastRoleItemCount[%i];
%player.setInventory(%item, %itemAmount);
%client.extraRoleItem[%i] = %item;
%client.extraRoleItemCount[%i] = %itemAmount;
// Re-equip, if necessary
if (%item $= %equippedWeapon)
%player.use(%item);
}
//echo(" ROLE: weapons equipped.");
}
function TR2Game::releaseRole(%game, %client)
{
if (%client.currentRole $= "")
return;
//echo(" ROLE: client " @ %client @ " released " @ %client.currentRole);
$numPlayers[%client.currentRole @ %client.team]--;
%client.currentRole = "";
}
function TR2Game::assignOutermostRole(%game, %client)
{
//$role[%client.currentRole @ %client.team @ %i] = "";
//$numPlayers[%client.currentRole @ %client.team]--;
//%client.currentRole = $TR2::role[$TR2::numRoles-1];
//echo(" ROLE: assigning outermost");
%outerRole = $TR2::role[$TR2::numRoles-1];
if (%client.player > 0 && %client.currentRole !$= %outerRole)
%game.trySetRole(%client.player, %outerRole);
}

View file

@ -0,0 +1,104 @@
// Weapon bonuses
// Weapon speed
$WeaponSpeedBonusList = new ScriptObject() {
class = WeaponSpeedBonusList;
};
function WeaponSpeedBonusList::get(%this, %a)
{
return $WeaponSpeedBonusList[%a];
}
$WeaponSpeedBonusList[0] = new ScriptObject() {
text = "Kilo";
value = 1;
sound = "blah.wav";
emitter = "Optional";
class = BonusComponent;
};
$WeaponSpeedBonusList[1] = new ScriptObject() {
text = "Mega";
value = 3;
sound = "blah.wav";
emitter = "Optional";
class = BonusComponent;
};
$WeaponSpeedBonusList[2] = new ScriptObject() {
text = "Giga";
value = 5;
sound = "blah.wav";
emitter = "Optional";
class = BonusComponent;
};
// Weapon height
$WeaponHeightBonusList = new ScriptObject() {
class = WeaponHeightBonusList;
};
function WeaponHeightBonusList::get(%this, %a)
{
return $WeaponHeightBonusList[%a];
}
$WeaponHeightBonusList[0] = new ScriptObject() {
text = "Hovering";
value = 1;
sound = "blah.wav";
emitter = "Optional";
class = BonusComponent;
};
$WeaponHeightBonusList[1] = new ScriptObject() {
text = "Towering";
value = 3;
sound = "blah.wav";
emitter = "Optional";
class = BonusComponent;
};
$WeaponHeightBonusList[3] = new ScriptObject() {
text = "Nose-Bleeding";
value = 5;
sound = "blah.wav";
emitter = "Optional";
class = BonusComponent;
};
// Weapon type
$WeaponTypeBonusList = new ScriptObject() {
class = WeaponTypeBonusList;
};
function WeaponTypeBonusList::get(%this, %a)
{
return $WeaponTypeBonusList[%a];
}
$WeaponTypeBonusList[0] = new ScriptObject() {
text = "Disc";
value = 3;
sound = "blah.wav";
emitter = "Optional";
class = BonusComponent;
};
$WeaponTypeBonusList[1] = new ScriptObject() {
text = "Grenade";
value = 1;
sound = "blah.wav";
emitter = "Optional";
class = BonusComponent;
};
$WeaponTypeBonusList[2] = new ScriptObject() {
text = "Chain";
value = 2;
sound = "blah.wav";
emitter = "Optional";
class = BonusComponent;
};

View file

@ -0,0 +1,41 @@
datablock TSShapeConstructor(TR2HeavyMaleDts)
{
baseShape = "TR2heavy_male.dts";
sequence0 = "TR2heavy_male_root.dsq root";
sequence1 = "TR2heavy_male_forward.dsq run";
sequence2 = "TR2heavy_male_back.dsq back";
sequence3 = "TR2heavy_male_side.dsq side";
sequence4 = "heavy_male_lookde.dsq look";
sequence5 = "heavy_male_head.dsq head";
sequence6 = "TR2heavy_male_fall.dsq fall";
sequence7 = "TR2heavy_male_jet.dsq jet";
sequence8 = "TR2heavy_male_land.dsq land";
sequence9 = "TR2heavy_male_jump.dsq jump";
sequence10 = "heavy_male_recoilde.dsq light_recoil";
sequence11 = "heavy_male_idlepda.dsq pda";
sequence12 = "heavy_male_headside.dsq headside";
sequence13 = "heavy_male_lookms.dsq lookms";
sequence14 = "TR2heavy_male_diehead.dsq death1";
sequence15 = "TR2heavy_male_diechest.dsq death2";
sequence16 = "TR2heavy_male_dieback.dsq death3";
sequence17 = "TR2heavy_male_diesidelf.dsq death4";
sequence18 = "TR2heavy_male_diesidert.dsq death5";
sequence19 = "TR2heavy_male_dieforward.dsq death6"; // heavy_male_dieleglf
sequence20 = "TR2heavy_male_diechest.dsq death7"; // heavy_male_dielegrt
sequence21 = "TR2heavy_male_dieslump.dsq death8";
sequence22 = "TR2heavy_male_dieforward.dsq death9"; // heavy_male_dieknees
sequence23 = "TR2heavy_male_dieforward.dsq death10";
sequence24 = "TR2heavy_male_diespin.dsq death11";
sequence25 = "TR2heavy_male_celsalute.dsq cel1";
sequence26 = "TR2heavy_male_celwave.dsq cel2";
sequence27 = "TR2heavy_male_tauntbest.dsq cel3";
sequence28 = "TR2heavy_male_tauntimp.dsq cel4";
sequence29 = "TR2heavy_male_celdance.dsq cel5";
sequence30 = "TR2heavy_male_celflex.dsq cel6";
sequence31 = "TR2heavy_male_celtaunt.dsq cel7";
sequence32 = "TR2heavy_male_celjump.dsq cel8";
sequence33 = "TR2heavy_male_ski.dsq ski";
sequence34 = "TR2heavy_male_standjump.dsq standjump";
sequence35 = "heavy_male_looknw.dsq looknw";
};

View file

@ -0,0 +1,43 @@
datablock TSShapeConstructor(TR2LightFemaleDts)
{
baseShape = "TR2light_female.dts";
sequence0 = "TR2light_female_root.dsq root";
sequence1 = "TR2light_female_forward.dsq run";
sequence2 = "TR2light_female_back.dsq back";
sequence3 = "TR2light_female_side.dsq side";
sequence4 = "light_female_lookde.dsq look";
sequence5 = "light_female_head.dsq head";
sequence6 = "light_female_headside.dsq headside";
sequence7 = "TR2light_female_fall.dsq fall";
sequence8 = "TR2light_female_jet.dsq jet";
sequence9 = "TR2light_female_land.dsq land";
sequence10 = "TR2light_female_jump.dsq jump";
sequence11 = "light_female_recoilde.dsq light_recoil";
sequence12 = "light_female_scoutroot.dsq scoutroot";
sequence13 = "light_female_looksn.dsq looksn";
sequence14 = "light_female_lookms.dsq lookms";
sequence15 = "light_female_sitting.dsq sitting";
sequence16 = "light_female_idlepda.dsq pda";
sequence17 = "TR2light_female_diehead.dsq death1";
sequence18 = "TR2light_female_diechest.dsq death2";
sequence19 = "TR2light_female_dieback.dsq death3";
sequence20 = "TR2light_female_diesidelf.dsq death4";
sequence21 = "TR2light_female_diesidert.dsq death5";
sequence22 = "TR2light_female_dieleglf.dsq death6";
sequence23 = "TR2light_female_dielegrt.dsq death7";
sequence24 = "TR2light_female_dieslump.dsq death8";
sequence25 = "TR2light_female_dieknees.dsq death9";
sequence26 = "TR2light_female_dieforward.dsq death10";
sequence27 = "TR2light_female_diespin.dsq death11";
sequence28 = "TR2light_female_celsalute.dsq cel1";
sequence29 = "TR2light_female_celwave.dsq cel2";
sequence30 = "TR2light_female_tauntbest.dsq cel3";
sequence31 = "TR2light_female_tauntimp.dsq cel4";
sequence32 = "TR2light_female_celdance.dsq cel5";
sequence33 = "TR2light_female_tauntkiss.dsq cel6";
sequence34 = "TR2light_female_tauntbutt.dsq cel7";
sequence35 = "TR2light_female_celbow.dsq cel8";
sequence36 = "TR2light_female_ski.dsq ski";
sequence37 = "TR2light_female_standjump.dsq standjump";
sequence38 = "light_female_looknw.dsq looknw";
};

View file

@ -0,0 +1,43 @@
datablock TSShapeConstructor(TR2lightMaleDts)
{
baseShape = "TR2light_male.dts";
sequence0 = "TR2light_male_root.dsq root";
sequence1 = "TR2light_male_forward.dsq run";
sequence2 = "TR2light_male_back.dsq back";
sequence3 = "TR2light_male_side.dsq side";
sequence4 = "light_male_lookde.dsq look";
sequence5 = "light_male_head.dsq head";
sequence6 = "TR2light_male_fall.dsq fall";
sequence7 = "TR2light_male_jet.dsq jet";
sequence8 = "TR2light_male_land.dsq land";
sequence9 = "TR2light_male_jump.dsq jump";
sequence10 = "light_male_diehead.dsq death1";
sequence11 = "light_male_diechest.dsq death2";
sequence12 = "light_male_dieback.dsq death3";
sequence13 = "light_male_diesidelf.dsq death4";
sequence14 = "light_male_diesidert.dsq death5";
sequence15 = "light_male_dieleglf.dsq death6";
sequence16 = "light_male_dielegrt.dsq death7";
sequence17 = "light_male_dieslump.dsq death8";
sequence18 = "light_male_dieknees.dsq death9";
sequence19 = "light_male_dieforward.dsq death10";
sequence20 = "light_male_diespin.dsq death11";
sequence21 = "light_male_idlepda.dsq pda";
sequence22 = "light_male_looksn.dsq looksn";
sequence23 = "light_male_lookms.dsq lookms";
sequence24 = "light_male_scoutroot.dsq scoutroot";
sequence25 = "light_male_headside.dsq headside";
sequence26 = "light_male_recoilde.dsq light_recoil";
sequence27 = "light_male_sitting.dsq sitting";
sequence28 = "light_male_celsalute.dsq cel1";
sequence29 = "light_male_celwave.dsq cel2";
sequence30 = "light_male_tauntbest.dsq cel3";
sequence31 = "light_male_tauntimp.dsq cel4";
sequence32 = "light_male_celdisco.dsq cel5";
sequence33 = "light_male_celflex.dsq cel6";
sequence34 = "light_male_celtaunt.dsq cel7";
sequence35 = "light_male_celrocky.dsq cel8";
sequence36 = "TR2light_male_ski.dsq ski";
sequence37 = "light_male_standjump.dsq standjump";
sequence38 = "light_male_looknw.dsq looknw";
};

View file

@ -0,0 +1,42 @@
datablock TSShapeConstructor(TR2MediumFemaleDts)
{
baseShape = "TR2medium_female.dts";
sequence0 = "TR2medium_female_root.dsq root";
sequence1 = "TR2medium_female_forward.dsq run";
sequence2 = "TR2medium_female_back.dsq back";
sequence3 = "TR2medium_female_side.dsq side";
sequence4 = "medium_female_lookde.dsq look";
sequence5 = "medium_female_head.dsq head";
sequence6 = "medium_female_headside.dsq headside";
sequence7 = "TR2medium_female_fall.dsq fall";
sequence8 = "TR2medium_female_jet.dsq jet";
sequence9 = "TR2medium_female_land.dsq land";
sequence10 = "TR2medium_female_jump.dsq jump";
sequence11 = "medium_female_recoilde.dsq light_recoil";
sequence12 = "medium_female_looksn.dsq looksn";
sequence13 = "medium_female_lookms.dsq lookms";
sequence14 = "medium_female_sitting.dsq sitting";
sequence15 = "medium_female_idlepda.dsq pda";
sequence16 = "TR2medium_female_diehead.dsq death1";
sequence17 = "TR2medium_female_diechest.dsq death2";
sequence18 = "TR2medium_female_dieback.dsq death3";
sequence19 = "TR2medium_female_diesidelf.dsq death4";
sequence20 = "TR2medium_female_diesidert.dsq death5";
sequence21 = "TR2medium_female_dieleglf.dsq death6";
sequence22 = "TR2medium_female_dielegrt.dsq death7";
sequence23 = "TR2medium_female_dieslump.dsq death8";
sequence24 = "TR2medium_female_dieknees.dsq death9";
sequence25 = "TR2medium_female_dieforward.dsq death10";
sequence26 = "TR2medium_female_diespin.dsq death11";
sequence27 = "TR2medium_female_celsalute.dsq cel1";
sequence28 = "TR2medium_female_celwave.dsq cel2";
sequence29 = "TR2medium_female_tauntbest.dsq cel3";
sequence30 = "TR2medium_female_tauntimp.dsq cel4";
sequence31 = "TR2medium_female_celdisco.dsq cel5";
sequence32 = "TR2medium_female_tauntkiss.dsq cel6";
sequence33 = "TR2medium_female_tauntbutt.dsq cel7";
sequence34 = "TR2medium_female_celbow.dsq cel8";
sequence35 = "TR2medium_female_ski.dsq ski";
sequence36 = "TR2medium_female_standjump.dsq standjump";
sequence37 = "medium_female_looknw.dsq looknw";
};

View file

@ -0,0 +1,43 @@
datablock TSShapeConstructor(TR2MediumMaleDts)
{
baseShape = "TR2medium_male.dts";
sequence0 = "TR2medium_male_root.dsq root";
sequence1 = "TR2medium_male_forward.dsq run";
sequence2 = "TR2medium_male_back.dsq back";
sequence3 = "TR2medium_male_side.dsq side";
sequence4 = "medium_male_lookde.dsq look";
sequence5 = "medium_male_head.dsq head";
sequence6 = "TR2medium_male_fall.dsq fall";
sequence7 = "TR2medium_male_jet.dsq jet";
sequence8 = "TR2medium_male_land.dsq land";
sequence9 = "TR2medium_male_jump.dsq jump";
sequence10 = "medium_male_recoilde.dsq light_recoil";
sequence11 = "medium_male_headside.dsq headside";
sequence12 = "medium_male_looksn.dsq looksn";
sequence13 = "medium_male_lookms.dsq lookms";
sequence14 = "TR2medium_male_sitting.dsq sitting";
sequence15 = "TR2medium_male_diehead.dsq death1";
sequence16 = "TR2medium_male_diechest.dsq death2";
sequence17 = "TR2medium_male_dieback.dsq death3";
sequence18 = "TR2medium_male_diesidelf.dsq death4";
sequence19 = "TR2medium_male_diesidert.dsq death5";
sequence20 = "TR2medium_male_dieleglf.dsq death6";
sequence21 = "TR2medium_male_diechest.dsq death7"; // medium_male_dielegrt
sequence22 = "TR2medium_male_dieback.dsq death8";
sequence23 = "TR2medium_male_dieknees.dsq death9";
sequence24 = "TR2medium_male_dieforward.dsq death10";
sequence25 = "TR2medium_male_diespin.dsq death11";
sequence26 = "medium_male_idlepda.dsq pda";
sequence27 = "TR2medium_male_celsalute.dsq cel1";
sequence28 = "TR2medium_male_celwave.dsq cel2";
sequence29 = "TR2medium_male_tauntbest.dsq cel3";
sequence30 = "TR2medium_male_tauntimp.dsq cel4";
sequence31 = "TR2medium_male_celdance.dsq cel5";
sequence32 = "TR2medium_male_celflex.dsq cel6";
sequence33 = "TR2medium_male_celtaunt.dsq cel7";
sequence34 = "TR2medium_male_celrocky.dsq cel8";
sequence35 = "TR2medium_male_ski.dsq ski";
sequence36 = "TR2medium_male_standjump.dsq standjump";
sequence37 = "medium_male_looknw.dsq looknw";
};

View file

@ -0,0 +1,75 @@
// ------------------------------------------------------------------
// ENERGY PACK
// can be used by any armor type
// does not have to be activated
// increases the user's energy recharge rate
datablock ShapeBaseImageData(TR2EnergyPackImage)
{
shapeFile = "pack_upgrade_energy.dts";
item = TR2EnergyPack;
mountPoint = 1;
offset = "0 0 0";
rechargeRateBoost = 0.11;//0.15;
stateName[0] = "default";
stateSequence[0] = "activation";
};
datablock ItemData(TR2EnergyPack)
{
className = Pack;
catagory = "Packs";
shapeFile = "pack_upgrade_energy.dts";
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
rotate = true;
image = "TR2EnergyPackImage";
pickUpName = "an energy pack";
computeCRC = false;
};
function TR2EnergyPackImage::onMount(%data, %obj, %node)
{
%obj.setRechargeRate(%obj.getRechargeRate() + %data.rechargeRateBoost);
%obj.hasEnergyPack = true; // set for sniper check
}
function TR2EnergyPackImage::onUnmount(%data, %obj, %node)
{
%obj.setRechargeRate(%obj.getRechargeRate() - %data.rechargeRateBoost);
%obj.hasEnergyPack = "";
}
// KP: Tried adding these, but putting state transitions in
// the above datablock causes a UE. =(
function TR2EnergyPackImage::onActivate(%data, %obj, %slot)
{
if (%obj.holdingFlag > 0)
{
%obj.flagThrowStrength = 1.5;
%obj.throwObject(%obj.holdingFlag);
}
//messageClient(%obj.client, 'MsgShieldPackOn', '\c2Shield pack on.');
//%obj.isShielded = true;
//if ( !isDemo() )
// commandToClient( %obj.client, 'setShieldIconOn' );
}
function TR2EnergyPackImage::onDeactivate(%data, %obj, %slot)
{
//messageClient(%obj.client, 'MsgShieldPackOff', '\c2Shield pack off.');
//%obj.setImageTrigger(%slot,false);
//%obj.isShielded = "";
//if ( !isDemo() )
// commandToClient( %obj.client, 'setShieldIconOff' );
}
function TR2EnergyPack::onPickup(%this, %obj, %shape, %amount)
{
// created to prevent console errors
}

View file

@ -0,0 +1,676 @@
//--------------------------------------
// TR2Chaingun
//--------------------------------------
//--------------------------------------------------------------------------
// Force-Feedback Effects
//--------------------------------------
datablock EffectProfile(TR2ChaingunSwitchEffect)
{
effectname = "weapons/TR2Chaingun_activate";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2ChaingunFireEffect)
{
effectname = "weapons/TR2Chaingun_fire";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2ChaingunSpinUpEffect)
{
effectname = "weapons/TR2Chaingun_spinup";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2ChaingunSpinDownEffect)
{
effectname = "weapons/TR2Chaingun_spindown";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2ChaingunDryFire)
{
effectname = "weapons/TR2Chaingun_dryfire";
minDistance = 2.5;
maxDistance = 2.5;
};
//--------------------------------------------------------------------------
// Sounds
//--------------------------------------
datablock AudioProfile(TR2ChaingunSwitchSound)
{
filename = "fx/weapons/chaingun_activate.wav";
description = AudioClosest3d;
preload = true;
effect = TR2ChaingunSwitchEffect;
};
datablock AudioProfile(TR2ChaingunFireSound)
{
filename = "fx/weapons/chaingun_fire.wav";
description = AudioDefaultLooping3d;
preload = true;
effect = TR2ChaingunFireEffect;
};
datablock AudioProfile(TR2ChaingunProjectile)
{
filename = "fx/weapons/chaingun_projectile.wav";
description = ProjectileLooping3d;
preload = true;
};
datablock AudioProfile(TR2ChaingunImpact)
{
filename = "fx/weapons/chaingun_impact.WAV";
description = AudioClosest3d;
preload = true;
};
datablock AudioProfile(TR2ChaingunSpinDownSound)
{
filename = "fx/weapons/chaingun_spindown.wav";
description = AudioClosest3d;
preload = true;
effect = TR2ChaingunSpinDownEffect;
};
datablock AudioProfile(TR2ChaingunSpinUpSound)
{
filename = "fx/weapons/chaingun_spinup.wav";
description = AudioClosest3d;
preload = true;
effect = TR2ChaingunSpinUpEffect;
};
datablock AudioProfile(TR2ChaingunDryFireSound)
{
filename = "fx/weapons/chaingun_dryfire.wav";
description = AudioClose3d;
preload = true;
effect = TR2ChaingunDryFire;
};
datablock AudioProfile(ShrikeBlasterProjectileSound)
{
filename = "fx/vehicles/shrike_blaster_projectile.wav";
description = ProjectileLooping3d;
preload = true;
};
//--------------------------------------------------------------------------
// Splash
//--------------------------------------------------------------------------
datablock ParticleData( TR2ChaingunSplashParticle )
{
dragCoefficient = 1;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = -1.4;
lifetimeMS = 300;
lifetimeVarianceMS = 0;
textureName = "special/droplet";
colors[0] = "0.7 0.8 1.0 1.0";
colors[1] = "0.7 0.8 1.0 0.5";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 0.05;
sizes[1] = 0.2;
sizes[2] = 0.2;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData( TR2ChaingunSplashEmitter )
{
ejectionPeriodMS = 4;
periodVarianceMS = 0;
ejectionVelocity = 3;
velocityVariance = 1.0;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 50;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 100;
particles = "TR2ChaingunSplashParticle";
};
datablock SplashData(TR2ChaingunSplash)
{
numSegments = 10;
ejectionFreq = 10;
ejectionAngle = 20;
ringLifetime = 0.4;
lifetimeMS = 400;
velocity = 3.0;
startRadius = 0.0;
acceleration = -3.0;
texWrap = 5.0;
texture = "special/water2";
emitter[0] = TR2ChaingunSplashEmitter;
colors[0] = "0.7 0.8 1.0 0.0";
colors[1] = "0.7 0.8 1.0 1.0";
colors[2] = "0.7 0.8 1.0 0.0";
colors[3] = "0.7 0.8 1.0 0.0";
times[0] = 0.0;
times[1] = 0.4;
times[2] = 0.8;
times[3] = 1.0;
};
//--------------------------------------------------------------------------
// Particle Effects
//--------------------------------------
datablock ParticleData(TR2ChaingunFireParticle)
{
dragCoefficient = 2.75;
gravityCoefficient = 0.1;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 550;
lifetimeVarianceMS = 0;
textureName = "particleTest";
colors[0] = "0.46 0.36 0.26 1.0";
colors[1] = "0.46 0.36 0.26 0.0";
sizes[0] = 0.25;
sizes[1] = 0.20;
};
datablock ParticleEmitterData(TR2ChaingunFireEmitter)
{
ejectionPeriodMS = 6;
periodVarianceMS = 0;
ejectionVelocity = 10;
velocityVariance = 1.0;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 12;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvance = true;
particles = "TR2ChaingunFireParticle";
};
//--------------------------------------------------------------------------
// Explosions
//--------------------------------------
datablock ParticleData(TR2ChaingunExplosionParticle1)
{
dragCoefficient = 0.65;
gravityCoefficient = 0.3;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 500;
lifetimeVarianceMS = 150;
textureName = "particleTest";
colors[0] = "0.56 0.36 0.26 1.0";
colors[1] = "0.56 0.36 0.26 0.0";
sizes[0] = 0.0625;
sizes[1] = 0.2;
};
datablock ParticleEmitterData(TR2ChaingunExplosionEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 0.75;
velocityVariance = 0.25;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 60;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
particles = "TR2ChaingunExplosionParticle1";
};
datablock ParticleData(TR2ChaingunImpactSmokeParticle)
{
dragCoefficient = 0.0;
gravityCoefficient = -0.2;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 1000;
lifetimeVarianceMS = 200;
useInvAlpha = true;
spinRandomMin = -90.0;
spinRandomMax = 90.0;
textureName = "particleTest";
colors[0] = "0.7 0.7 0.7 0.0";
colors[1] = "0.7 0.7 0.7 0.4";
colors[2] = "0.7 0.7 0.7 0.0";
sizes[0] = 0.5;
sizes[1] = 0.5;
sizes[2] = 1.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2ChaingunImpactSmoke)
{
ejectionPeriodMS = 8;
periodVarianceMS = 1;
ejectionVelocity = 1.0;
velocityVariance = 0.5;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 35;
overrideAdvances = false;
particles = "TR2ChaingunImpactSmokeParticle";
lifetimeMS = 50;
};
datablock ParticleData(TR2ChaingunSparks)
{
dragCoefficient = 1;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = 0.0;
lifetimeMS = 300;
lifetimeVarianceMS = 0;
textureName = "special/spark00";
colors[0] = "0.56 0.36 0.26 1.0";
colors[1] = "0.56 0.36 0.26 1.0";
colors[2] = "1.0 0.36 0.26 0.0";
sizes[0] = 0.6;
sizes[1] = 0.2;
sizes[2] = 0.05;
times[0] = 0.0;
times[1] = 0.2;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2ChaingunSparkEmitter)
{
ejectionPeriodMS = 4;
periodVarianceMS = 0;
ejectionVelocity = 4;
velocityVariance = 2.0;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 50;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 100;
particles = "TR2ChaingunSparks";
};
datablock ExplosionData(TR2ChaingunExplosion)
{
soundProfile = TR2ChaingunImpact;
emitter[0] = TR2ChaingunImpactSmoke;
emitter[1] = TR2ChaingunSparkEmitter;
faceViewer = false;
};
datablock ShockwaveData(ScoutTR2ChaingunHit)
{
width = 0.5;
numSegments = 13;
numVertSegments = 1;
velocity = 0.5;
acceleration = 2.0;
lifetimeMS = 900;
height = 0.1;
verticalCurve = 0.5;
mapToTerrain = false;
renderBottom = false;
orientToNormal = true;
texture[0] = "special/shockwave5";
texture[1] = "special/gradient";
texWrap = 3.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
colors[0] = "0.6 0.6 1.0 1.0";
colors[1] = "0.6 0.3 1.0 0.5";
colors[2] = "0.0 0.0 1.0 0.0";
};
datablock ParticleData(ScoutTR2ChaingunExplosionParticle1)
{
dragCoefficient = 2;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = -0.0;
lifetimeMS = 600;
lifetimeVarianceMS = 000;
textureName = "special/crescent4";
colors[0] = "0.6 0.6 1.0 1.0";
colors[1] = "0.6 0.3 1.0 1.0";
colors[2] = "0.0 0.0 1.0 0.0";
sizes[0] = 0.25;
sizes[1] = 0.5;
sizes[2] = 1.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(ScoutTR2ChaingunExplosionEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 2;
velocityVariance = 1.5;
ejectionOffset = 0.0;
thetaMin = 80;
thetaMax = 90;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 200;
particles = "ScoutTR2ChaingunExplosionParticle1";
};
datablock ExplosionData(ScoutTR2ChaingunExplosion)
{
soundProfile = blasterExpSound;
shockwave = ScoutTR2ChaingunHit;
emitter[0] = ScoutTR2ChaingunExplosionEmitter;
};
//--------------------------------------------------------------------------
// Particle effects
//--------------------------------------
datablock DebrisData( TR2ShellDebris )
{
shapeName = "weapon_chaingun_ammocasing.dts";
lifetime = 3.0;
minSpinSpeed = 300.0;
maxSpinSpeed = 400.0;
elasticity = 0.5;
friction = 0.2;
numBounces = 3;
fade = true;
staticOnMaxBounce = true;
snapOnMaxBounce = true;
};
//--------------------------------------------------------------------------
// Projectile
//--------------------------------------
datablock DecalData(TR2ChaingunDecal1)
{
sizeX = 0.05;
sizeY = 0.05;
textureName = "special/bullethole1";
};
datablock DecalData(TR2ChaingunDecal2) : TR2ChaingunDecal1
{
textureName = "special/bullethole2";
};
datablock DecalData(TR2ChaingunDecal3) : TR2ChaingunDecal1
{
textureName = "special/bullethole3";
};
datablock DecalData(TR2ChaingunDecal4) : TR2ChaingunDecal1
{
textureName = "special/bullethole4";
};
datablock DecalData(TR2ChaingunDecal5) : TR2ChaingunDecal1
{
textureName = "special/bullethole5";
};
datablock DecalData(TR2ChaingunDecal6) : TR2ChaingunDecal1
{
textureName = "special/bullethole6";
};
datablock TracerProjectileData(TR2ChaingunBullet)
{
doDynamicClientHits = true;
directDamage = 0.065;
directDamageType = $DamageType::Bullet;
explosion = "TR2ChaingunExplosion";
splash = TR2ChaingunSplash;
kickBackStrength = 0.0;
sound = TR2ChaingunProjectile;
dryVelocity = 750.0;
wetVelocity = 280.0;
velInheritFactor = 1.0;
fizzleTimeMS = 3000;
lifetimeMS = 3000;
explodeOnDeath = false;
reflectOnWaterImpactAngle = 0.0;
explodeOnWaterImpact = false;
deflectionOnWaterImpact = 0.0;
fizzleUnderwaterMS = 3000;
tracerLength = 30.0;//15.0;
tracerAlpha = false;
tracerMinPixels = 6;
tracerColor = 211.0/255.0 @ " " @ 215.0/255.0 @ " " @ 120.0/255.0 @ " 0.75";
//211.0/255.0 @ " " @ 215.0/255.0 @ " " @ 120.0/255.0 @ " 0.75";
tracerTex[0] = "special/tracer00";
tracerTex[1] = "special/tracercross";
tracerWidth = 0.20;//0.10;
crossSize = 0.20;
crossViewAng = 0.990;
renderCross = true;
decalData[0] = TR2ChaingunDecal1;
decalData[1] = TR2ChaingunDecal2;
decalData[2] = TR2ChaingunDecal3;
decalData[3] = TR2ChaingunDecal4;
decalData[4] = TR2ChaingunDecal5;
decalData[5] = TR2ChaingunDecal6;
};
//--------------------------------------------------------------------------
// Scout Projectile
//--------------------------------------
datablock TracerProjectileData(ScoutTR2ChaingunBullet)
{
doDynamicClientHits = true;
directDamage = 0.125;
explosion = "ScoutTR2ChaingunExplosion";
splash = TR2ChaingunSplash;
directDamageType = $DamageType::ShrikeBlaster;
kickBackStrength = 0.0;
sound = ShrikeBlasterProjectileSound;
dryVelocity = 400.0;
wetVelocity = 100.0;
velInheritFactor = 1.0;
fizzleTimeMS = 1000;
lifetimeMS = 1000;
explodeOnDeath = false;
reflectOnWaterImpactAngle = 0.0;
explodeOnWaterImpact = false;
deflectionOnWaterImpact = 0.0;
fizzleUnderwaterMS = 3000;
tracerLength = 45.0;
tracerAlpha = false;
tracerMinPixels = 6;
tracerColor = "1.0 1.0 1.0 1.0";
tracerTex[0] = "special/shrikeBolt";
tracerTex[1] = "special/shrikeBoltCross";
tracerWidth = 0.55;
crossSize = 0.99;
crossViewAng = 0.990;
renderCross = true;
};
//--------------------------------------------------------------------------
// Ammo
//--------------------------------------
datablock ItemData(TR2ChaingunAmmo)
{
className = Ammo;
catagory = "Ammo";
shapeFile = "ammo_chaingun.dts";
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "some chaingun ammo";
computeCRC = false;
};
//--------------------------------------------------------------------------
// Weapon
//--------------------------------------
datablock ShapeBaseImageData(TR2ChaingunImage)
{
className = WeaponImage;
shapeFile = "TR2weapon_chaingun.dts";
item = TR2Chaingun;
ammo = TR2ChaingunAmmo;
projectile = TR2ChaingunBullet;
projectileType = TracerProjectile;
emap = true;
casing = TR2ShellDebris;
shellExitDir = "1.0 0.3 1.0";
shellExitOffset = "0.15 -0.56 -0.1";
shellExitVariance = 18.0;
shellVelocity = 4.0;
projectileSpread = 5.5 / 1000.0;
//--------------------------------------
stateName[0] = "Activate";
stateSequence[0] = "Activate";
stateSound[0] = TR2ChaingunSwitchSound;
stateAllowImageChange[0] = false;
//
stateTimeoutValue[0] = 0.5;
stateTransitionOnTimeout[0] = "Ready";
stateTransitionOnNoAmmo[0] = "NoAmmo";
//--------------------------------------
stateName[1] = "Ready";
stateSpinThread[1] = Stop;
//
stateTransitionOnTriggerDown[1] = "Spinup";
stateTransitionOnNoAmmo[1] = "NoAmmo";
//--------------------------------------
stateName[2] = "NoAmmo";
stateTransitionOnAmmo[2] = "Ready";
stateSpinThread[2] = Stop;
stateTransitionOnTriggerDown[2] = "DryFire";
//--------------------------------------
stateName[3] = "Spinup";
stateSpinThread[3] = SpinUp;
stateSound[3] = TR2ChaingunSpinupSound;
//
stateTimeoutValue[3] = 0.5;
stateWaitForTimeout[3] = false;
stateTransitionOnTimeout[3] = "Fire";
stateTransitionOnTriggerUp[3] = "Spindown";
//--------------------------------------
stateName[4] = "Fire";
stateSequence[4] = "Fire";
stateSequenceRandomFlash[4] = true;
stateSpinThread[4] = FullSpeed;
stateSound[4] = TR2ChaingunFireSound;
//stateRecoil[4] = LightRecoil;
stateAllowImageChange[4] = false;
stateScript[4] = "onFire";
stateFire[4] = true;
stateEjectShell[4] = true;
//
stateTimeoutValue[4] = 0.15;
stateTransitionOnTimeout[4] = "Fire";
stateTransitionOnTriggerUp[4] = "Spindown";
stateTransitionOnNoAmmo[4] = "EmptySpindown";
//--------------------------------------
stateName[5] = "Spindown";
stateSound[5] = TR2ChaingunSpinDownSound;
stateSpinThread[5] = SpinDown;
//
stateTimeoutValue[5] = 0.4;//1.0;
stateWaitForTimeout[5] = false;//true;
stateTransitionOnTimeout[5] = "Ready";
stateTransitionOnTriggerDown[5] = "Spinup";
//--------------------------------------
stateName[6] = "EmptySpindown";
stateSound[6] = TR2ChaingunSpinDownSound;
stateSpinThread[6] = SpinDown;
//
stateTimeoutValue[6] = 0.5;
stateTransitionOnTimeout[6] = "NoAmmo";
//--------------------------------------
stateName[7] = "DryFire";
stateSound[7] = TR2ChaingunDryFireSound;
stateTimeoutValue[7] = 0.5;
stateTransitionOnTimeout[7] = "NoAmmo";
};
datablock ItemData(TR2Chaingun)
{
className = Weapon;
catagory = "Spawn Items";
shapeFile = "TR2weapon_chaingun.dts";
image = TR2ChaingunImage;
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "a chaingun";
computeCRC = true;
emap = true;
};

View file

@ -0,0 +1,484 @@
//--------------------------------------
// TR2Disc launcher
//--------------------------------------
//--------------------------------------------------------------------------
// Force-Feedback Effects
//--------------------------------------
datablock EffectProfile(TR2DiscFireEffect)
{
effectname = "weapons/Tspinfusor_fire";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2DiscSwitchEffect)
{
effectname = "weapons/spinfusor_activate";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2DiscDryFireEffect)
{
effectname = "weapons/spinfusor_dryfire";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2DiscIdleEffect)
{
effectname = "weapons/spinfusor_idle";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2DiscReloadEffect)
{
effectname = "weapons/spinfusor_reload";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2DiscExpEffect)
{
effectname = "explosions/grenade_explode";
minDistance = 5;
maxDistance = 20;
};
//--------------------------------------------------------------------------
// Sounds
//--------------------------------------
datablock AudioProfile(TR2DiscSwitchSound)
{
filename = "fx/weapons/blaster_activate.wav";
description = AudioClosest3d;
preload = true;
effect = TR2DiscSwitchEffect;
};
datablock AudioProfile(TR2DiscLoopSound)
{
filename = "fx/weapons/spinfusor_idle.wav";
description = ClosestLooping3d;
effect = TR2DiscIdleEffect;
};
datablock AudioProfile(TR2DiscFireSound)
{
filename = "fx/weapons/TR2spinfusor_fire.wav";
description = AudioDefault3d;
preload = true;
effect = TR2DiscFireEffect;
};
datablock AudioProfile(TR2DiscReloadSound)
{
filename = "fx/weapons/spinfusor_reload.wav";
description = AudioClosest3d;
preload = true;
effect = TR2DiscReloadEffect;
};
datablock AudioProfile(TR2DiscExpSound)
{
filename = "fx/weapons/spinfusor_impact.wav";
description = AudioExplosion3d;
preload = true;
effect = TR2DiscExpEffect;
};
datablock AudioProfile(underwaterTR2DiscExpSound)
{
filename = "fx/weapons/spinfusor_impact_UW.wav";
description = AudioExplosion3d;
preload = true;
effect = TR2DiscExpEffect;
};
datablock AudioProfile(TR2DiscProjectileSound)
{
filename = "fx/weapons/spinfusor_projectile.wav";
description = ProjectileLooping3d;
preload = true;
};
datablock AudioProfile(TR2DiscDryFireSound)
{
filename = "fx/weapons/spinfusor_dryfire.wav";
description = AudioClose3d;
preload = true;
effect = TR2DiscDryFireEffect;
};
//--------------------------------------------------------------------------
// Explosion
//--------------------------------------
datablock ParticleData(TR2DiscExplosionBubbleParticle)
{
dragCoefficient = 0.0;
gravityCoefficient = -0.25;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 2000;
lifetimeVarianceMS = 750;
useInvAlpha = false;
textureName = "special/bubbles";
spinRandomMin = -100.0;
spinRandomMax = 100.0;
colors[0] = "0.7 0.8 1.0 0.0";
colors[1] = "0.7 0.8 1.0 0.4";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 1.0;
sizes[1] = 1.0;
sizes[2] = 1.0;
times[0] = 0.0;
times[1] = 0.3;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2DiscExplosionBubbleEmitter)
{
ejectionPeriodMS = 7;
periodVarianceMS = 0;
ejectionVelocity = 1.0;
ejectionOffset = 3.0;
velocityVariance = 0.5;
thetaMin = 0;
thetaMax = 80;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
particles = "TR2DiscExplosionBubbleParticle";
};
datablock ExplosionData(UnderwaterTR2DiscExplosion)
{
explosionShape = "Disc_explosion.dts";
soundProfile = underwaterTR2DiscExpSound;
faceViewer = true;
sizes[0] = "1.3 1.3 1.3";
sizes[1] = "0.75 0.75 0.75";
sizes[2] = "0.4 0.4 0.4";
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
emitter[0] = "TR2DiscExplosionBubbleEmitter";
shakeCamera = false;//true;
camShakeFreq = "10.0 11.0 10.0";
camShakeAmp = "20.0 20.0 20.0";
camShakeDuration = 0.5;
camShakeRadius = 10.0;
};
datablock ExplosionData(TR2DiscExplosion)
{
explosionShape = "Disc_explosion.dts";
soundProfile = TR2DiscExpSound;
faceViewer = true;
explosionScale = "2.0 2.0 2.0";//"1 1 1";
shakeCamera = false;//true;
camShakeFreq = "10.0 11.0 10.0";
camShakeAmp = "20.0 20.0 20.0";
camShakeDuration = 0.5;
camShakeRadius = 10.0;
sizes[0] = "2.5 2.5 2.5";//"1.0 1.0 1.0";
sizes[1] = "2.5 2.5 2.5";//"1.0 1.0 1.0";
times[0] = 0.0;
times[1] = 1.0;
};
//--------------------------------------------------------------------------
// Splash
//--------------------------------------------------------------------------
datablock ParticleData(TR2DiscMist)
{
dragCoefficient = 2.0;
gravityCoefficient = -0.05;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 400;
lifetimeVarianceMS = 100;
useInvAlpha = false;
spinRandomMin = -90.0;
spinRandomMax = 500.0;
textureName = "particleTest";
colors[0] = "0.7 0.8 1.0 1.0";
colors[1] = "0.7 0.8 1.0 0.5";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 0.5;
sizes[1] = 0.5;
sizes[2] = 0.8;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2DiscMistEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 3.0;
velocityVariance = 2.0;
ejectionOffset = 0.0;
thetaMin = 85;
thetaMax = 85;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
lifetimeMS = 250;
particles = "TR2DiscMist";
};
datablock ParticleData( TR2DiscSplashParticle2 )
{
dragCoeffiecient = 0.4;
gravityCoefficient = -0.03; // rises slowly
inheritedVelFactor = 0.025;
lifetimeMS = 600;
lifetimeVarianceMS = 300;
textureName = "particleTest";
useInvAlpha = false;
spinRandomMin = -200.0;
spinRandomMax = 200.0;
colors[0] = "0.7 0.8 1.0 1.0";
colors[1] = "0.7 0.8 1.0 0.5";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 0.5;
sizes[1] = 1.0;
sizes[2] = 2.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData( TR2DiscSplashEmitter2 )
{
ejectionPeriodMS = 25;
ejectionOffset = 0.2;
periodVarianceMS = 0;
ejectionVelocity = 2.25;
velocityVariance = 0.50;
thetaMin = 0.0;
thetaMax = 30.0;
lifetimeMS = 250;
particles = "TR2DiscSplashParticle2";
};
datablock ParticleData( TR2DiscSplashParticle )
{
dragCoefficient = 1;
gravityCoefficient = 0.2;
inheritedVelFactor = 0.2;
constantAcceleration = -0.0;
lifetimeMS = 600;
lifetimeVarianceMS = 0;
textureName = "special/droplet";
colors[0] = "0.7 0.8 1.0 1.0";
colors[1] = "0.7 0.8 1.0 0.5";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 0.5;
sizes[1] = 0.5;
sizes[2] = 0.5;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData( TR2DiscSplashEmitter )
{
ejectionPeriodMS = 1;
periodVarianceMS = 0;
ejectionVelocity = 3;
velocityVariance = 1.0;
ejectionOffset = 0.0;
thetaMin = 60;
thetaMax = 80;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 100;
particles = "TR2DiscSplashParticle";
};
datablock SplashData(TR2DiscSplash)
{
numSegments = 15;
ejectionFreq = 0.0001;
ejectionAngle = 45;
ringLifetime = 0.5;
lifetimeMS = 400;
velocity = 5.0;
startRadius = 0.0;
acceleration = -3.0;
texWrap = 5.0;
texture = "special/water2";
emitter[0] = TR2DiscSplashEmitter;
emitter[1] = TR2DiscMistEmitter;
colors[0] = "0.7 0.8 1.0 0.0";
colors[1] = "0.7 0.8 1.0 1.0";
colors[2] = "0.7 0.8 1.0 0.0";
colors[3] = "0.7 0.8 1.0 0.0";
times[0] = 0.0;
times[1] = 0.4;
times[2] = 0.8;
times[3] = 1.0;
};
//--------------------------------------------------------------------------
// Projectile
//--------------------------------------
datablock LinearProjectileData(TR2DiscProjectile)
{
projectileShapeName = "Disc.dts";
emitterDelay = -1;
directDamage = 0.0;
hasDamageRadius = true;
indirectDamage = 0.5;//0.35;//0.50;
damageRadius = 15;//11;//7.5;
radiusDamageType = $DamageType::Disc;
kickBackStrength = 6100;//1750;
sound = TR2DiscProjectileSound;
explosion = "TR2DiscExplosion";
underwaterExplosion = "UnderwaterTR2DiscExplosion";
splash = TR2DiscSplash;
dryVelocity = 130;//90;
wetVelocity = 120;
velInheritFactor = 0.7;
fizzleTimeMS = 5000;
lifetimeMS = 5000;
explodeOnDeath = true;
reflectOnWaterImpactAngle = 30.0;//15.0;
explodeOnWaterImpact = false;
deflectionOnWaterImpact = 0.0;
fizzleUnderwaterMS = 5000;
activateDelayMS = 100;
hasLight = true;
lightRadius = 6.0;
lightColor = "0.175 0.175 1.0";
};
//--------------------------------------------------------------------------
// Ammo
//--------------------------------------
datablock ItemData(TR2DiscAmmo)
{
className = Ammo;
catagory = "Ammo";
shapeFile = "ammo_disc.dts";
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "some spinfusor discs";
computeCRC = false;
};
//--------------------------------------------------------------------------
// Weapon
//--------------------------------------
datablock ShapeBaseImageData(TR2DiscImage)
{
className = WeaponImage;
shapeFile = "TR2weapon_disc.dts";
item = TR2Disc;
ammo = TR2DiscAmmo;
offset = "0 -0.5 0";
emap = true;
projectileSpread = 0.0 / 1000.0;
projectile = TR2DiscProjectile;
projectileType = LinearProjectile;
// State Data
stateName[0] = "Preactivate";
stateTransitionOnLoaded[0] = "Activate";
stateTransitionOnNoAmmo[0] = "NoAmmo";
stateName[1] = "Activate";
stateTransitionOnTimeout[1] = "Ready";
stateTimeoutValue[1] = 0.5;
stateSequence[1] = "Activated";
stateSound[1] = TR2DiscSwitchSound;
stateName[2] = "Ready";
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "Fire";
stateSequence[2] = "TR2DiscSpin";
stateSound[2] = TR2DiscLoopSound;
stateName[3] = "Fire";
stateTransitionOnTimeout[3] = "Reload";
stateTimeoutValue[3] = 1.25;
stateFire[3] = true;
stateRecoil[3] = LightRecoil;
stateAllowImageChange[3] = false;
stateSequence[3] = "Fire";
stateScript[3] = "onFire";
stateSound[3] = TR2DiscFireSound;
stateName[4] = "Reload";
stateTransitionOnNoAmmo[4] = "NoAmmo";
stateTransitionOnTimeout[4] = "Ready";
stateTimeoutValue[4] = 0.5; // 0.25 load, 0.25 spinup
stateAllowImageChange[4] = false;
stateSequence[4] = "Reload";
stateSound[4] = TR2DiscReloadSound;
stateName[5] = "NoAmmo";
stateTransitionOnAmmo[5] = "Reload";
stateSequence[5] = "NoAmmo";
stateTransitionOnTriggerDown[5] = "DryFire";
stateName[6] = "DryFire";
stateSound[6] = TR2DiscDryFireSound;
stateTimeoutValue[6] = 1.0;
stateTransitionOnTimeout[6] = "NoAmmo";
};
datablock ItemData(TR2Disc)
{
className = Weapon;
catagory = "Spawn Items";
shapeFile = "TR2weapon_disc.dts";
image = TR2DiscImage;
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "a spinfusor";
computeCRC = true;
emap = true;
};

View file

@ -0,0 +1,380 @@
// ------------------------------------------------------------------------
// grenade (thrown by hand) script
// ------------------------------------------------------------------------
datablock EffectProfile(TR2GrenadeThrowEffect)
{
effectname = "weapons/grenade_throw";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2GrenadeSwitchEffect)
{
effectname = "weapons/generic_switch";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock AudioProfile(TR2GrenadeThrowSound)
{
filename = "fx/weapons/throw_grenade.wav";
description = AudioClose3D;
preload = true;
effect = GrenadeThrowEffect;
};
datablock AudioProfile(TR2GrenadeSwitchSound)
{
filename = "fx/weapons/generic_switch.wav";
description = AudioClosest3D;
preload = true;
effect = GrenadeSwitchEffect;
};
//**************************************************************************
// Hand Grenade underwater fx
//**************************************************************************
//--------------------------------------------------------------------------
// Underwater Hand Grenade Particle effects
//--------------------------------------------------------------------------
datablock ParticleData(TR2HandGrenadeExplosionBubbleParticle)
{
dragCoefficient = 0.0;
gravityCoefficient = -0.25;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 2000;
lifetimeVarianceMS = 750;
useInvAlpha = false;
textureName = "special/bubbles";
spinRandomMin = -100.0;
spinRandomMax = 100.0;
colors[0] = "0.7 0.8 1.0 0.0";
colors[1] = "0.7 0.8 1.0 0.4";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 0.75;
sizes[1] = 0.75;
sizes[2] = 0.75;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2HandGrenadeExplosionBubbleEmitter)
{
ejectionPeriodMS = 7;
periodVarianceMS = 0;
ejectionVelocity = 1.0;
ejectionOffset = 2.0;
velocityVariance = 0.5;
thetaMin = 0;
thetaMax = 80;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
particles = "TR2HandGrenadeExplosionBubbleParticle";
};
datablock ParticleData(UnderwaterTR2HandGrenadeExplosionSmoke)
{
dragCoeffiecient = 105.0;
gravityCoefficient = -0.0; // rises slowly
inheritedVelFactor = 0.025;
constantAcceleration = -1.0;
lifetimeMS = 1250;
lifetimeVarianceMS = 0;
textureName = "particleTest";
useInvAlpha = false;
spinRandomMin = -200.0;
spinRandomMax = 200.0;
textureName = "special/Smoke/smoke_001";
colors[0] = "0.4 0.4 1.0 1.0";
colors[1] = "0.4 0.4 1.0 0.5";
colors[2] = "0.0 0.0 0.0 0.0";
sizes[0] = 1.0;
sizes[1] = 3.0;
sizes[2] = 5.0;
times[0] = 0.0;
times[1] = 0.2;
times[2] = 1.0;
};
datablock ParticleEmitterData(UnderwaterTR2HandGrenadeExplosionSmokeEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 5.25;
velocityVariance = 0.25;
thetaMin = 0.0;
thetaMax = 180.0;
lifetimeMS = 250;
particles = "UnderwaterTR2HandGrenadeExplosionSmoke";
};
datablock ParticleData(UnderwaterTR2HandGrenadeSparks)
{
dragCoefficient = 1;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = 0.0;
lifetimeMS = 500;
lifetimeVarianceMS = 350;
textureName = "special/droplet";
colors[0] = "0.6 0.6 1.0 1.0";
colors[1] = "0.6 0.6 1.0 1.0";
colors[2] = "0.6 0.6 1.0 0.0";
sizes[0] = 0.5;
sizes[1] = 0.25;
sizes[2] = 0.25;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(UnderwaterTR2HandGrenadeSparkEmitter)
{
ejectionPeriodMS = 3;
periodVarianceMS = 0;
ejectionVelocity = 10;
velocityVariance = 6.75;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 180;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 100;
particles = "UnderwaterTR2HandGrenadeSparks";
};
datablock ExplosionData(UnderwaterTR2HandGrenadeSubExplosion1)
{
offset = 1.0;
emitter[0] = UnderwaterTR2HandGrenadeExplosionSmokeEmitter;
emitter[1] = UnderwaterTR2HandGrenadeSparkEmitter;
};
datablock ExplosionData(UnderwaterTR2HandGrenadeSubExplosion2)
{
offset = 1.0;
emitter[0] = UnderwaterTR2HandGrenadeExplosionSmokeEmitter;
emitter[1] = UnderwaterTR2HandGrenadeSparkEmitter;
};
datablock ExplosionData(UnderwaterTR2HandGrenadeExplosion)
{
soundProfile = TR2GrenadeExplosionSound;
emitter[0] = UnderwaterTR2HandGrenadeExplosionSmokeEmitter;
emitter[1] = UnderwaterTR2HandGrenadeSparkEmitter;
emitter[2] = TR2HandGrenadeExplosionBubbleEmitter;
subExplosion[0] = UnderwaterTR2HandGrenadeSubExplosion1;
subExplosion[1] = UnderwaterTR2HandGrenadeSubExplosion2;
shakeCamera = true;
camShakeFreq = "12.0 13.0 11.0";
camShakeAmp = "35.0 35.0 35.0";
camShakeDuration = 1.0;
camShakeRadius = 15.0;
};
//**************************************************************************
// Hand Grenade effects
//**************************************************************************
//--------------------------------------------------------------------------
// Grenade Particle effects
//--------------------------------------------------------------------------
datablock ParticleData(TR2HandGrenadeExplosionSmoke)
{
dragCoeffiecient = 105.0;
gravityCoefficient = -0.0; // rises slowly
inheritedVelFactor = 0.025;
constantAcceleration = -0.80;
lifetimeMS = 1250;
lifetimeVarianceMS = 0;
textureName = "particleTest";
useInvAlpha = true;
spinRandomMin = -200.0;
spinRandomMax = 200.0;
textureName = "special/Smoke/smoke_001";
colors[0] = "1.0 0.7 0.0 1.0";
colors[1] = "0.2 0.2 0.2 1.0";
colors[2] = "0.0 0.0 0.0 0.0";
sizes[0] = 4.0;//1.0;
sizes[1] = 12.0;//3.0;
sizes[2] = 20.0;//5.0;
times[0] = 0.0;
times[1] = 0.2;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2HandGrenadeExplosionSmokeEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 10.25;
velocityVariance = 0.25;
thetaMin = 0.0;
thetaMax = 180.0;
lifetimeMS = 250;
particles = "TR2HandGrenadeExplosionSmoke";
};
datablock ParticleData(TR2HandGrenadeSparks)
{
dragCoefficient = 1;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = 0.0;
lifetimeMS = 500;
lifetimeVarianceMS = 350;
textureName = "special/bigSpark";
colors[0] = "0.56 0.36 0.26 1.0";
colors[1] = "0.56 0.36 0.26 1.0";
colors[2] = "1.0 0.36 0.26 0.0";
sizes[0] = 3.0;//0.5;
sizes[1] = 1.5;//0.25;
sizes[2] = 1.0;//0.25;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2HandGrenadeSparkEmitter)
{
ejectionPeriodMS = 3;
periodVarianceMS = 0;
ejectionVelocity = 24;//18;
velocityVariance = 6.75;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 180;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 100;
particles = "TR2HandGrenadeSparks";
};
//----------------------------------------------------
// Explosion
//----------------------------------------------------
datablock ExplosionData(TR2HandGrenadeSubExplosion1)
{
offset = 2.0;
emitter[0] = TR2HandGrenadeExplosionSmokeEmitter;
emitter[1] = TR2HandGrenadeSparkEmitter;
};
datablock ExplosionData(TR2HandGrenadeSubExplosion2)
{
offset = 2.0;
emitter[0] = TR2HandGrenadeExplosionSmokeEmitter;
emitter[1] = TR2HandGrenadeSparkEmitter;
};
datablock ExplosionData(TR2HandGrenadeExplosion)
{
soundProfile = TR2GrenadeExplosionSound;
emitter[0] = TR2HandGrenadeExplosionSmokeEmitter;
emitter[1] = TR2HandGrenadeSparkEmitter;
subExplosion[0] = TR2HandGrenadeSubExplosion1;
subExplosion[1] = TR2HandGrenadeSubExplosion2;
shakeCamera = true;
camShakeFreq = "12.0 13.0 11.0";
camShakeAmp = "35.0 35.0 35.0";
camShakeDuration = 1.0;
camShakeRadius = 15.0;
};
datablock ItemData(TR2GrenadeThrown)
{
className = Weapon;
shapeFile = "grenade.dts";
mass = 0.35;//0.7;
elasticity = 0.2;
friction = 1;
pickupRadius = 2;
maxDamage = 0.5;
explosion = TR2HandGrenadeExplosion;
underwaterExplosion = UnderwaterTR2HandGrenadeExplosion;
indirectDamage = 0.4;
damageRadius = 22.0;//10.0;
radiusDamageType = $DamageType::Grenade;
kickBackStrength = 8000;//2000;
computeCRC = false;
};
datablock ItemData(TR2Grenade)
{
className = HandInventory;
catagory = "Handheld";
shapeFile = "grenade.dts";
mass = 0.35;//0.7;
elasticity = 0.2;
friction = 1;
pickupRadius = 2;
thrownItem = TR2GrenadeThrown;
pickUpName = "some grenades";
isGrenade = true;
computeCRC = false;
};
function TR2GrenadeThrown::onThrow(%this, %gren)
{
//AIGrenadeThrow(%gren);
%gren.detThread = schedule(2000, %gren, "detonateGrenade", %gren);
}

View file

@ -0,0 +1,788 @@
//--------------------------------------
// TR2Grenade launcher
//--------------------------------------
//--------------------------------------------------------------------------
// Force-Feedback Effects
//--------------------------------------
datablock EffectProfile(TR2GrenadeSwitchEffect)
{
effectname = "weapons/generic_switch";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2GrenadeFireEffect)
{
effectname = "weapons/grenadelauncher_fire";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2GrenadeDryFireEffect)
{
effectname = "weapons/grenadelauncher_dryfire";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2GrenadeReloadEffect)
{
effectname = "weapons/generic_switch";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2GrenadeExplosionEffect)
{
effectname = "explosions/grenade_explode";
minDistance = 10;
maxDistance = 35;
};
//--------------------------------------------------------------------------
// Sounds
//--------------------------------------
datablock AudioProfile(TR2GrenadeSwitchSound)
{
filename = "fx/weapons/generic_switch.wav";
description = AudioClosest3d;
preload = true;
effect = TR2GrenadeSwitchEffect;
};
datablock AudioProfile(TR2GrenadeFireSound)
{
filename = "fx/weapons/grenadelauncher_fire.wav";
description = AudioDefault3d;
preload = true;
effect = TR2GrenadeFireEffect;
};
datablock AudioProfile(TR2GrenadeProjectileSound)
{
filename = "fx/weapons/grenadelauncher_projectile.wav";
description = ProjectileLooping3d;
preload = true;
};
datablock AudioProfile(TR2GrenadeReloadSound)
{
filename = "fx/weapons/generic_switch.wav";
description = AudioClosest3d;
preload = true;
effect = TR2GrenadeReloadEffect;
};
datablock AudioProfile(TR2GrenadeExplosionSound)
{
filename = "fx/weapons/grenade_explode.wav";
description = AudioExplosion3d;
preload = true;
effect = TR2GrenadeExplosionEffect;
};
datablock AudioProfile(UnderwaterTR2GrenadeExplosionSound)
{
filename = "fx/weapons/grenade_explode_UW.wav";
description = AudioExplosion3d;
preload = true;
effect = TR2GrenadeExplosionEffect;
};
datablock AudioProfile(TR2GrenadeDryFireSound)
{
filename = "fx/weapons/grenadelauncher_dryfire.wav";
description = AudioClose3d;
preload = true;
effect = TR2GrenadeDryFireEffect;
};
//----------------------------------------------------------------------------
// Underwater fx
//----------------------------------------------------------------------------
datablock ParticleData(TR2GrenadeExplosionBubbleParticle)
{
dragCoefficient = 0.0;
gravityCoefficient = -0.25;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 1500;
lifetimeVarianceMS = 600;
useInvAlpha = false;
textureName = "special/bubbles";
spinRandomMin = -100.0;
spinRandomMax = 100.0;
colors[0] = "0.7 0.8 1.0 0.0";
colors[1] = "0.7 0.8 1.0 0.4";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 1.0;
sizes[1] = 1.0;
sizes[2] = 1.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2GrenadeExplosionBubbleEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 1.0;
ejectionOffset = 3.0;
velocityVariance = 0.5;
thetaMin = 0;
thetaMax = 80;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
particles = "TR2GrenadeExplosionBubbleParticle";
};
datablock ParticleData(UnderwaterTR2GrenadeDust)
{
dragCoefficient = 1.0;
gravityCoefficient = -0.01;
inheritedVelFactor = 0.0;
constantAcceleration = -1.1;
lifetimeMS = 1000;
lifetimeVarianceMS = 100;
useInvAlpha = false;
spinRandomMin = -90.0;
spinRandomMax = 500.0;
textureName = "particleTest";
colors[0] = "0.6 0.6 1.0 0.5";
colors[1] = "0.6 0.6 1.0 0.5";
colors[2] = "0.6 0.6 1.0 0.0";
sizes[0] = 3.0;
sizes[1] = 3.0;
sizes[2] = 3.0;
times[0] = 0.0;
times[1] = 0.7;
times[2] = 1.0;
};
datablock ParticleEmitterData(UnderwaterTR2GrenadeDustEmitter)
{
ejectionPeriodMS = 15;
periodVarianceMS = 0;
ejectionVelocity = 15.0;
velocityVariance = 0.0;
ejectionOffset = 0.0;
thetaMin = 70;
thetaMax = 70;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
lifetimeMS = 250;
particles = "UnderwaterTR2GrenadeDust";
};
datablock ParticleData(UnderwaterTR2GrenadeExplosionSmoke)
{
dragCoeffiecient = 0.4;
gravityCoefficient = -0.25; // rises slowly
inheritedVelFactor = 0.025;
constantAcceleration = -1.1;
lifetimeMS = 1250;
lifetimeVarianceMS = 0;
textureName = "particleTest";
useInvAlpha = false;
spinRandomMin = -200.0;
spinRandomMax = 200.0;
textureName = "special/Smoke/smoke_001";
colors[0] = "0.1 0.1 1.0 1.0";
colors[1] = "0.4 0.4 1.0 1.0";
colors[2] = "0.4 0.4 1.0 0.0";
sizes[0] = 2.0;
sizes[1] = 6.0;
sizes[2] = 2.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(UnderwaterTR2GExplosionSmokeEmitter)
{
ejectionPeriodMS = 15;
periodVarianceMS = 0;
ejectionVelocity = 6.25;
velocityVariance = 0.25;
thetaMin = 0.0;
thetaMax = 90.0;
lifetimeMS = 250;
particles = "UnderwaterTR2GrenadeExplosionSmoke";
};
datablock ParticleData(UnderwaterTR2GrenadeSparks)
{
dragCoefficient = 1;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = 0.0;
lifetimeMS = 500;
lifetimeVarianceMS = 350;
textureName = "special/underwaterSpark";
colors[0] = "0.6 0.6 1.0 1.0";
colors[1] = "0.6 0.6 1.0 1.0";
colors[2] = "0.6 0.6 1.0 0.0";
sizes[0] = 0.5;
sizes[1] = 0.5;
sizes[2] = 0.75;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(UnderwaterTR2GrenadeSparksEmitter)
{
ejectionPeriodMS = 2;
periodVarianceMS = 0;
ejectionVelocity = 12;
velocityVariance = 6.75;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 60;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 100;
particles = "UnderwaterTR2GrenadeSparks";
};
datablock ExplosionData(UnderwaterTR2GrenadeExplosion)
{
soundProfile = UnderwaterTR2GrenadeExplosionSound;
faceViewer = true;
explosionScale = "0.8 0.8 0.8";
emitter[0] = UnderwaterTR2GrenadeDustEmitter;
emitter[1] = UnderwaterTR2GExplosionSmokeEmitter;
emitter[2] = UnderwaterTR2GrenadeSparksEmitter;
emitter[3] = TR2GrenadeExplosionBubbleEmitter;
shakeCamera = true;
camShakeFreq = "10.0 6.0 9.0";
camShakeAmp = "20.0 20.0 20.0";
camShakeDuration = 0.5;
camShakeRadius = 20.0;
};
//----------------------------------------------------------------------------
// Bubbles
//----------------------------------------------------------------------------
datablock ParticleData(TR2GrenadeBubbleParticle)
{
dragCoefficient = 0.0;
gravityCoefficient = -0.25;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 1500;
lifetimeVarianceMS = 600;
useInvAlpha = false;
textureName = "special/bubbles";
spinRandomMin = -100.0;
spinRandomMax = 100.0;
colors[0] = "0.7 0.8 1.0 0.4";
colors[1] = "0.7 0.8 1.0 0.4";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 0.5;
sizes[1] = 0.5;
sizes[2] = 0.5;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2GrenadeBubbleEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 1.0;
ejectionOffset = 0.1;
velocityVariance = 0.5;
thetaMin = 0;
thetaMax = 80;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
particles = "TR2GrenadeBubbleParticle";
};
//----------------------------------------------------------------------------
// Debris
//----------------------------------------------------------------------------
datablock ParticleData( TR2GDebrisSmokeParticle )
{
dragCoeffiecient = 1.0;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
lifetimeMS = 1000;
lifetimeVarianceMS = 100;
textureName = "particleTest";
useInvAlpha = true;
spinRandomMin = -60.0;
spinRandomMax = 60.0;
colors[0] = "0.4 0.4 0.4 1.0";
colors[1] = "0.3 0.3 0.3 0.5";
colors[2] = "0.0 0.0 0.0 0.0";
sizes[0] = 0.0;
sizes[1] = 1.0;
sizes[2] = 1.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData( TR2GDebrisSmokeEmitter )
{
ejectionPeriodMS = 7;
periodVarianceMS = 1;
ejectionVelocity = 1.0; // A little oomph at the back end
velocityVariance = 0.2;
thetaMin = 0.0;
thetaMax = 40.0;
particles = "TR2GDebrisSmokeParticle";
};
datablock DebrisData( TR2GrenadeDebris )
{
emitters[0] = TR2GDebrisSmokeEmitter;
explodeOnMaxBounce = true;
elasticity = 0.4;
friction = 0.2;
lifetime = 0.3;
lifetimeVariance = 0.02;
numBounces = 1;
};
//--------------------------------------------------------------------------
// Splash
//--------------------------------------------------------------------------
datablock ParticleData( TR2GrenadeSplashParticle )
{
dragCoefficient = 1;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = -1.4;
lifetimeMS = 300;
lifetimeVarianceMS = 0;
textureName = "special/droplet";
colors[0] = "0.7 0.8 1.0 1.0";
colors[1] = "0.7 0.8 1.0 0.5";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 0.05;
sizes[1] = 0.2;
sizes[2] = 0.2;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData( TR2GrenadeSplashEmitter )
{
ejectionPeriodMS = 4;
periodVarianceMS = 0;
ejectionVelocity = 4;
velocityVariance = 1.0;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 50;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 100;
particles = "BlasterSplashParticle";
};
datablock SplashData(TR2GrenadeSplash)
{
numSegments = 15;
ejectionFreq = 15;
ejectionAngle = 40;
ringLifetime = 0.35;
lifetimeMS = 300;
velocity = 3.0;
startRadius = 0.0;
acceleration = -3.0;
texWrap = 5.0;
texture = "special/water2";
emitter[0] = BlasterSplashEmitter;
colors[0] = "0.7 0.8 1.0 1.0";
colors[1] = "0.7 0.8 1.0 1.0";
colors[2] = "0.7 0.8 1.0 1.0";
colors[3] = "0.7 0.8 1.0 1.0";
times[0] = 0.0;
times[1] = 0.4;
times[2] = 0.8;
times[3] = 1.0;
};
//--------------------------------------------------------------------------
// Particle effects
//--------------------------------------
datablock ParticleData(TR2GrenadeSmokeParticle)
{
dragCoeffiecient = 0.0;
gravityCoefficient = -0.2; // rises slowly
inheritedVelFactor = 0.00;
lifetimeMS = 700; // lasts 2 second
lifetimeVarianceMS = 150; // ...more or less
textureName = "particleTest";
useInvAlpha = true;
spinRandomMin = -30.0;
spinRandomMax = 30.0;
// TR2: white
colors[0] = "1.0 1.0 1.0 1.0";
colors[1] = "0.95 0.95 0.95 1.0";
colors[2] = "0.9 0.9 0.9 0.0";
sizes[0] = 0.7;//0.25;
sizes[1] = 2.4;//1.0;
sizes[2] = 7.0;//3.0;
times[0] = 0.0;
times[1] = 0.2;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2GrenadeSmokeEmitter)
{
ejectionPeriodMS = 15;
periodVarianceMS = 5;
ejectionVelocity = 1.25;
velocityVariance = 0.50;
thetaMin = 0.0;
thetaMax = 90.0;
particles = "TR2GrenadeSmokeParticle";
};
datablock ParticleData(TR2GrenadeDust)
{
dragCoefficient = 1.0;
gravityCoefficient = -0.01;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 1000;
lifetimeVarianceMS = 100;
useInvAlpha = true;
spinRandomMin = -90.0;
spinRandomMax = 500.0;
textureName = "particleTest";
colors[0] = "0.3 0.3 0.3 0.5";
colors[1] = "0.3 0.3 0.3 0.5";
colors[2] = "0.3 0.3 0.3 0.0";
sizes[0] = 7.0;//3.2;
sizes[1] = 10.0;//4.6;
sizes[2] = 11.0;//5.0;
times[0] = 0.0;
times[1] = 0.7;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2GrenadeDustEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 15.0;
velocityVariance = 0.0;
ejectionOffset = 0.0;
thetaMin = 85;
thetaMax = 85;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
lifetimeMS = 250;
particles = "TR2GrenadeDust";
};
datablock ParticleData(TR2GrenadeExplosionSmoke)
{
dragCoeffiecient = 0.4;
gravityCoefficient = -0.5; // rises slowly
inheritedVelFactor = 0.025;
lifetimeMS = 1250;
lifetimeVarianceMS = 0;
textureName = "particleTest";
useInvAlpha = true;
spinRandomMin = -200.0;
spinRandomMax = 200.0;
textureName = "special/Smoke/smoke_001";
// TR2: Red/orange
colors[0] = "0.9 0.7 0.7 1.0";
colors[1] = "0.8 0.4 0.2 1.0";
colors[2] = "0.6 0.2 0.1 0.0";
sizes[0] = 6.0;//2.0;
sizes[1] = 18.0;//6.0;
sizes[2] = 6.0;//2.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2GExplosionSmokeEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 6.25;
velocityVariance = 0.25;
thetaMin = 0.0;
thetaMax = 90.0;
lifetimeMS = 250;
particles = "TR2GrenadeExplosionSmoke";
};
datablock ParticleData(TR2GrenadeSparks)
{
dragCoefficient = 1;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = 0.0;
lifetimeMS = 500;
lifetimeVarianceMS = 350;
textureName = "special/bigspark";
colors[0] = "0.56 0.36 0.26 1.0";
colors[1] = "0.56 0.36 0.26 1.0";
colors[2] = "1.0 0.36 0.26 0.0";
sizes[0] = 9.0;//0.5;
sizes[1] = 9.0;//0.5;
sizes[2] = 12.0;//0.75;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2GrenadeSparksEmitter)
{
ejectionPeriodMS = 2;
periodVarianceMS = 0;
ejectionVelocity = 12;
velocityVariance = 6.75;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 60;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 100;
particles = "TR2GrenadeSparks";
};
//----------------------------------------------------
// Explosion
//----------------------------------------------------
datablock ExplosionData(TR2GrenadeExplosion)
{
soundProfile = TR2GrenadeExplosionSound;
faceViewer = true;
explosionScale = "3.0 3.0 3.0";//"0.8 0.8 0.8";
debris = TR2GrenadeDebris;
debrisThetaMin = 10;
debrisThetaMax = 50;
debrisNum = 8;
debrisVelocity = 52.0;//26.0;
debrisVelocityVariance = 14.0;//7.0;
emitter[0] = TR2GrenadeDustEmitter;
emitter[1] = TR2GExplosionSmokeEmitter;
emitter[2] = TR2GrenadeSparksEmitter;
shakeCamera = true;
camShakeFreq = "10.0 6.0 9.0";
camShakeAmp = "20.0 20.0 20.0";
camShakeDuration = 0.5;
camShakeRadius = 20.0;
};
//--------------------------------------------------------------------------
// Projectile
//--------------------------------------
datablock GrenadeProjectileData(BasicTR2Grenade)
{
projectileShapeName = "grenade_projectile.dts";
emitterDelay = -1;
directDamage = 0.0;
hasDamageRadius = true;
indirectDamage = 0.40;
damageRadius = 27;//20.0;
radiusDamageType = $DamageType::Grenade;
kickBackStrength = 7200;//1500;
bubbleEmitTime = 1.0;
sound = TR2GrenadeProjectileSound;
explosion = "TR2GrenadeExplosion";
underwaterExplosion = "UnderwaterTR2GrenadeExplosion";
velInheritFactor = 0.62;//0.7;//0.5;
splash = TR2GrenadeSplash;
baseEmitter = TR2GrenadeSmokeEmitter;
bubbleEmitter = TR2GrenadeBubbleEmitter;
grenadeElasticity = 0.15;//0.25;//0.35;
grenadeFriction = 0.09;//0.2;//0.2;
armingDelayMS = 1000;
muzzleVelocity = 165;//78;//47.00;
drag = 0.09;//0.15;//0.1;
gravityMod = 2.75;
};
//--------------------------------------------------------------------------
// Ammo
//--------------------------------------
datablock ItemData(TR2GrenadeLauncherAmmo)
{
className = Ammo;
catagory = "Ammo";
shapeFile = "ammo_grenade.dts";
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "some grenade launcher ammo";
computeCRC = false;
emap = true;
};
//--------------------------------------------------------------------------
// Weapon
//--------------------------------------
datablock ItemData(TR2GrenadeLauncher)
{
className = Weapon;
catagory = "Spawn Items";
shapeFile = "TR2weapon_grenade_launcher.dts";
image = TR2GrenadeLauncherImage;
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "a grenade launcher";
computeCRC = true;
};
datablock ShapeBaseImageData(TR2GrenadeLauncherImage)
{
className = WeaponImage;
shapeFile = "TR2weapon_grenade_launcher.dts";
item = TR2GrenadeLauncher;
ammo = TR2GrenadeLauncherAmmo;
offset = "0 0 0";
emap = true;
projectile = BasicTR2Grenade;
projectileType = GrenadeProjectile;
stateName[0] = "Activate";
stateTransitionOnTimeout[0] = "ActivateReady";
stateTimeoutValue[0] = 0.5;
stateSequence[0] = "Activate";
stateSound[0] = TR2GrenadeSwitchSound;
stateName[1] = "ActivateReady";
stateTransitionOnLoaded[1] = "Ready";
stateTransitionOnNoAmmo[1] = "NoAmmo";
stateName[2] = "Ready";
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "Fire";
stateName[3] = "Fire";
stateTransitionOnTimeout[3] = "Reload";
stateTimeoutValue[3] = 0.4;
stateFire[3] = true;
stateRecoil[3] = LightRecoil;
stateAllowImageChange[3] = false;
stateSequence[3] = "Fire";
stateScript[3] = "onFire";
stateSound[3] = TR2GrenadeFireSound;
stateName[4] = "Reload";
stateTransitionOnNoAmmo[4] = "NoAmmo";
stateTransitionOnTimeout[4] = "Ready";
stateTimeoutValue[4] = 0.5;
stateAllowImageChange[4] = false;
stateSequence[4] = "Reload";
stateSound[4] = TR2GrenadeReloadSound;
stateName[5] = "NoAmmo";
stateTransitionOnAmmo[5] = "Reload";
stateSequence[5] = "NoAmmo";
stateTransitionOnTriggerDown[5] = "DryFire";
stateName[6] = "DryFire";
stateSound[6] = TR2GrenadeDryFireSound;
stateTimeoutValue[6] = 1.5;
stateTransitionOnTimeout[6] = "NoAmmo";
};

View file

@ -0,0 +1,799 @@
//--------------------------------------
// Mortar
//--------------------------------------
//--------------------------------------------------------------------------
// Force-Feedback Effects
//--------------------------------------
datablock EffectProfile(TR2MortarSwitchEffect)
{
effectname = "weapons/mortar_activate";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2MortarFireEffect)
{
effectname = "weapons/mortar_fire";
minDistance = 2.5;
maxDistance = 5.0;
};
datablock EffectProfile(TR2MortarReloadEffect)
{
effectname = "weapons/mortar_reload";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2MortarDryFireEffect)
{
effectname = "weapons/mortar_dryfire";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2MortarExplosionEffect)
{
effectname = "explosions/explosion.xpl03";
minDistance = 30;
maxDistance = 65;
};
//--------------------------------------------------------------------------
// Sounds
//--------------------------------------
datablock AudioProfile(TR2MortarSwitchSound)
{
filename = "fx/weapons/mortar_activate.wav";
description = AudioClosest3d;
preload = true;
effect = TR2MortarSwitchEffect;
};
datablock AudioProfile(TR2MortarReloadSound)
{
filename = "fx/weapons/mortar_reload.wav";
description = AudioClosest3d;
preload = true;
effect = TR2MortarReloadEffect;
};
// DELETE IF NOT NEEDED
//datablock AudioProfile(TR2MortarIdleSound)
//{
// filename = "fx/weapons/weapon.mortarIdle.wav";
// description = ClosestLooping3d;
// preload = true;
//};
datablock AudioProfile(TR2MortarFireSound)
{
filename = "fx/weapons/mortar_fire.wav";
description = AudioDefault3d;
preload = true;
effect = TR2MortarFireEffect;
};
datablock AudioProfile(TR2MortarProjectileSound)
{
filename = "fx/weapons/mortar_projectile.wav";
description = ProjectileLooping3d;
preload = true;
};
datablock AudioProfile(TR2MortarExplosionSound)
{
filename = "fx/weapons/mortar_explode.wav";
description = AudioBIGExplosion3d;
preload = true;
effect = TR2MortarExplosionEffect;
};
datablock AudioProfile(UnderwaterTR2MortarExplosionSound)
{
filename = "fx/weapons/mortar_explode_UW.wav";
description = AudioBIGExplosion3d;
preload = true;
effect = TR2MortarExplosionEffect;
};
datablock AudioProfile(TR2MortarDryFireSound)
{
filename = "fx/weapons/mortar_dryfire.wav";
description = AudioClose3d;
preload = true;
effect = TR2MortarDryFireEffect;
};
//----------------------------------------------------------------------------
// Bubbles
//----------------------------------------------------------------------------
datablock ParticleData(TR2MortarBubbleParticle)
{
dragCoefficient = 0.0;
gravityCoefficient = -0.25;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 1500;
lifetimeVarianceMS = 600;
useInvAlpha = false;
textureName = "special/bubbles";
spinRandomMin = -100.0;
spinRandomMax = 100.0;
colors[0] = "0.7 0.8 1.0 0.4";
colors[1] = "0.7 0.8 1.0 0.4";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 0.8;
sizes[1] = 0.8;
sizes[2] = 0.8;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2MortarBubbleEmitter)
{
ejectionPeriodMS = 9;
periodVarianceMS = 0;
ejectionVelocity = 1.0;
ejectionOffset = 0.1;
velocityVariance = 0.5;
thetaMin = 0;
thetaMax = 80;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
particles = "TR2MortarBubbleParticle";
};
//--------------------------------------------------------------------------
// Splash
//--------------------------------------------------------------------------
datablock ParticleData( TR2MortarSplashParticle )
{
dragCoefficient = 1;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = -1.4;
lifetimeMS = 300;
lifetimeVarianceMS = 0;
textureName = "special/droplet";
colors[0] = "0.7 0.8 1.0 1.0";
colors[1] = "0.7 0.8 1.0 0.5";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 0.05;
sizes[1] = 0.2;
sizes[2] = 0.2;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData( TR2MortarSplashEmitter )
{
ejectionPeriodMS = 4;
periodVarianceMS = 0;
ejectionVelocity = 3;
velocityVariance = 1.0;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 50;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 100;
particles = "TR2MortarSplashParticle";
};
datablock SplashData(TR2MortarSplash)
{
numSegments = 10;
ejectionFreq = 10;
ejectionAngle = 20;
ringLifetime = 0.4;
lifetimeMS = 400;
velocity = 3.0;
startRadius = 0.0;
acceleration = -3.0;
texWrap = 5.0;
texture = "special/water2";
emitter[0] = TR2MortarSplashEmitter;
colors[0] = "0.7 0.8 1.0 0.0";
colors[1] = "0.7 0.8 1.0 1.0";
colors[2] = "0.7 0.8 1.0 0.0";
colors[3] = "0.7 0.8 1.0 0.0";
times[0] = 0.0;
times[1] = 0.4;
times[2] = 0.8;
times[3] = 1.0;
};
//---------------------------------------------------------------------------
// Mortar Shockwaves
//---------------------------------------------------------------------------
datablock ShockwaveData(UnderwaterTR2MortarShockwave)
{
width = 6.0;
numSegments = 32;
numVertSegments = 6;
velocity = 10;
acceleration = 20.0;
lifetimeMS = 900;
height = 1.0;
verticalCurve = 0.5;
is2D = false;
texture[0] = "special/shockwave4";
texture[1] = "special/gradient";
texWrap = 6.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
colors[0] = "0.4 0.4 1.0 0.50";
colors[1] = "0.4 0.4 1.0 0.25";
colors[2] = "0.4 0.4 1.0 0.0";
mapToTerrain = true;
orientToNormal = false;
renderBottom = false;
};
datablock ShockwaveData(TR2MortarShockwave)
{
width = 6.0;
numSegments = 32;
numVertSegments = 6;
velocity = 30;
acceleration = 20.0;
lifetimeMS = 500;
height = 1.0;
verticalCurve = 0.5;
is2D = false;
texture[0] = "special/shockwave4";
texture[1] = "special/gradient";
texWrap = 6.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
colors[0] = "0.4 1.0 0.4 0.50";
colors[1] = "0.4 1.0 0.4 0.25";
colors[2] = "0.4 1.0 0.4 0.0";
mapToTerrain = true;
orientToNormal = false;
renderBottom = false;
};
//--------------------------------------------------------------------------
// Mortar Explosion Particle effects
//--------------------------------------
datablock ParticleData( TR2MortarCrescentParticle )
{
dragCoefficient = 2;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = -0.0;
lifetimeMS = 600;
lifetimeVarianceMS = 000;
textureName = "special/crescent3";
colors[0] = "0.7 1.0 0.7 1.0";
colors[1] = "0.7 1.0 0.7 0.5";
colors[2] = "0.7 1.0 0.7 0.0";
sizes[0] = 8.0;
sizes[1] = 16.0;
sizes[2] = 18.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData( TR2MortarCrescentEmitter )
{
ejectionPeriodMS = 25;
periodVarianceMS = 0;
ejectionVelocity = 40;
velocityVariance = 5.0;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 80;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 200;
particles = "TR2MortarCrescentParticle";
};
datablock ParticleData(TR2MortarExplosionSmoke)
{
dragCoeffiecient = 0.4;
gravityCoefficient = -0.30; // rises slowly
inheritedVelFactor = 0.025;
lifetimeMS = 1250;
lifetimeVarianceMS = 500;
textureName = "particleTest";
useInvAlpha = true;
spinRandomMin = -100.0;
spinRandomMax = 100.0;
textureName = "special/Smoke/bigSmoke";
colors[0] = "0.7 0.7 0.7 0.0";
colors[1] = "0.4 0.4 0.4 0.5";
colors[2] = "0.4 0.4 0.4 0.5";
colors[3] = "0.4 0.4 0.4 0.0";
sizes[0] = 25.0;
sizes[1] = 28.0;
sizes[2] = 40.0;
sizes[3] = 56.0;
times[0] = 0.0;
times[1] = 0.333;
times[2] = 0.666;
times[3] = 1.0;
};
datablock ParticleEmitterData(TR2MortarExplosionSmokeEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionOffset = 8.0;
ejectionVelocity = 7.0;//3.25;
velocityVariance = 1.2;
thetaMin = 0.0;
thetaMax = 90.0;
lifetimeMS = 500;
particles = "TR2MortarExplosionSmoke";
};
//---------------------------------------------------------------------------
// Underwater Explosion
//---------------------------------------------------------------------------
datablock ParticleData(TR2UnderwaterExplosionSparks)
{
dragCoefficient = 0;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = 0.0;
lifetimeMS = 500;
lifetimeVarianceMS = 350;
textureName = "special/crescent3";
colors[0] = "0.4 0.4 1.0 1.0";
colors[1] = "0.4 0.4 1.0 1.0";
colors[2] = "0.4 0.4 1.0 0.0";
sizes[0] = 3.5;
sizes[1] = 3.5;
sizes[2] = 3.5;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2UnderwaterExplosionSparksEmitter)
{
ejectionPeriodMS = 2;
periodVarianceMS = 0;
ejectionVelocity = 17;
velocityVariance = 4;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 60;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 100;
particles = "TR2UnderwaterExplosionSparks";
};
datablock ParticleData(TR2MortarExplosionBubbleParticle)
{
dragCoefficient = 0.0;
gravityCoefficient = -0.25;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 1500;
lifetimeVarianceMS = 600;
useInvAlpha = false;
textureName = "special/bubbles";
spinRandomMin = -100.0;
spinRandomMax = 100.0;
colors[0] = "0.7 0.8 1.0 0.0";
colors[1] = "0.7 0.8 1.0 0.4";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 2.0;
sizes[1] = 2.0;
sizes[2] = 2.0;
times[0] = 0.0;
times[1] = 0.8;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2MortarExplosionBubbleEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 1.0;
ejectionOffset = 7.0;
velocityVariance = 0.5;
thetaMin = 0;
thetaMax = 80;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
particles = "TR2MortarExplosionBubbleParticle";
};
datablock DebrisData( UnderwaterTR2MortarDebris )
{
emitters[0] = MortarExplosionBubbleEmitter;
explodeOnMaxBounce = true;
elasticity = 0.4;
friction = 0.2;
lifetime = 1.5;
lifetimeVariance = 0.2;
numBounces = 1;
};
datablock ExplosionData(UnderwaterTR2MortarSubExplosion1)
{
explosionShape = "disc_explosion.dts";
faceViewer = true;
delayMS = 100;
offset = 3.0;
playSpeed = 1.5;
sizes[0] = "3.25 3.25 3.25";//"0.75 0.75 0.75";
sizes[1] = "2.5 2.5 2.5";//"1.0 1.0 1.0";
sizes[2] = "1.5 1.5 1.5";//"0.5 0.5 0.5";
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ExplosionData(UnderwaterTR2MortarSubExplosion2)
{
explosionShape = "disc_explosion.dts";
faceViewer = true;
delayMS = 50;
offset = 3.0;
playSpeed = 0.75;
sizes[0] = "4.5 4.5 4.5";//"1.5 1.5 1.5";
sizes[1] = "4.5 4.5 4.5";//"1.5 1.5 1.5";
sizes[2] = "3.5 3.5 3.5";//"1.0 1.0 1.0";
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ExplosionData(UnderwaterTR2MortarSubExplosion3)
{
explosionShape = "disc_explosion.dts";
faceViewer = true;
delayMS = 0;
offset = 0.0;
playSpeed = 0.5;
sizes[0] = "1.0 1.0 1.0";
sizes[1] = "2.0 2.0 2.0";
sizes[2] = "1.5 1.5 1.5";
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ExplosionData(UnderwaterTR2MortarExplosion)
{
soundProfile = UnderwaterTR2MortarExplosionSound;
shockwave = UnderwaterTR2MortarShockwave;
shockwaveOnTerrain = true;
subExplosion[0] = UnderwaterTR2MortarSubExplosion1;
subExplosion[1] = UnderwaterTR2MortarSubExplosion2;
subExplosion[2] = UnderwaterTR2MortarSubExplosion3;
emitter[0] = TR2MortarExplosionBubbleEmitter;
emitter[1] = TR2UnderwaterExplosionSparksEmitter;
shakeCamera = true;
camShakeFreq = "8.0 9.0 7.0";
camShakeAmp = "100.0 100.0 100.0";
camShakeDuration = 1.3;
camShakeRadius = 25.0;
};
//---------------------------------------------------------------------------
// Explosion
//---------------------------------------------------------------------------
datablock ExplosionData(TR2MortarSubExplosion1)
{
explosionShape = "mortar_explosion.dts";
faceViewer = true;
delayMS = 100;
offset = 5.0;
playSpeed = 1.5;
sizes[0] = "8.0 8.0 8.0";//"1.5 1.5 1.5";
sizes[1] = "8.0 8.0 8.0";//"1.5 1.5 1.5";
times[0] = 0.0;
times[1] = 1.0;
};
datablock ExplosionData(TR2MortarSubExplosion2)
{
explosionShape = "mortar_explosion.dts";
faceViewer = true;
delayMS = 50;
offset = 5.0;
playSpeed = 1.0;
sizes[0] = "12.0 12.0 12.0";//"3.0 3.0 3.0";
sizes[1] = "12.0 12.0 12.0";//"3.0 3.0 3.0";
times[0] = 0.0;
times[1] = 1.0;
};
datablock ExplosionData(TR2MortarSubExplosion3)
{
explosionShape = "mortar_explosion.dts";
faceViewer = true;
delayMS = 0;
offset = 0.0;
playSpeed = 0.7;
sizes[0] = "24.0 24.0 24.0";//"3.0 3.0 3.0";
sizes[1] = "48.0 48.0 48.0";//"6.0 6.0 6.0";
times[0] = 0.0;
times[1] = 1.0;
};
datablock ExplosionData(TR2MortarExplosion)
{
soundProfile = TR2MortarExplosionSound;
shockwave = MortarShockwave;
shockwaveOnTerrain = true;
subExplosion[0] = TR2MortarSubExplosion1;
subExplosion[1] = TR2MortarSubExplosion2;
subExplosion[2] = TR2MortarSubExplosion3;
emitter[0] = TR2MortarExplosionSmokeEmitter;
emitter[1] = TR2MortarCrescentEmitter;
shakeCamera = true;
camShakeFreq = "8.0 9.0 7.0";
camShakeAmp = "100.0 100.0 100.0";
camShakeDuration = 1.3;
camShakeRadius = 40.0;//25.0;
};
//---------------------------------------------------------------------------
// Smoke particles
//---------------------------------------------------------------------------
datablock ParticleData(TR2MortarSmokeParticle)
{
dragCoeffiecient = 0.4;
gravityCoefficient = -0.3; // rises slowly
inheritedVelFactor = 0.125;
lifetimeMS = 1200;
lifetimeVarianceMS = 200;
useInvAlpha = true;
spinRandomMin = -100.0;
spinRandomMax = 100.0;
animateTexture = false;
textureName = "special/Smoke/bigSmoke";
colors[0] = "0.7 1.0 0.7 0.5";
colors[1] = "0.3 0.7 0.3 0.8";
colors[2] = "0.0 0.0 0.0 0.0";
sizes[0] = 4.0;//2.0;
sizes[1] = 8.0;//4.0;
sizes[2] = 17.0;//8.5;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2MortarSmokeEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 3;
ejectionVelocity = 4.0;//2.25;
velocityVariance = 0.55;
thetaMin = 0.0;
thetaMax = 40.0;
particles = "TR2MortarSmokeParticle";
};
//--------------------------------------------------------------------------
// Projectile
//--------------------------------------
datablock GrenadeProjectileData(TR2MortarShot)
{
projectileShapeName = "mortar_projectile.dts";
emitterDelay = -1;
directDamage = 0.0;
hasDamageRadius = true;
indirectDamage = 0.2;
damageRadius = 50.0;
radiusDamageType = $DamageType::Mortar;
kickBackStrength = 9500;
explosion = "MortarExplosion";
underwaterExplosion = "UnderwaterMortarExplosion";
velInheritFactor = 0.5;
splash = TR2MortarSplash;
depthTolerance = 10.0; // depth at which it uses underwater explosion
baseEmitter = TR2MortarSmokeEmitter;
bubbleEmitter = TR2MortarBubbleEmitter;
grenadeElasticity = 0.15;
grenadeFriction = 0.4;
armingDelayMS = 1200;//2000;
muzzleVelocity = 120.0;//63.7;
drag = 0.1;
gravityMod = 1.5;
sound = TR2MortarProjectileSound;
hasLight = true;
lightRadius = 4;
lightColor = "0.05 0.2 0.05";
hasLightUnderwaterColor = true;
underWaterLightColor = "0.05 0.075 0.2";
};
//--------------------------------------------------------------------------
// Ammo
//--------------------------------------
datablock ItemData(TR2MortarAmmo)
{
className = Ammo;
catagory = "Ammo";
shapeFile = "ammo_mortar.dts";
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "some mortar ammo";
computeCRC = false;
};
//--------------------------------------------------------------------------
// Weapon
//--------------------------------------
datablock ItemData(TR2Mortar)
{
className = Weapon;
catagory = "Spawn Items";
shapeFile = "TR2weapon_mortar.dts";
image = TR2MortarImage;
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "a mortar gun";
computeCRC = true;
emap = true;
};
datablock ShapeBaseImageData(TR2MortarImage)
{
className = WeaponImage;
shapeFile = "TR2weapon_mortar.dts";
item = TR2Mortar;
ammo = TR2MortarAmmo;
offset = "0 0 0";
emap = true;
projectile = TR2MortarShot;
projectileType = GrenadeProjectile;
stateName[0] = "Activate";
stateTransitionOnTimeout[0] = "ActivateReady";
stateTimeoutValue[0] = 0.5;
stateSequence[0] = "Activate";
stateSound[0] = TR2MortarSwitchSound;
stateName[1] = "ActivateReady";
stateTransitionOnLoaded[1] = "Ready";
stateTransitionOnNoAmmo[1] = "NoAmmo";
stateName[2] = "Ready";
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "Fire";
//stateSound[2] = MortarIdleSound;
stateName[3] = "Fire";
stateSequence[3] = "Recoil";
stateTransitionOnTimeout[3] = "Reload";
stateTimeoutValue[3] = 0.8;
stateFire[3] = true;
stateRecoil[3] = LightRecoil;
stateAllowImageChange[3] = false;
stateScript[3] = "onFire";
stateSound[3] = TR2MortarFireSound;
stateName[4] = "Reload";
stateTransitionOnNoAmmo[4] = "NoAmmo";
stateTransitionOnTimeout[4] = "Ready";
stateTimeoutValue[4] = 2.0;
stateAllowImageChange[4] = false;
stateSequence[4] = "Reload";
stateSound[4] = TR2MortarReloadSound;
stateName[5] = "NoAmmo";
stateTransitionOnAmmo[5] = "Reload";
stateSequence[5] = "NoAmmo";
stateTransitionOnTriggerDown[5] = "DryFire";
stateName[6] = "DryFire";
stateSound[6] = TR2MortarDryFireSound;
stateTimeoutValue[6] = 1.5;
stateTransitionOnTimeout[6] = "NoAmmo";
};

View file

@ -0,0 +1,297 @@
//--------------------------------------------------------------------------
// Shock Lance
//
//
//--------------------------------------------------------------------------
datablock EffectProfile(TR2ShockLanceSwitchEffect)
{
effectname = "weapons/shocklance_activate";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2ShockLanceFireEffect)
{
effectname = "weapons/shocklance_fire";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2ShockLanceReloadEffect)
{
effectname = "weapons/shocklance_reload";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock AudioProfile(TR2ShockLanceSwitchSound)
{
filename = "fx/weapons/shocklance_activate.wav";
description = AudioClosest3d;
preload = true;
effect = ShockLanceSwitchEffect;
};
//--------------------------------------------------------------------------
// Explosion
//--------------------------------------
datablock AudioProfile(TR2ShockLanceHitSound)
{
filename = "fx/weapons/shocklance_fire.WAV";
description = AudioClose3d;
preload = true;
effect = TR2ShockLanceFireEffect;
};
datablock AudioProfile(TR2ShockLanceReloadSound)
{
filename = "fx/weapons/shocklance_reload.WAV";
description = AudioClosest3d;
preload = true;
effect = TR2ShockLanceReloadEffect;
};
datablock AudioProfile(TR2ShockLanceDryFireSound)
{
filename = "fx/weapons/shocklance_dryfire.WAV";
description = AudioClose3d;
preload = true;
effect = TR2ShockLanceReloadEffect;
};
datablock AudioProfile(TR2ShockLanceMissSound)
{
filename = "fx/weapons/shocklance_miss.WAV";
description = AudioExplosion3d;
preload = true;
};
//--------------------------------------------------------------------------
// Particle data
//--------------------------------------------------------------------------
datablock ParticleData(TR2ShockParticle)
{
dragCoeffiecient = 0.0;
gravityCoefficient = -0.0;
inheritedVelFactor = 0.0;
lifetimeMS = 1000;
lifetimeVarianceMS = 0;
textureName = "particleTest";
useInvAlpha = false;
spinRandomMin = -100.0;
spinRandomMax = 100.0;
numParts = 50;
animateTexture = true;
framesPerSec = 26;
animTexName[00] = "special/Explosion/exp_0002";
animTexName[01] = "special/Explosion/exp_0004";
animTexName[02] = "special/Explosion/exp_0006";
animTexName[03] = "special/Explosion/exp_0008";
animTexName[04] = "special/Explosion/exp_0010";
animTexName[05] = "special/Explosion/exp_0012";
animTexName[06] = "special/Explosion/exp_0014";
animTexName[07] = "special/Explosion/exp_0016";
animTexName[08] = "special/Explosion/exp_0018";
animTexName[09] = "special/Explosion/exp_0020";
animTexName[10] = "special/Explosion/exp_0022";
animTexName[11] = "special/Explosion/exp_0024";
animTexName[12] = "special/Explosion/exp_0026";
animTexName[13] = "special/Explosion/exp_0028";
animTexName[14] = "special/Explosion/exp_0030";
animTexName[15] = "special/Explosion/exp_0032";
animTexName[16] = "special/Explosion/exp_0034";
animTexName[17] = "special/Explosion/exp_0036";
animTexName[18] = "special/Explosion/exp_0038";
animTexName[19] = "special/Explosion/exp_0040";
animTexName[20] = "special/Explosion/exp_0042";
animTexName[21] = "special/Explosion/exp_0044";
animTexName[22] = "special/Explosion/exp_0046";
animTexName[23] = "special/Explosion/exp_0048";
animTexName[24] = "special/Explosion/exp_0050";
animTexName[25] = "special/Explosion/exp_0052";
colors[0] = "0.5 0.5 1.0 1.0";
colors[1] = "0.5 0.5 1.0 0.5";
colors[2] = "0.25 0.25 1.0 0.0";
sizes[0] = 0.5;
sizes[1] = 0.5;
sizes[2] = 0.5;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TR2ShockParticleEmitter)
{
ejectionPeriodMS = 1;
periodVarianceMS = 0;
ejectionVelocity = 0.25;
velocityVariance = 0.0;
thetaMin = 0.0;
thetaMax = 30.0;
particles = "TR2ShockParticle";
};
//--------------------------------------------------------------------------
// Shockwave
//--------------------------------------------------------------------------
datablock ShockwaveData( TR2ShocklanceHit )
{
width = 0.5;
numSegments = 20;
numVertSegments = 1;
velocity = 0.25;
acceleration = 1.0;
lifetimeMS = 600;
height = 0.1;
verticalCurve = 0.5;
mapToTerrain = false;
renderBottom = false;
orientToNormal = true;
texture[0] = "special/shocklanceHit";
texture[1] = "special/gradient";
texWrap = 3.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
colors[0] = "1.0 1.0 1.0 1.0";
colors[1] = "1.0 1.0 1.0 0.5";
colors[2] = "1.0 1.0 1.0 0.0";
};
//--------------------------------------
// Projectile
//--------------------------------------
datablock ShockLanceProjectileData(TR2BasicShocker)
{
directDamage = 0.1;//0.45;
radiusDamageType = $DamageType::ShockLance;
kickBackStrength = 12000;
velInheritFactor = 0;
sound = "";
zapDuration = 1.0;
impulse = 12000;//1800;
boltLength = 45;//14.0;
extension = 39;//14.0;//14.0; // script variable indicating distance you can shock people from
lightningFreq = 25.0;
lightningDensity = 3.0;
lightningAmp = 0.25;
lightningWidth = 0.05;
shockwave = TR2ShocklanceHit;
boltSpeed[0] = 2.0;
boltSpeed[1] = -0.5;
texWrap[0] = 1.5;
texWrap[1] = 1.5;
startWidth[0] = 0.3;
endWidth[0] = 0.6;
startWidth[1] = 0.3;
endWidth[1] = 0.6;
texture[0] = "special/shockLightning01";
texture[1] = "special/shockLightning02";
texture[2] = "special/shockLightning03";
texture[3] = "special/ELFBeam";
emitter[0] = TR2ShockParticleEmitter;
};
//--------------------------------------
// Rifle and item...
//--------------------------------------
datablock ItemData(TR2ShockLance)
{
className = Weapon;
catagory = "Spawn Items";
shapeFile = "TR2weapon_shocklance.dts";
image = TR2ShockLanceImage;
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "a shocklance";
computeCRC = true;
emap = true;
};
datablock ShapeBaseImageData(TR2ShockLanceImage)
{
classname = WeaponImage;
shapeFile = "TR2weapon_shocklance.dts";
item = TR2ShockLance;
offset = "0 0 0";
emap = true;
projectile = TR2BasicShocker;
usesEnergy = true;
missEnergy = 0;
hitEnergy = 15;
minEnergy = 15; // needs to change to be datablock's energy drain for a hit
stateName[0] = "Activate";
stateTransitionOnTimeout[0] = "ActivateReady";
stateSound[0] = TR2ShockLanceSwitchSound;
stateTimeoutValue[0] = 0.5;
stateSequence[0] = "Activate";
stateName[1] = "ActivateReady";
stateTransitionOnLoaded[1] = "Ready";
stateTransitionOnNoAmmo[1] = "NoAmmo";
stateName[2] = "Ready";
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "CheckWet";
stateName[3] = "Fire";
stateTransitionOnTimeout[3] = "Reload";
stateTimeoutValue[3] = 0.5;
stateFire[3] = true;
stateAllowImageChange[3] = false;
stateSequence[3] = "Fire";
stateScript[3] = "onFire";
stateSound[3] = TR2ShockLanceDryFireSound;
stateName[4] = "Reload";
stateTransitionOnNoAmmo[4] = "NoAmmo";
stateTransitionOnTimeout[4] = "Ready";
stateTimeoutValue[4] = 2.0;
stateAllowImageChange[4] = false;
stateSequence[4] = "Reload";
stateSound[4] = TR2ShockLanceReloadSound;
stateName[5] = "NoAmmo";
stateTransitionOnAmmo[5] = "Ready";
stateName[6] = "DryFire";
stateSound[6] = TR2ShockLanceDryFireSound;
stateTimeoutValue[6] = 1.0;
stateTransitionOnTimeout[6] = "Ready";
stateName[7] = "CheckWet";
stateTransitionOnWet[7] = "DryFire";
stateTransitionOnNotWet[7] = "Fire";
};

View file

@ -0,0 +1,218 @@
//--------------------------------------------------------------------------
// Targeting laser
//
//--------------------------------------------------------------------------
datablock EffectProfile(TR2TargetingLaserSwitchEffect)
{
effectname = "weapons/generic_switch";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock EffectProfile(TR2TargetingLaserPaintEffect)
{
effectname = "weapons/targetinglaser_paint";
minDistance = 2.5;
maxDistance = 2.5;
};
datablock AudioProfile(TR2TargetingLaserSwitchSound)
{
filename = "fx/weapons/generic_switch.wav";
description = AudioClosest3d;
preload = true;
effect = TargetingLaserSwitchEffect;
};
datablock AudioProfile(TR2TargetingLaserPaintSound)
{
filename = "fx/weapons/targetinglaser_paint.wav";
description = CloseLooping3d;
preload = true;
effect = TargetingLaserPaintEffect;
};
//--------------------------------------
// Projectile
//--------------------------------------
datablock TargetProjectileData(TR2BasicGoldTargeter)
{
directDamage = 0.0;
hasDamageRadius = false;
indirectDamage = 0.0;
damageRadius = 0.0;
velInheritFactor = 1.0;
maxRifleRange = 1000;
beamColor = "0.8 0.8 0.0";
startBeamWidth = 0.80;
pulseBeamWidth = 0.55;
beamFlareAngle = 3.0;
minFlareSize = 0.0;
maxFlareSize = 400.0;
pulseSpeed = 6.0;
pulseLength = 0.150;
textureName[0] = "special/nonlingradient";
textureName[1] = "special/flare";
textureName[2] = "special/pulse";
textureName[3] = "special/expFlare";
beacon = true;
};
datablock TargetProjectileData(TR2BasicSilverTargeter)
{
directDamage = 0.0;
hasDamageRadius = false;
indirectDamage = 0.0;
damageRadius = 0.0;
velInheritFactor = 1.0;
maxRifleRange = 1000;
beamColor = "0.56 0.56 0.56";
startBeamWidth = 0.80;
pulseBeamWidth = 0.55;
beamFlareAngle = 3.0;
minFlareSize = 0.0;
maxFlareSize = 400.0;
pulseSpeed = 6.0;
pulseLength = 0.150;
textureName[0] = "special/nonlingradient";
textureName[1] = "special/flare";
textureName[2] = "special/pulse";
textureName[3] = "special/expFlare";
beacon = true;
};
//--------------------------------------
// Rifle and item...
//--------------------------------------
datablock ItemData(TR2GoldTargetingLaser)
{
className = Weapon;
catagory = "Spawn Items";
shapeFile = "weapon_targeting.dts";
image = TR2GoldTargetingLaserImage;
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "a targeting laser rifle";
computeCRC = false;
};
datablock ItemData(TR2SilverTargetingLaser)
{
className = Weapon;
catagory = "Spawn Items";
shapeFile = "weapon_targeting.dts";
image = TR2SilverTargetingLaserImage;
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "a targeting laser rifle";
computeCRC = false;
};
datablock ShapeBaseImageData(TR2GoldTargetingLaserImage)
{
className = WeaponImage;
shapeFile = "weapon_targeting.dts";
item = TR2GoldTargetingLaser;
offset = "0 0 0";
projectile = TR2BasicGoldTargeter;
projectileType = TargetProjectile;
deleteLastProjectile = true;
usesEnergy = true;
minEnergy = 1;
stateName[0] = "Activate";
stateSequence[0] = "Activate";
stateSound[0] = TR2TargetingLaserSwitchSound;
stateTimeoutValue[0] = 0.5;
stateTransitionOnTimeout[0] = "ActivateReady";
stateName[1] = "ActivateReady";
stateTransitionOnAmmo[1] = "Ready";
stateTransitionOnNoAmmo[1] = "NoAmmo";
stateName[2] = "Ready";
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "Fire";
stateName[3] = "Fire";
stateEnergyDrain[3] = 0;
stateFire[3] = true;
stateAllowImageChange[3] = false;
stateScript[3] = "onFire";
stateTransitionOnTriggerUp[3] = "Deconstruction";
stateTransitionOnNoAmmo[3] = "Deconstruction";
stateSound[3] = TR2TargetingLaserPaintSound;
stateName[4] = "NoAmmo";
stateTransitionOnAmmo[4] = "Ready";
stateName[5] = "Deconstruction";
stateScript[5] = "deconstruct";
stateTransitionOnTimeout[5] = "Ready";
};
datablock ShapeBaseImageData(TR2SilverTargetingLaserImage)
{
className = WeaponImage;
shapeFile = "weapon_targeting.dts";
item = TR2SilverTargetingLaser;
offset = "0 0 0";
projectile = TR2BasicSilverTargeter;
projectileType = TargetProjectile;
deleteLastProjectile = true;
usesEnergy = true;
minEnergy = 1;
stateName[0] = "Activate";
stateSequence[0] = "Activate";
stateSound[0] = TR2TargetingLaserSwitchSound;
stateTimeoutValue[0] = 0.5;
stateTransitionOnTimeout[0] = "ActivateReady";
stateName[1] = "ActivateReady";
stateTransitionOnAmmo[1] = "Ready";
stateTransitionOnNoAmmo[1] = "NoAmmo";
stateName[2] = "Ready";
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "Fire";
stateName[3] = "Fire";
stateEnergyDrain[3] = 0;
stateFire[3] = true;
stateAllowImageChange[3] = false;
stateScript[3] = "onFire";
stateTransitionOnTriggerUp[3] = "Deconstruction";
stateTransitionOnNoAmmo[3] = "Deconstruction";
stateSound[3] = TR2TargetingLaserPaintSound;
stateName[4] = "NoAmmo";
stateTransitionOnAmmo[4] = "Ready";
stateName[5] = "Deconstruction";
stateScript[5] = "deconstruct";
stateTransitionOnTimeout[5] = "Ready";
};