add DMP2 map pack

This commit is contained in:
Brian Beck 2025-11-26 00:00:11 -08:00
parent 91111f8986
commit f8958bdb1d
1073 changed files with 118893 additions and 1 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";
};

View file

@ -0,0 +1,2 @@
# Broken Compass
A Tribes 2 map pack

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more