Initial implementation of the new Base Game Template and some starting modules.

This makes some tweaks to the engine to support this, specifically, it tweaks the hardcoded shaderpaths to defer to a pref variable, so none of the shader paths are hardcoded.

Also tweaks how post effects read in texture files, removing a bizzare filepath interpretation choice, where if the file path didn't start with "/" it forcefully appended the script's file path. This made it impossible to have images not in the same dir as the script file defining the post effect.

This was changed and the existing template's post effects tweaked for now to just add "./" to those few paths impacted, as well as the perf vars to support the non-hardcoded shader paths in the engine.
This commit is contained in:
Areloch 2017-02-24 02:40:56 -06:00
parent 5c8a82180b
commit d680dc9934
2321 changed files with 296541 additions and 85 deletions

View file

@ -0,0 +1,323 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Message Hud
//-----------------------------------------------------------------------------
// chat hud sizes in lines
$outerChatLenY[1] = 4;
$outerChatLenY[2] = 9;
$outerChatLenY[3] = 13;
// Only play sound files that are <= 5000ms in length.
$MaxMessageWavLength = 5000;
// Helper function to play a sound file if the message indicates.
// Returns starting position of wave file indicator.
function playMessageSound(%message, %voice, %pitch)
{
// Search for wav tag marker.
%wavStart = strstr(%message, "~w");
if (%wavStart == -1)
{
return -1;
}
%wav = getSubStr(%message, %wavStart + 2, 1000);
if (%voice !$= "")
{
%wavFile = "data/FPSGameplay/sound/voice/" @ %voice @ "/" @ %wav;
}
else
%wavFile = "data/FPSGameplay/sound/" @ %wav;
if (strstr(%wavFile, ".wav") != (strlen(%wavFile) - 4))
%wavFile = %wavFile @ ".wav";
// XXX This only expands to a single filepath, of course; it
// would be nice to support checking in each mod path if we
// have multiple mods active.
%wavFile = ExpandFilename(%wavFile);
%wavSource = sfxCreateSource(AudioMessage, %wavFile);
if (isObject(%wavSource))
{
%wavLengthMS = %wavSource.getDuration() * %pitch;
if (%wavLengthMS == 0)
error("** WAV file \"" @ %wavFile @ "\" is nonexistent or sound is zero-length **");
else if (%wavLengthMS <= $MaxMessageWavLength)
{
if (isObject($ClientChatHandle[%sender]))
$ClientChatHandle[%sender].delete();
$ClientChatHandle[%sender] = %wavSource;
if (%pitch != 1.0)
$ClientChatHandle[%sender].setPitch(%pitch);
$ClientChatHandle[%sender].play();
}
else
error("** WAV file \"" @ %wavFile @ "\" is too long **");
}
else
error("** Unable to load WAV file : \"" @ %wavFile @ "\" **");
return %wavStart;
}
// All messages are stored in this HudMessageVector, the actual
// MainChatHud only displays the contents of this vector.
new MessageVector(HudMessageVector);
$LastHudTarget = 0;
//-----------------------------------------------------------------------------
function onChatMessage(%message, %voice, %pitch)
{
// XXX Client objects on the server must have voiceTag and voicePitch
// fields for values to be passed in for %voice and %pitch... in
// this example mod, they don't have those fields.
// Clients are not allowed to trigger general game sounds with their
// chat messages... a voice directory MUST be specified.
if (%voice $= "") {
%voice = "default";
}
// See if there's a sound at the end of the message, and play it.
if ((%wavStart = playMessageSound(%message, %voice, %pitch)) != -1) {
// Remove the sound marker from the end of the message.
%message = getSubStr(%message, 0, %wavStart);
}
// Chat goes to the chat HUD.
if (getWordCount(%message)) {
ChatHud.addLine(%message);
}
}
function onServerMessage(%message)
{
// See if there's a sound at the end of the message, and play it.
if ((%wavStart = playMessageSound(%message)) != -1) {
// Remove the sound marker from the end of the message.
%message = getSubStr(%message, 0, %wavStart);
}
// Server messages go to the chat HUD too.
if (getWordCount(%message)) {
ChatHud.addLine(%message);
}
}
//-----------------------------------------------------------------------------
// MainChatHud methods
//-----------------------------------------------------------------------------
function MainChatHud::onWake( %this )
{
// set the chat hud to the users pref
%this.setChatHudLength( $Pref::ChatHudLength );
}
//------------------------------------------------------------------------------
function MainChatHud::setChatHudLength( %this, %length )
{
%textHeight = ChatHud.Profile.fontSize + ChatHud.lineSpacing;
if (%textHeight <= 0)
%textHeight = 12;
%lengthInPixels = $outerChatLenY[%length] * %textHeight;
%chatMargin = getWord(OuterChatHud.extent, 1) - getWord(ChatScrollHud.Extent, 1)
+ 2 * ChatScrollHud.profile.borderThickness;
OuterChatHud.setExtent(firstWord(OuterChatHud.extent), %lengthInPixels + %chatMargin);
ChatScrollHud.scrollToBottom();
ChatPageDown.setVisible(false);
}
//------------------------------------------------------------------------------
function MainChatHud::nextChatHudLen( %this )
{
%len = $pref::ChatHudLength++;
if ($pref::ChatHudLength == 4)
$pref::ChatHudLength = 1;
%this.setChatHudLength($pref::ChatHudLength);
}
//-----------------------------------------------------------------------------
// ChatHud methods
// This is the actual message vector/text control which is part of
// the MainChatHud dialog
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
function ChatHud::addLine(%this,%text)
{
//first, see if we're "scrolled up"...
%textHeight = %this.profile.fontSize + %this.lineSpacing;
if (%textHeight <= 0)
%textHeight = 12;
%scrollBox = %this.getGroup();
%chatScrollHeight = getWord(%scrollBox.extent, 1) - 2 * %scrollBox.profile.borderThickness;
%chatPosition = getWord(%this.extent, 1) - %chatScrollHeight + getWord(%this.position, 1) - %scrollBox.profile.borderThickness;
%linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5);
if (%linesToScroll > 0)
%origPosition = %this.position;
//remove old messages from the top only if scrolled down all the way
while( !chatPageDown.isVisible() && HudMessageVector.getNumLines() && (HudMessageVector.getNumLines() >= $pref::HudMessageLogSize))
{
%tag = HudMessageVector.getLineTag(0);
if(%tag != 0)
%tag.delete();
HudMessageVector.popFrontLine();
}
//add the message...
HudMessageVector.pushBackLine(%text, $LastHudTarget);
$LastHudTarget = 0;
//now that we've added the message, see if we need to reset the position
if (%linesToScroll > 0)
{
chatPageDown.setVisible(true);
%this.position = %origPosition;
}
else
chatPageDown.setVisible(false);
}
//-----------------------------------------------------------------------------
function ChatHud::pageUp(%this)
{
// Find out the text line height
%textHeight = %this.profile.fontSize + %this.lineSpacing;
if (%textHeight <= 0)
%textHeight = 12;
%scrollBox = %this.getGroup();
// Find out how many lines per page are visible
%chatScrollHeight = getWord(%scrollBox.extent, 1) - 2 * %scrollBox.profile.borderThickness;
if (%chatScrollHeight <= 0)
return;
%pageLines = mFloor(%chatScrollHeight / %textHeight) - 1; // have a 1 line overlap on pages
if (%pageLines <= 0)
%pageLines = 1;
// See how many lines we actually can scroll up:
%chatPosition = -1 * (getWord(%this.position, 1) - %scrollBox.profile.borderThickness);
%linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5);
if (%linesToScroll <= 0)
return;
if (%linesToScroll > %pageLines)
%scrollLines = %pageLines;
else
%scrollLines = %linesToScroll;
// Now set the position
%this.position = firstWord(%this.position) SPC (getWord(%this.position, 1) + (%scrollLines * %textHeight));
// Display the pageup icon
chatPageDown.setVisible(true);
}
//-----------------------------------------------------------------------------
function ChatHud::pageDown(%this)
{
// Find out the text line height
%textHeight = %this.profile.fontSize + %this.lineSpacing;
if (%textHeight <= 0)
%textHeight = 12;
%scrollBox = %this.getGroup();
// Find out how many lines per page are visible
%chatScrollHeight = getWord(%scrollBox.extent, 1) - 2 * %scrollBox.profile.borderThickness;
if (%chatScrollHeight <= 0)
return;
%pageLines = mFloor(%chatScrollHeight / %textHeight) - 1;
if (%pageLines <= 0)
%pageLines = 1;
// See how many lines we actually can scroll down:
%chatPosition = getWord(%this.extent, 1) - %chatScrollHeight + getWord(%this.position, 1) - %scrollBox.profile.borderThickness;
%linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5);
if (%linesToScroll <= 0)
return;
if (%linesToScroll > %pageLines)
%scrollLines = %pageLines;
else
%scrollLines = %linesToScroll;
// Now set the position
%this.position = firstWord(%this.position) SPC (getWord(%this.position, 1) - (%scrollLines * %textHeight));
// See if we have should (still) display the pagedown icon
if (%scrollLines < %linesToScroll)
chatPageDown.setVisible(true);
else
chatPageDown.setVisible(false);
}
//-----------------------------------------------------------------------------
// Support functions
//-----------------------------------------------------------------------------
function pageUpMessageHud()
{
ChatHud.pageUp();
}
function pageDownMessageHud()
{
ChatHud.pageDown();
}
function cycleMessageHudSize()
{
MainChatHud.nextChatHudLen();
}

View file

@ -0,0 +1,180 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Server Admin Commands
//-----------------------------------------------------------------------------
function SAD(%password)
{
if (%password !$= "")
commandToServer('SAD', %password);
}
function SADSetPassword(%password)
{
commandToServer('SADSetPassword', %password);
}
//----------------------------------------------------------------------------
// Misc server commands
//----------------------------------------------------------------------------
function clientCmdSyncClock(%time)
{
// Time update from the server, this is only sent at the start of a mission
// or when a client joins a game in progress.
}
// ----------------------------------------------------------------------------
// WeaponHUD
// ----------------------------------------------------------------------------
// Update the Ammo Counter with current ammo, if not any then hide the counter.
function clientCmdSetAmmoAmountHud(%amount, %amountInClips)
{
if (!%amount)
AmmoAmount.setVisible(false);
else
{
AmmoAmount.setVisible(true);
AmmoAmount.setText("Ammo: " @ %amount @ "/" @ %amountInClips);
}
}
// Here we update the Weapon Preview image & reticle for each weapon. We also
// update the Ammo Counter (just so we don't have to call it separately).
// Passing an empty parameter ("") hides the HUD component.
function clientCmdRefreshWeaponHUD(%amount, %preview, %ret, %zoomRet, %amountInClips)
{
if (!%amount)
AmmoAmount.setVisible(false);
else
{
AmmoAmount.setVisible(true);
AmmoAmount.setText("Ammo: " @ %amount @ "/" @ %amountInClips);
}
if (%preview $= "")
WeaponHUD.setVisible(false);//PreviewImage.setVisible(false);
else
{
WeaponHUD.setVisible(true);//PreviewImage.setVisible(true);
PreviewImage.setbitmap("data/FPSGameplay/art/gui/weaponHud/"@ detag(%preview));
}
if (%ret $= "")
Reticle.setVisible(false);
else
{
Reticle.setVisible(true);
Reticle.setbitmap("data/FPSGameplay/art/gui/weaponHud/"@ detag(%ret));
}
if (isObject(ZoomReticle))
{
if (%zoomRet $= "")
{
ZoomReticle.setBitmap("");
}
else
{
ZoomReticle.setBitmap("data/FPSGameplay/art/gui/weaponHud/"@ detag(%zoomRet));
}
}
}
//-----------------------------------------------------------------------------
// Damage Direction Indicator
//-----------------------------------------------------------------------------
function clientCmdSetDamageDirection(%direction)
{
eval("%ctrl = DamageHUD-->damage_" @ %direction @ ";");
if (isObject(%ctrl))
{
// Show the indicator, and schedule an event to hide it again
cancelAll(%ctrl);
%ctrl.setVisible(true);
%ctrl.schedule(500, setVisible, false);
}
}
//-----------------------------------------------------------------------------
// Teleporter visual effect
//-----------------------------------------------------------------------------
function clientCmdPlayTeleportEffect(%position, %effectDataBlock)
{
if (isObject(%effectDataBlock))
{
new Explosion()
{
position = %position;
dataBlock = %effectDataBlock;
};
}
}
// ----------------------------------------------------------------------------
// Vehicle Support
// ----------------------------------------------------------------------------
function clientCmdtoggleVehicleMap(%toggle)
{
if(%toggle)
{
moveMap.pop();
// clear movement
$mvForwardAction = 0;
$mvBackwardAction = 0;
vehicleMap.push();
}
else
{
vehicleMap.pop();
moveMap.push();
}
}
// ----------------------------------------------------------------------------
// Turret Support
// ----------------------------------------------------------------------------
// Call by the Turret class when a player mounts or unmounts it.
// %turret = The turret that was mounted
// %player = The player doing the mounting
// %mounted = True if the turret was mounted, false if it was unmounted
function turretMountCallback(%turret, %player, %mounted)
{
//echo ( "\c4turretMountCallback -> " @ %mounted );
if (%mounted)
{
// Push the action map
turretMap.push();
}
else
{
// Pop the action map
turretMap.pop();
}
}

View file

@ -0,0 +1,224 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
if ( isObject( moveMap ) )
moveMap.delete();
new ActionMap(moveMap);
//------------------------------------------------------------------------------
// Non-remapable binds
//------------------------------------------------------------------------------
moveMap.bind( keyboard, F2, showPlayerList );
moveMap.bind(keyboard, "ctrl h", hideHUDs);
moveMap.bind(keyboard, "alt p", doScreenShotHudless);
moveMap.bindCmd(keyboard, "escape", "", "Canvas.pushDialog(PauseMenu);");
//------------------------------------------------------------------------------
// Movement Keys
//------------------------------------------------------------------------------
moveMap.bind( keyboard, a, moveleft );
moveMap.bind( keyboard, d, moveright );
moveMap.bind( keyboard, left, moveleft );
moveMap.bind( keyboard, right, moveright );
moveMap.bind( keyboard, w, moveforward );
moveMap.bind( keyboard, s, movebackward );
moveMap.bind( keyboard, up, moveforward );
moveMap.bind( keyboard, down, movebackward );
moveMap.bind( keyboard, e, moveup );
moveMap.bind( keyboard, c, movedown );
moveMap.bind( keyboard, space, jump );
moveMap.bind( mouse, xaxis, yaw );
moveMap.bind( mouse, yaxis, pitch );
moveMap.bind( gamepad, thumbrx, "D", "-0.23 0.23", gamepadYaw );
moveMap.bind( gamepad, thumbry, "D", "-0.23 0.23", gamepadPitch );
moveMap.bind( gamepad, thumblx, "D", "-0.23 0.23", gamePadMoveX );
moveMap.bind( gamepad, thumbly, "D", "-0.23 0.23", gamePadMoveY );
moveMap.bind( gamepad, btn_a, jump );
moveMap.bindCmd( gamepad, btn_back, "disconnect();", "" );
moveMap.bindCmd(gamepad, dpadl, "toggleLightColorViz();", "");
moveMap.bindCmd(gamepad, dpadu, "toggleDepthViz();", "");
moveMap.bindCmd(gamepad, dpadd, "toggleNormalsViz();", "");
moveMap.bindCmd(gamepad, dpadr, "toggleLightSpecularViz();", "");
// ----------------------------------------------------------------------------
// Stance/pose
// ----------------------------------------------------------------------------
moveMap.bind(keyboard, lcontrol, doCrouch);
moveMap.bind(gamepad, btn_b, doCrouch);
moveMap.bind(keyboard, lshift, doSprint);
//------------------------------------------------------------------------------
// Mouse Trigger
//------------------------------------------------------------------------------
//function altTrigger(%val)
//{
//$mvTriggerCount1++;
//}
moveMap.bind( mouse, button0, mouseFire );
//moveMap.bind( mouse, button1, altTrigger );
//------------------------------------------------------------------------------
// Gamepad Trigger
//------------------------------------------------------------------------------
moveMap.bind(gamepad, triggerr, gamepadFire);
moveMap.bind(gamepad, triggerl, gamepadAltTrigger);
//------------------------------------------------------------------------------
// Zoom and FOV functions
//------------------------------------------------------------------------------
if($Player::CurrentFOV $= "")
$Player::CurrentFOV = $pref::Player::DefaultFOV / 2;
// toggleZoomFOV() works by dividing the CurrentFOV by 2. Each time that this
// toggle is hit it simply divides the CurrentFOV by 2 once again. If the
// FOV is reduced below a certain threshold then it resets to equal half of the
// DefaultFOV value. This gives us 4 zoom levels to cycle through.
moveMap.bind(keyboard, f, setZoomFOV); // f for field of view
moveMap.bind(keyboard, z, toggleZoom); // z for zoom
moveMap.bind( mouse, button1, mouseButtonZoom );
//------------------------------------------------------------------------------
// Camera & View functions
//------------------------------------------------------------------------------
moveMap.bind( keyboard, v, toggleFreeLook ); // v for vanity
moveMap.bind(keyboard, tab, toggleFirstPerson );
moveMap.bind( gamepad, btn_x, toggleFirstPerson );
// ----------------------------------------------------------------------------
// Misc. Player stuff
// ----------------------------------------------------------------------------
// Gideon does not have these animations, so the player does not need access to
// them. Commenting instead of removing so as to retain an example for those
// who will want to use a player model that has these animations and wishes to
// use them.
//moveMap.bindCmd(keyboard, "ctrl w", "commandToServer('playCel',\"wave\");", "");
//moveMap.bindCmd(keyboard, "ctrl s", "commandToServer('playCel',\"salute\");", "");
moveMap.bindCmd(keyboard, "ctrl k", "commandToServer('suicide');", "");
//------------------------------------------------------------------------------
// Item manipulation
//------------------------------------------------------------------------------
moveMap.bindCmd(keyboard, "1", "commandToServer('use',\"Ryder\");", "");
moveMap.bindCmd(keyboard, "2", "commandToServer('use',\"Lurker\");", "");
moveMap.bindCmd(keyboard, "3", "commandToServer('use',\"LurkerGrenadeLauncher\");", "");
moveMap.bindCmd(keyboard, "4", "commandToServer('use',\"ProxMine\");", "");
moveMap.bindCmd(keyboard, "5", "commandToServer('use',\"DeployableTurret\");", "");
moveMap.bindCmd(keyboard, "r", "commandToServer('reloadWeapon');", "");
moveMap.bind(keyboard, 0, unmountWeapon);
moveMap.bind(keyboard, "alt w", throwWeapon);
moveMap.bind(keyboard, "alt a", tossAmmo);
moveMap.bind(keyboard, q, nextWeapon);
moveMap.bind(keyboard, "ctrl q", prevWeapon);
moveMap.bind(mouse, "zaxis", mouseWheelWeaponCycle);
//------------------------------------------------------------------------------
// Message HUD functions
//------------------------------------------------------------------------------
moveMap.bind(keyboard, u, toggleMessageHud );
//moveMap.bind(keyboard, y, teamMessageHud );
moveMap.bind(keyboard, "pageUp", pageMessageHudUp );
moveMap.bind(keyboard, "pageDown", pageMessageHudDown );
moveMap.bind(keyboard, "p", resizeMessageHud );
//------------------------------------------------------------------------------
// Demo recording functions
//------------------------------------------------------------------------------
moveMap.bind( keyboard, F3, startRecordingDemo );
moveMap.bind( keyboard, F4, stopRecordingDemo );
//------------------------------------------------------------------------------
// Helper Functions
//------------------------------------------------------------------------------
moveMap.bind(keyboard, "F8", dropCameraAtPlayer);
moveMap.bind(keyboard, "F7", dropPlayerAtCamera);
GlobalActionMap.bind(keyboard, "ctrl F3", doProfile);
//------------------------------------------------------------------------------
// Misc.
//------------------------------------------------------------------------------
GlobalActionMap.bind(keyboard, "tilde", toggleConsole);
GlobalActionMap.bindCmd(keyboard, "alt k", "cls();","");
GlobalActionMap.bindCmd(keyboard, "alt enter", "", "Canvas.attemptFullscreenToggle();");
GlobalActionMap.bindCmd(keyboard, "F1", "", "contextHelp();");
moveMap.bindCmd(keyboard, "n", "toggleNetGraph();", "");
// ----------------------------------------------------------------------------
// Useful vehicle stuff
// ----------------------------------------------------------------------------
// Bind the keys to the carjack command
moveMap.bindCmd(keyboard, "ctrl z", "carjack();", "");
// Starting vehicle action map code
if ( isObject( vehicleMap ) )
vehicleMap.delete();
new ActionMap(vehicleMap);
//------------------------------------------------------------------------------
// Non-remapable binds
//------------------------------------------------------------------------------
vehicleMap.bindCmd(keyboard, "escape", "", "Canvas.pushDialog(PauseMenu);");
// The key command for flipping the car
vehicleMap.bindCmd(keyboard, "ctrl x", "commandToServer(\'flipCar\');", "");
vehicleMap.bind( keyboard, w, moveforward );
vehicleMap.bind( keyboard, s, movebackward );
vehicleMap.bind( keyboard, up, moveforward );
vehicleMap.bind( keyboard, down, movebackward );
vehicleMap.bind( mouse, xaxis, yaw );
vehicleMap.bind( mouse, yaxis, pitch );
vehicleMap.bind( mouse, button0, mouseFire );
vehicleMap.bind( mouse, button1, altTrigger );
vehicleMap.bindCmd(keyboard, "f","getout();","");
vehicleMap.bind(keyboard, space, brake);
vehicleMap.bindCmd(keyboard, "l", "brakeLights();", "");
vehicleMap.bind( keyboard, v, toggleFreeLook ); // v for vanity
//vehicleMap.bind(keyboard, tab, toggleFirstPerson );
// bind the left thumbstick for steering
vehicleMap.bind( gamepad, thumblx, "D", "-0.23 0.23", gamepadYaw );
// bind the gas, break, and reverse buttons
vehicleMap.bind( gamepad, btn_a, moveforward );
vehicleMap.bind( gamepad, btn_b, brake );
vehicleMap.bind( gamepad, btn_x, movebackward );
// bind exiting the vehicle to a button
vehicleMap.bindCmd(gamepad, btn_y,"getout();","");

View file

@ -0,0 +1,175 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Override base controls
//GuiMenuButtonProfile.soundButtonOver = "AudioButtonOver";
//GuiMenuButtonProfile.soundButtonDown = "AudioButtonDown";
//-----------------------------------------------------------------------------
// Chat Hud profiles
singleton GuiControlProfile (ChatHudEditProfile)
{
opaque = false;
fillColor = "255 255 255";
fillColorHL = "128 128 128";
border = false;
borderThickness = 0;
borderColor = "40 231 240";
fontColor = "40 231 240";
fontColorHL = "40 231 240";
fontColorNA = "128 128 128";
textOffset = "0 2";
autoSizeWidth = false;
autoSizeHeight = true;
tab = true;
canKeyFocus = true;
};
singleton GuiControlProfile (ChatHudTextProfile)
{
opaque = false;
fillColor = "255 255 255";
fillColorHL = "128 128 128";
border = false;
borderThickness = 0;
borderColor = "40 231 240";
fontColor = "40 231 240";
fontColorHL = "40 231 240";
fontColorNA = "128 128 128";
textOffset = "0 0";
autoSizeWidth = true;
autoSizeHeight = true;
tab = true;
canKeyFocus = true;
};
singleton GuiControlProfile ("ChatHudMessageProfile")
{
fontType = "Arial";
fontSize = 16;
fontColor = "44 172 181"; // default color (death msgs, scoring, inventory)
fontColors[1] = "4 235 105"; // client join/drop, tournament mode
fontColors[2] = "219 200 128"; // gameplay, admin/voting, pack/deployable
fontColors[3] = "77 253 95"; // team chat, spam protection message, client tasks
fontColors[4] = "40 231 240"; // global chat
fontColors[5] = "200 200 50 200"; // used in single player game
// WARNING! Colors 6-9 are reserved for name coloring
autoSizeWidth = true;
autoSizeHeight = true;
};
singleton GuiControlProfile ("ChatHudScrollProfile")
{
opaque = false;
borderThickness = 0;
borderColor = "0 255 0";
bitmap = "data/UI/art/scrollBar";
hasBitmapArray = true;
};
//-----------------------------------------------------------------------------
// Core Hud profiles
singleton GuiControlProfile ("HudScrollProfile")
{
opaque = false;
border = true;
borderColor = "0 255 0";
bitmap = "data/UI/art/scrollBar";
hasBitmapArray = true;
};
singleton GuiControlProfile ("HudTextProfile")
{
opaque = false;
fillColor = "128 128 128";
fontColor = "0 255 0";
border = true;
borderColor = "0 255 0";
};
singleton GuiControlProfile ("ChatHudBorderProfile")
{
bitmap = "data/UI/art/chatHudBorderArray";
hasBitmapArray = true;
opaque = false;
};
//-----------------------------------------------------------------------------
// Center and bottom print
singleton GuiControlProfile ("CenterPrintProfile")
{
opaque = false;
fillColor = "128 128 128";
fontColor = "0 255 0";
border = true;
borderColor = "0 255 0";
};
singleton GuiControlProfile ("CenterPrintTextProfile")
{
opaque = false;
fontType = "Arial";
fontSize = 12;
fontColor = "0 255 0";
};
// -----------------------------------------------------------------------------
// HUD text
// -----------------------------------------------------------------------------
singleton GuiControlProfile (HudTextNormalProfile)
{
opaque = false;
fontType = "Arial";
fontSize = 14;
fontColor = "255 255 255";
};
singleton GuiControlProfile (HudTextItalicProfile : HudTextNormalProfile)
{
fontType = "ArialItalic";
};
singleton GuiControlProfile (HudTextBoldProfile : HudTextNormalProfile)
{
fontType = "ArialBold";
};
// -----------------------------------------------------------------------------
// Numerical health text
// -----------------------------------------------------------------------------
singleton GuiControlProfile (NumericHealthProfile)
{
opaque = true;
justify = "center";
fontType = "ArialBold";
fontSize = 32;
fontColor = "255 255 255";
};

View file

@ -0,0 +1,533 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
function escapeFromGame()
{
disconnect();
}
function showPlayerList(%val)
{
if (%val)
PlayerListGui.toggle();
}
function hideHUDs(%val)
{
if (%val)
HudlessPlayGui.toggle();
}
function doScreenShotHudless(%val)
{
if(%val)
{
canvas.setContent(HudlessPlayGui);
//doScreenshot(%val);
schedule(10, 0, "doScreenShot", %val);
}
else
canvas.setContent(PlayGui);
}
$movementSpeed = 1; // m/s
function setSpeed(%speed)
{
if(%speed)
$movementSpeed = %speed;
}
function moveleft(%val)
{
$mvLeftAction = %val * $movementSpeed;
}
function moveright(%val)
{
$mvRightAction = %val * $movementSpeed;
}
function moveforward(%val)
{
$mvForwardAction = %val * $movementSpeed;
}
function movebackward(%val)
{
$mvBackwardAction = %val * $movementSpeed;
}
function moveup(%val)
{
%object = ServerConnection.getControlObject();
if(%object.isInNamespaceHierarchy("Camera"))
$mvUpAction = %val * $movementSpeed;
}
function movedown(%val)
{
%object = ServerConnection.getControlObject();
if(%object.isInNamespaceHierarchy("Camera"))
$mvDownAction = %val * $movementSpeed;
}
function turnLeft( %val )
{
$mvYawRightSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
}
function turnRight( %val )
{
$mvYawLeftSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
}
function panUp( %val )
{
$mvPitchDownSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
}
function panDown( %val )
{
$mvPitchUpSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
}
function getMouseAdjustAmount(%val)
{
// based on a default camera FOV of 90'
return(%val * ($cameraFov / 90) * 0.01) * $pref::Input::LinkMouseSensitivity;
}
function getGamepadAdjustAmount(%val)
{
// based on a default camera FOV of 90'
return(%val * ($cameraFov / 90) * 0.01) * 10.0;
}
function yaw(%val)
{
%yawAdj = getMouseAdjustAmount(%val);
if(ServerConnection.isControlObjectRotDampedCamera())
{
// Clamp and scale
%yawAdj = mClamp(%yawAdj, -m2Pi()+0.01, m2Pi()-0.01);
%yawAdj *= 0.5;
}
$mvYaw += %yawAdj;
}
function pitch(%val)
{
%pitchAdj = getMouseAdjustAmount(%val);
if(ServerConnection.isControlObjectRotDampedCamera())
{
// Clamp and scale
%pitchAdj = mClamp(%pitchAdj, -m2Pi()+0.01, m2Pi()-0.01);
%pitchAdj *= 0.5;
}
$mvPitch += %pitchAdj;
}
function jump(%val)
{
$mvTriggerCount2++;
}
function gamePadMoveX( %val )
{
if(%val > 0)
{
$mvRightAction = %val * $movementSpeed;
$mvLeftAction = 0;
}
else
{
$mvRightAction = 0;
$mvLeftAction = -%val * $movementSpeed;
}
}
function gamePadMoveY( %val )
{
if(%val > 0)
{
$mvForwardAction = %val * $movementSpeed;
$mvBackwardAction = 0;
}
else
{
$mvForwardAction = 0;
$mvBackwardAction = -%val * $movementSpeed;
}
}
function gamepadYaw(%val)
{
%yawAdj = getGamepadAdjustAmount(%val);
if(ServerConnection.isControlObjectRotDampedCamera())
{
// Clamp and scale
%yawAdj = mClamp(%yawAdj, -m2Pi()+0.01, m2Pi()-0.01);
%yawAdj *= 0.5;
}
if(%yawAdj > 0)
{
$mvYawLeftSpeed = %yawAdj;
$mvYawRightSpeed = 0;
}
else
{
$mvYawLeftSpeed = 0;
$mvYawRightSpeed = -%yawAdj;
}
}
function gamepadPitch(%val)
{
%pitchAdj = getGamepadAdjustAmount(%val);
if(ServerConnection.isControlObjectRotDampedCamera())
{
// Clamp and scale
%pitchAdj = mClamp(%pitchAdj, -m2Pi()+0.01, m2Pi()-0.01);
%pitchAdj *= 0.5;
}
if(%pitchAdj > 0)
{
$mvPitchDownSpeed = %pitchAdj;
$mvPitchUpSpeed = 0;
}
else
{
$mvPitchDownSpeed = 0;
$mvPitchUpSpeed = -%pitchAdj;
}
}
function doCrouch(%val)
{
$mvTriggerCount3++;
}
function doSprint(%val)
{
$mvTriggerCount5++;
}
function mouseFire(%val)
{
$mvTriggerCount0++;
}
function gamepadFire(%val)
{
if(%val > 0.1 && !$gamepadFireTriggered)
{
$gamepadFireTriggered = true;
$mvTriggerCount0++;
}
else if(%val <= 0.1 && $gamepadFireTriggered)
{
$gamepadFireTriggered = false;
$mvTriggerCount0++;
}
}
function gamepadAltTrigger(%val)
{
if(%val > 0.1 && !$gamepadAltTriggerTriggered)
{
$gamepadAltTriggerTriggered = true;
$mvTriggerCount1++;
}
else if(%val <= 0.1 && $gamepadAltTriggerTriggered)
{
$gamepadAltTriggerTriggered = false;
$mvTriggerCount1++;
}
}
function toggleZoomFOV()
{
$Player::CurrentFOV = $Player::CurrentFOV / 2;
if($Player::CurrentFOV < 5)
resetCurrentFOV();
if(ServerConnection.zoomed)
setFOV($Player::CurrentFOV);
else
{
setFov(ServerConnection.getControlCameraDefaultFov());
}
}
function resetCurrentFOV()
{
$Player::CurrentFOV = ServerConnection.getControlCameraDefaultFov() / 2;
}
function turnOffZoom()
{
ServerConnection.zoomed = false;
setFov(ServerConnection.getControlCameraDefaultFov());
Reticle.setVisible(true);
zoomReticle.setVisible(false);
// Rather than just disable the DOF effect, we want to set it to the level's
// preset values.
//DOFPostEffect.disable();
ppOptionsUpdateDOFSettings();
}
function setZoomFOV(%val)
{
if(%val)
toggleZoomFOV();
}
function toggleZoom(%val)
{
if (%val)
{
ServerConnection.zoomed = true;
setFov($Player::CurrentFOV);
Reticle.setVisible(false);
zoomReticle.setVisible(true);
DOFPostEffect.setAutoFocus( true );
DOFPostEffect.setFocusParams( 0.5, 0.5, 50, 500, -5, 5 );
DOFPostEffect.enable();
}
else
{
turnOffZoom();
}
}
function mouseButtonZoom(%val)
{
toggleZoom(%val);
}
function toggleFreeLook( %val )
{
if ( %val )
$mvFreeLook = true;
else
$mvFreeLook = false;
}
function toggleFirstPerson(%val)
{
if (%val)
{
ServerConnection.setFirstPerson(!ServerConnection.isFirstPerson());
}
}
function toggleCamera(%val)
{
if (%val)
commandToServer('ToggleCamera');
}
function unmountWeapon(%val)
{
if (%val)
commandToServer('unmountWeapon');
}
function throwWeapon(%val)
{
if (%val)
commandToServer('Throw', "Weapon");
}
function tossAmmo(%val)
{
if (%val)
commandToServer('Throw', "Ammo");
}
function nextWeapon(%val)
{
if (%val)
commandToServer('cycleWeapon', "next");
}
function prevWeapon(%val)
{
if (%val)
commandToServer('cycleWeapon', "prev");
}
function mouseWheelWeaponCycle(%val)
{
if (%val < 0)
commandToServer('cycleWeapon', "next");
else if (%val > 0)
commandToServer('cycleWeapon', "prev");
}
function pageMessageHudUp( %val )
{
if ( %val )
pageUpMessageHud();
}
function pageMessageHudDown( %val )
{
if ( %val )
pageDownMessageHud();
}
function resizeMessageHud( %val )
{
if ( %val )
cycleMessageHudSize();
}
function startRecordingDemo( %val )
{
if ( %val )
startDemoRecord();
}
function stopRecordingDemo( %val )
{
if ( %val )
stopDemoRecord();
}
function dropCameraAtPlayer(%val)
{
if (%val)
commandToServer('dropCameraAtPlayer');
}
function dropPlayerAtCamera(%val)
{
if (%val)
commandToServer('DropPlayerAtCamera');
}
function bringUpOptions(%val)
{
if (%val)
Canvas.pushDialog(OptionsDlg);
}
GlobalActionMap.bind(keyboard, "ctrl o", bringUpOptions);
//------------------------------------------------------------------------------
// Debugging Functions
//------------------------------------------------------------------------------
function showMetrics(%val)
{
if(%val)
{
if(!Canvas.isMember(FrameOverlayGui))
metrics("fps gfx shadow sfx terrain groundcover forest net");
else
metrics("");
}
}
GlobalActionMap.bind(keyboard, "ctrl F2", showMetrics);
//------------------------------------------------------------------------------
//
// Start profiler by pressing ctrl f3
// ctrl f3 - starts profile that will dump to console and file
//
function doProfile(%val)
{
if (%val)
{
// key down -- start profile
echo("Starting profile session...");
profilerReset();
profilerEnable(true);
}
else
{
// key up -- finish off profile
echo("Ending profile session...");
profilerDumpToFile("profilerDumpToFile" @ getSimTime() @ ".txt");
profilerEnable(false);
}
}
// Trace a line along the direction the crosshair is pointing
// If you find a car with a player in it...eject them
function carjack()
{
%player = LocalClientConnection.getControlObject();
if (%player.getClassName() $= "Player")
{
%eyeVec = %player.getEyeVector();
%startPos = %player.getEyePoint();
%endPos = VectorAdd(%startPos, VectorScale(%eyeVec, 1000));
%target = ContainerRayCast(%startPos, %endPos, $TypeMasks::VehicleObjectType);
if (%target)
{
// See if anyone is mounted in the car's driver seat
%mount = %target.getMountNodeObject(0);
// Can only carjack bots
// remove '&& %mount.getClassName() $= "AIPlayer"' to allow you
// to carjack anyone/anything
if (%mount && %mount.getClassName() $= "AIPlayer")
{
commandToServer('carUnmountObj', %mount);
}
}
}
}
function getOut()
{
vehicleMap.pop();
moveMap.push();
commandToServer('dismountVehicle');
}
function brakeLights()
{
// Turn on/off the Cheetah's head lights.
commandToServer('toggleBrakeLights');
}
function brake(%val)
{
commandToServer('toggleBrakeLights');
$mvTriggerCount2++;
}

View file

@ -0,0 +1,109 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Functions that process commands sent from the server.
// This function is for chat messages only; it is invoked on the client when
// the server does a commandToClient with the tag ChatMessage. (Cf. the
// functions chatMessage* in core/scripts/server/message.cs.)
// This just invokes onChatMessage, which the mod code must define.
function clientCmdChatMessage(%sender, %voice, %pitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10)
{
onChatMessage(detag(%msgString), %voice, %pitch);
}
// Game event descriptions, which may or may not include text messages, can be
// sent using the message* functions in core/scripts/server/message.cs. Those
// functions do commandToClient with the tag ServerMessage, which invokes the
// function below.
// For ServerMessage messages, the client can install callbacks that will be
// run, according to the "type" of the message.
function clientCmdServerMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10)
{
// Get the message type; terminates at any whitespace.
%tag = getWord(%msgType, 0);
// First see if there is a callback installed that doesn't have a type;
// if so, that callback is always executed when a message arrives.
for (%i = 0; (%func = $MSGCB["", %i]) !$= ""; %i++) {
call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10);
}
// Next look for a callback for this particular type of ServerMessage.
if (%tag !$= "") {
for (%i = 0; (%func = $MSGCB[%tag, %i]) !$= ""; %i++) {
call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10);
}
}
}
// Called by the client to install a callback for a particular type of
// ServerMessage.
function addMessageCallback(%msgType, %func)
{
for (%i = 0; (%afunc = $MSGCB[%msgType, %i]) !$= ""; %i++) {
// If it already exists as a callback for this type,
// nothing to do.
if (%afunc $= %func) {
return;
}
}
// Set it up.
$MSGCB[%msgType, %i] = %func;
}
// The following is the callback that will be executed for every ServerMessage,
// because we're going to install it without a specified type. Any type-
// specific callbacks will be executed afterward.
// This just invokes onServerMessage, which can be overridden by the game
function onServerMessage(%a, %b, %c, %d, %e, %f, %g, %h, %i)
{
echo("onServerMessage: ");
if(%a !$= "") echo(" +- a: " @ %a);
if(%b !$= "") echo(" +- b: " @ %b);
if(%c !$= "") echo(" +- c: " @ %c);
if(%d !$= "") echo(" +- d: " @ %d);
if(%e !$= "") echo(" +- e: " @ %e);
if(%f !$= "") echo(" +- f: " @ %f);
if(%g !$= "") echo(" +- g: " @ %g);
if(%h !$= "") echo(" +- h: " @ %h);
if(%i !$= "") echo(" +- i: " @ %i);
}
function defaultMessageCallback(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10)
{
onServerMessage(detag(%msgString));
}
// Register that default message handler now.
addMessageCallback("", defaultMessageCallback);

View file

@ -0,0 +1,121 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Enter Chat Message Hud
//----------------------------------------------------------------------------
//------------------------------------------------------------------------------
function MessageHud::open(%this)
{
%offset = 6;
if(%this.isVisible())
return;
if(%this.isTeamMsg)
%text = "TEAM:";
else
%text = "GLOBAL:";
MessageHud_Text.setValue(%text);
%windowPos = "0 " @ ( getWord( outerChatHud.position, 1 ) + getWord( outerChatHud.extent, 1 ) + 1 );
%windowExt = getWord( OuterChatHud.extent, 0 ) @ " " @ getWord( MessageHud_Frame.extent, 1 );
%textExtent = getWord(MessageHud_Text.extent, 0) + 14;
%ctrlExtent = getWord(MessageHud_Frame.extent, 0);
Canvas.pushDialog(%this);
messageHud_Frame.position = %windowPos;
messageHud_Frame.extent = %windowExt;
MessageHud_Edit.position = setWord(MessageHud_Edit.position, 0, %textExtent + %offset);
MessageHud_Edit.extent = setWord(MessageHud_Edit.extent, 0, %ctrlExtent - %textExtent - (2 * %offset));
%this.setVisible(true);
MessageHud_Edit.makeFirstResponder(true);
}
//------------------------------------------------------------------------------
function MessageHud::close(%this)
{
if(!%this.isVisible())
return;
Canvas.popDialog(%this);
%this.setVisible(false);
MessageHud_Edit.setValue("");
}
//------------------------------------------------------------------------------
function MessageHud::toggleState(%this)
{
if(%this.isVisible())
%this.close();
else
%this.open();
}
//------------------------------------------------------------------------------
function MessageHud_Edit::onEscape(%this)
{
MessageHud.close();
}
//------------------------------------------------------------------------------
function MessageHud_Edit::eval(%this)
{
%text = collapseEscape(trim(%this.getValue()));
if(%text !$= "")
{
if(MessageHud.isTeamMsg)
commandToServer('teamMessageSent', %text);
else
commandToServer('messageSent', %text);
}
MessageHud.close();
}
//----------------------------------------------------------------------------
// MessageHud key handlers
function toggleMessageHud(%make)
{
if(%make)
{
MessageHud.isTeamMsg = false;
MessageHud.toggleState();
}
}
function teamMessageHud(%make)
{
if(%make)
{
MessageHud.isTeamMsg = true;
MessageHud.toggleState();
}
}

View file

@ -0,0 +1,116 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Hook into the client update messages to maintain our player list and scores.
//-----------------------------------------------------------------------------
addMessageCallback('MsgClientJoin', handleClientJoin);
addMessageCallback('MsgClientDrop', handleClientDrop);
addMessageCallback('MsgClientScoreChanged', handleClientScoreChanged);
function handleClientJoin(%msgType, %msgString, %clientName, %clientId, %guid,
%score, %kills, %deaths, %isAI, %isAdmin, %isSuperAdmin)
{
PlayerListGui.update(%clientId, detag(%clientName), %isSuperAdmin, %isAdmin,
%isAI, %score, %kills, %deaths);
}
function handleClientDrop(%msgType, %msgString, %clientName, %clientId)
{
PlayerListGui.remove(%clientId);
}
function handleClientScoreChanged(%msgType, %msgString, %score, %kills, %deaths, %clientId)
{
PlayerListGui.updateScore(%clientId, %score, %kills, %deaths);
echo(" score:"@%score@" kills:"@%kills@" deaths:"@%deaths);
}
// ----------------------------------------------------------------------------
// GUI methods
// ----------------------------------------------------------------------------
function PlayerListGui::update(%this, %clientId, %name, %isSuperAdmin, %isAdmin, %isAI, %score, %kills, %deaths)
{
// Build the row to display. The name can have ML control tags, including
// color and font. Since we're not using an ML control here, we need to
// strip them off.
%tag = %isSuperAdmin ? "[Super]" :
(%isAdmin ? "[Admin]" :
(%isAI ? "[Bot]" :
""));
%text = StripMLControlChars(%name) SPC %tag TAB %score TAB %kills TAB %deaths;
// Update or add the player to the control
if (PlayerListGuiList.getRowNumById(%clientId) == -1)
PlayerListGuiList.addRow(%clientId, %text);
else
PlayerListGuiList.setRowById(%clientId, %text);
// Sorts by score
PlayerListGuiList.sortNumerical(1, false);
PlayerListGuiList.clearSelection();
}
function PlayerListGui::updateScore(%this, %clientId, %score, %kills, %deaths)
{
%text = PlayerListGuiList.getRowTextById(%clientId);
%text = setField(%text, 1, %score);
%text = setField(%text, 2, %kills);
%text = setField(%text, 3, %deaths);
PlayerListGuiList.setRowById(%clientId, %text);
PlayerListGuiList.sortNumerical(1, false);
PlayerListGuiList.clearSelection();
}
function PlayerListGui::remove(%this, %clientId)
{
PlayerListGuiList.removeRowById(%clientId);
}
function PlayerListGui::toggle(%this)
{
if (%this.isAwake())
Canvas.popDialog(%this);
else
Canvas.pushDialog(%this);
}
function PlayerListGui::clear(%this)
{
// Override to clear the list.
PlayerListGuiList.clear();
}
function PlayerListGui::zeroScores(%this)
{
for (%i = 0; %i < PlayerListGuiList.rowCount(); %i++)
{
%text = PlayerListGuiList.getRowText(%i);
%text = setField(%text, 1, "0");
%text = setField(%text, 2, "0");
%text = setField(%text, 3, "0");
PlayerListGuiList.setRowById(PlayerListGuiList.getRowId(%i), %text);
}
PlayerListGuiList.clearSelection();
}

View file

@ -0,0 +1,30 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Demo Pathed AIPlayer.
//-----------------------------------------------------------------------------
datablock PlayerData(DemoPlayer : DefaultPlayerData)
{
shootingDelay = 2000;
};

View file

@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// Game specific audio descriptions. Always declare SFXDescription's (the type of sound)
// before SFXProfile's (the sound itself) when creating new ones
singleton SFXDescription(BulletFireDesc : AudioEffect )
{
isLooping = false;
is3D = true;
ReferenceDistance = 10.0;
MaxDistance = 60.0;
};
singleton SFXDescription(BulletImpactDesc : AudioEffect )
{
isLooping = false;
is3D = true;
ReferenceDistance = 10.0;
MaxDistance = 30.0;
volume = 0.4;
pitch = 1.4;
};

View file

@ -0,0 +1,35 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// Always declare audio Descriptions (the type of sound) before Profiles (the
// sound itself) when creating new ones.
// ----------------------------------------------------------------------------
// Now for the profiles - these are the usable sounds
// ----------------------------------------------------------------------------
datablock SFXProfile(ThrowSnd)
{
filename = "data/FPSGameplay/sound/throw";
description = AudioClose3d;
preload = false;
};

View file

@ -0,0 +1,58 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// This is the default save location for any ForestBrush(s) created in
// the Forest Editor.
// This script is executed from ForestEditorPlugin::onWorldEditorStartup().
//--- OBJECT WRITE BEGIN ---
new SimGroup(ForestBrushGroup) {
canSaveDynamicFields = "1";
new ForestBrush() {
internalName = "ExampleForestBrush";
canSaveDynamicFields = "1";
new ForestBrushElement() {
internalName = "ExampleElement";
canSaveDynamicFields = "1";
ForestItemData = "ExampleForestMesh";
probability = "1";
rotationRange = "360";
scaleMin = "1";
scaleMax = "2";
scaleExponent = "0.2";
sinkMin = "0";
sinkMax = "0.1";
sinkRadius = "0.25";
slopeMin = "0";
slopeMax = "30";
elevationMin = "-10000";
elevationMax = "10000";
clumpCountMin = "1";
clumpCountMax = "1";
clumpCountExponent = "1";
clumpRadius = "10";
};
};
};
//--- OBJECT WRITE END ---

View file

@ -0,0 +1,4 @@
datablock CameraData(Observer)
{
mode = "Observer";
};

View file

@ -0,0 +1,66 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
datablock ParticleData(DefaultParticle)
{
textureName = "data/FPSGameplay/art/particles/defaultParticle";
dragCoefficient = 0.498534;
gravityCoefficient = 0;
inheritedVelFactor = 0.499022;
constantAcceleration = 0.0;
lifetimeMS = 1313;
lifetimeVarianceMS = 500;
useInvAlpha = true;
spinRandomMin = -360;
spinRandomMax = 360;
spinSpeed = 1;
colors[0] = "0.992126 0.00787402 0.0314961 1";
colors[1] = "1 0.834646 0 0.645669";
colors[2] = "1 0.299213 0 0.330709";
colors[3] = "0.732283 1 0 0";
sizes[0] = 0;
sizes[1] = 0.497467;
sizes[2] = 0.73857;
sizes[3] = 0.997986;
times[0] = 0.0;
times[1] = 0.247059;
times[2] = 0.494118;
times[3] = 1;
animTexName = "data/FPSGameplay/art/particles/defaultParticle";
};
datablock ParticleEmitterData(DefaultEmitter)
{
ejectionPeriodMS = "50";
ejectionVelocity = "1";
velocityVariance = "0";
ejectionOffset = "0.2";
thetaMax = "40";
particles = "DefaultParticle";
blendStyle = "ADDITIVE";
softParticles = "0";
softnessDistance = "1";
};

View file

@ -0,0 +1,100 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// ENVIROMENTAL EFFECTS GO HERE (PRECIPITATION - LIGHTNING)
// ----------------------------------------------------------------------------
// Rain
// ----------------------------------------------------------------------------
datablock SFXProfile(HeavyRainSound)
{
filename = "data/FPSGameplay/sound/environment/amb";
description = AudioLoop2d;
};
datablock PrecipitationData(HeavyRain)
{
soundProfile = "HeavyRainSound";
dropTexture = "data/FPSGameplay/art/environment/precipitation/rain";
splashTexture = "data/FPSGameplay/art/environment/precipitation/water_splash";
dropSize = 0.35;
splashSize = 0.1;
useTrueBillboards = false;
splashMS = 500;
};
// ----------------------------------------------------------------------------
// Lightning
// ----------------------------------------------------------------------------
// When setting up thunder sounds for lightning it should be known that:
// - strikeSound is a 3d sound
// - thunderSounds[n] are 2d sounds
datablock SFXProfile(ThunderCrash1Sound)
{
filename = "data/FPSGameplay/sound/environment/thunder1";
description = Audio2d;
};
datablock SFXProfile(ThunderCrash2Sound)
{
filename = "data/FPSGameplay/sound/environment/thunder2";
description = Audio2d;
};
datablock SFXProfile(ThunderCrash3Sound)
{
filename = "data/FPSGameplay/sound/environment/thunder3";
description = Audio2d;
};
datablock SFXProfile(ThunderCrash4Sound)
{
filename = "data/FPSGameplay/sound/environment/thunder4";
description = Audio2d;
};
datablock LightningData(DefaultStorm)
{
thunderSounds[0] = ThunderCrash1Sound;
thunderSounds[1] = ThunderCrash2Sound;
thunderSounds[2] = ThunderCrash3Sound;
thunderSounds[3] = ThunderCrash4Sound;
strikeTextures[0] = "data/FPSGameplay/art/environment/lightning";
};
datablock ReflectorDesc( DefaultCubeDesc )
{
texSize = 256;
nearDist = 0.1;
farDist = 1000.0;
objectTypeMask = 0xFFFFFFFF;
detailAdjust = 1.0;
priority = 1.0;
maxRateMs = 15;
useOcclusionQuery = true;
};

View file

@ -0,0 +1,85 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// Inventory items. These objects rely on the item & inventory support
// system defined in item.cs and inventory.cs
//-----------------------------------------------------------------------------
// Health kits can be added to your inventory and used to heal up.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Audio profiles
//-----------------------------------------------------------------------------
datablock SFXProfile(HealthUseSound)
{
filename = "data/FPSGameplay/sound/health_mono_01";
description = AudioClose3d;
preload = true;
};
//-----------------------------------------------------------------------------
// Health Kits cannot be picked up and are not meant to be added to
// inventory. Health is applied automatically when an objects collides
// with a patch.
//-----------------------------------------------------------------------------
datablock ItemData(HealthKitSmall)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
category = "Health";
className = "HealthPatch";
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/items/kit/healthkit.dts";
mass = 2;
friction = 1;
elasticity = 0.3;
emap = true;
// Dynamic properties defined by the scripts
pickupName = "a small health kit";
repairAmount = 50;
};
// This is the "health patch" dropped by a dying player.
datablock ItemData(HealthKitPatch)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
category = "Health";
className = "HealthPatch";
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/items/patch/healthpatch.dts";
mass = 2;
friction = 1;
elasticity = 0.3;
emap = true;
// Dynamic properties defined by the scripts
pickupName = "a health patch";
repairAmount = 50;
};

View file

@ -0,0 +1,608 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// LightAnimData
//------------------------------------------------------------------------------
datablock LightAnimData( NullLightAnim )
{
animEnabled = false;
};
datablock LightAnimData( PulseLightAnim )
{
brightnessA = 0;
brightnessZ = 1;
brightnessPeriod = 1;
brightnessKeys = "aza";
brightnessSmooth = true;
};
datablock LightAnimData( SubtlePulseLightAnim )
{
brightnessA = 0.5;
brightnessZ = 1;
brightnessPeriod = 1;
brightnessKeys = "aza";
brightnessSmooth = true;
};
datablock LightAnimData( FlickerLightAnim )
{
brightnessA = 1;
brightnessZ = 0;
brightnessPeriod = 5;
brightnessKeys = "aaazaaaaaazaaazaaazaaaaazaaaazzaaaazaaaaaazaaaazaaaza";
brightnessSmooth = false;
};
datablock LightAnimData( BlinkLightAnim )
{
brightnessA = 0;
brightnessZ = 1;
brightnessPeriod = 5;
brightnessKeys = "azaaaazazaaaaaazaaaazaaaazzaaaaaazaazaaazaaaaaaa";
brightnessSmooth = false;
};
datablock LightAnimData( FireLightAnim )
{
brightnessA = 0.75;
brightnessZ = 1;
brightnessPeriod = 0.7;
brightnessKeys = "annzzznnnzzzaznzzzz";
brightnessSmooth = 0;
offsetA[0] = "-0.05";
offsetA[1] = "-0.05";
offsetA[2] = "-0.05";
offsetZ[0] = "0.05";
offsetZ[1] = "0.05";
offsetZ[2] = "0.05";
offsetPeriod[0] = "1.25";
offsetPeriod[1] = "1.25";
offsetPeriod[2] = "1.25";
offsetKeys[0] = "ahahaazahakayajza";
offsetKeys[1] = "ahahaazahakayajza";
offsetKeys[2] = "ahahaazahakayajza";
rotKeys[0] = "";
rotKeys[1] = "";
rotKeys[2] = "";
colorKeys[0] = "";
colorKeys[1] = "";
colorKeys[2] = "";
};
datablock LightAnimData( SpinLightAnim )
{
rotA[2] = "0";
rotZ[2] = "360";
rotPeriod[2] = "1";
rotKeys[2] = "az";
rotSmooth[2] = true;
};
//------------------------------------------------------------------------------
// LightFlareData
//------------------------------------------------------------------------------
datablock LightFlareData( NullLightFlare )
{
flareEnabled = false;
};
datablock LightFlareData( SunFlareExample )
{
overallScale = 4.0;
flareEnabled = true;
renderReflectPass = false;
flareTexture = "data/FPSGameplay/art/lights/lensFlareSheet0";
elementRect[0] = "512 0 512 512";
elementDist[0] = 0.0;
elementScale[0] = 2.0;
elementTint[0] = "0.6 0.6 0.6";
elementRotate[0] = true;
elementUseLightColor[0] = true;
elementRect[1] = "1152 0 128 128";
elementDist[1] = 0.3;
elementScale[1] = 0.7;
elementTint[1] = "1.0 1.0 1.0";
elementRotate[1] = true;
elementUseLightColor[1] = true;
elementRect[2] = "1024 0 128 128";
elementDist[2] = 0.5;
elementScale[2] = 0.25;
elementTint[2] = "1.0 1.0 1.0";
elementRotate[2] = true;
elementUseLightColor[2] = true;
elementRect[3] = "1024 128 128 128";
elementDist[3] = 0.8;
elementScale[3] = 0.7;
elementTint[3] = "1.0 1.0 1.0";
elementRotate[3] = true;
elementUseLightColor[3] = true;
elementRect[4] = "1024 0 128 128";
elementDist[4] = 1.18;
elementScale[4] = 0.5;
elementTint[4] = "1.0 1.0 1.0";
elementRotate[4] = true;
elementUseLightColor[4] = true;
elementRect[5] = "1152 128 128 128";
elementDist[5] = 1.25;
elementScale[5] = 0.25;
elementTint[5] = "1.0 1.0 1.0";
elementRotate[5] = true;
elementUseLightColor[5] = true;
elementRect[6] = "1024 0 128 128";
elementDist[6] = 2.0;
elementScale[6] = 0.25;
elementTint[6] = "1.0 1.0 1.0";
elementRotate[6] = true;
elementUseLightColor[6] = true;
occlusionRadius = "0.25";
};
datablock LightFlareData( SunFlareExample2 )
{
overallScale = 2.0;
flareEnabled = true;
renderReflectPass = false;
flareTexture = "data/FPSGameplay/art/lights/lensFlareSheet0";
elementRect[0] = "1024 0 128 128";
elementDist[0] = 0.5;
elementScale[0] = 0.25;
elementTint[0] = "1.0 1.0 1.0";
elementRotate[0] = true;
elementUseLightColor[0] = true;
elementRect[1] = "1024 128 128 128";
elementDist[1] = 0.8;
elementScale[1] = 0.7;
elementTint[1] = "1.0 1.0 1.0";
elementRotate[1] = true;
elementUseLightColor[1] = true;
elementRect[2] = "1024 0 128 128";
elementDist[2] = 1.18;
elementScale[2] = 0.5;
elementTint[2] = "1.0 1.0 1.0";
elementRotate[2] = true;
elementUseLightColor[2] = true;
elementRect[3] = "1152 128 128 128";
elementDist[3] = 1.25;
elementScale[3] = 0.25;
elementTint[3] = "1.0 1.0 1.0";
elementRotate[3] = true;
elementUseLightColor[3] = true;
elementRect[4] = "1024 0 128 128";
elementDist[4] = 2.0;
elementScale[4] = 0.25;
elementTint[4] = "0.7 0.7 0.7";
elementRotate[4] = true;
elementUseLightColor[4] = true;
occlusionRadius = "0.25";
};
datablock LightFlareData(SunFlareExample3)
{
overallScale = 2.0;
flareEnabled = true;
renderReflectPass = false;
flareTexture = "data/FPSGameplay/art/lights/lensflareSheet3.png";
elementRect[0] = "0 256 256 256";
elementDist[0] = "-0.6";
elementScale[0] = "3.5";
elementTint[0] = "0.537255 0.537255 0.537255 1";
elementRotate[0] = true;
elementUseLightColor[0] = true;
elementRect[1] = "128 128 128 128";
elementDist[1] = "0.1";
elementScale[1] = "1.5";
elementTint[1] = "0.996078 0.976471 0.721569 1";
elementRotate[1] = true;
elementUseLightColor[1] = true;
elementRect[2] = "0 0 64 64";
elementDist[2] = "0.4";
elementScale[2] = "0.25";
elementTint[2] = "0 0 1 1";
elementRotate[2] = true;
elementUseLightColor[2] = true;
elementRect[3] = "0 0 64 64";
elementDist[3] = "0.45";
elementScale[3] = 0.25;
elementTint[3] = "0 1 0 1";
elementRotate[3] = true;
elementUseLightColor[3] = true;
elementRect[4] = "0 0 64 64";
elementDist[4] = "0.5";
elementScale[4] = 0.25;
elementTint[4] = "1 0 0 1";
elementRotate[4] = true;
elementUseLightColor[4] = true;
elementRect[9] = "256 0 256 256";
elementDist[3] = "0.45";
elementScale[3] = "0.25";
elementScale[9] = "2";
elementRect[4] = "0 0 64 64";
elementRect[5] = "128 0 128 128";
elementDist[4] = "0.5";
elementDist[5] = "1.2";
elementScale[1] = "1.5";
elementScale[4] = "0.25";
elementScale[5] = "0.5";
elementTint[1] = "0.996078 0.976471 0.721569 1";
elementTint[2] = "0 0 1 1";
elementTint[5] = "0.721569 0 1 1";
elementRotate[5] = "0";
elementUseLightColor[5] = "1";
elementRect[0] = "0 256 256 256";
elementRect[1] = "128 128 128 128";
elementRect[2] = "0 0 64 64";
elementRect[3] = "0 0 64 64";
elementDist[0] = "-0.6";
elementDist[1] = "0.1";
elementDist[2] = "0.4";
elementScale[0] = "3.5";
elementScale[2] = "0.25";
elementTint[0] = "0.537255 0.537255 0.537255 1";
elementTint[3] = "0 1 0 1";
elementTint[4] = "1 0 0 1";
elementRect[6] = "64 64 64 64";
elementDist[6] = "0.9";
elementScale[6] = "4";
elementTint[6] = "0.00392157 0.721569 0.00392157 1";
elementRotate[6] = "0";
elementUseLightColor[6] = "1";
elementRect[7] = "64 64 64 64";
elementRect[8] = "64 64 64 64";
elementDist[7] = "0.25";
elementDist[8] = "0.18";
elementDist[9] = "0";
elementScale[7] = "2";
elementScale[8] = "0.5";
elementTint[7] = "0.6 0.0117647 0.741176 1";
elementTint[8] = "0.027451 0.690196 0.0117647 1";
elementTint[9] = "0.647059 0.647059 0.647059 1";
elementRotate[9] = "0";
elementUseLightColor[7] = "1";
elementUseLightColor[8] = "1";
elementRect[10] = "256 256 256 256";
elementRect[11] = "0 64 64 64";
elementRect[12] = "0 64 64 64";
elementRect[13] = "64 0 64 64";
elementDist[10] = "0";
elementDist[11] = "-0.3";
elementDist[12] = "-0.32";
elementDist[13] = "1";
elementScale[10] = "10";
elementScale[11] = "2.5";
elementScale[12] = "0.3";
elementScale[13] = "0.4";
elementTint[10] = "0.321569 0.321569 0.321569 1";
elementTint[11] = "0.443137 0.0431373 0.00784314 1";
elementTint[12] = "0.00784314 0.996078 0.0313726 1";
elementTint[13] = "0.996078 0.94902 0.00784314 1";
elementUseLightColor[10] = "1";
elementUseLightColor[11] = "1";
elementUseLightColor[13] = "1";
elementRect[14] = "0 0 64 64";
elementDist[14] = "0.15";
elementScale[14] = "0.8";
elementTint[14] = "0.505882 0.0470588 0.00784314 1";
elementRotate[14] = "1";
elementUseLightColor[9] = "1";
elementUseLightColor[14] = "1";
elementRect[15] = "64 64 64 64";
elementRect[16] = "0 64 64 64";
elementRect[17] = "0 0 64 64";
elementRect[18] = "0 64 64 64";
elementRect[19] = "256 0 256 256";
elementDist[15] = "0.8";
elementDist[16] = "0.7";
elementDist[17] = "1.4";
elementDist[18] = "-0.5";
elementDist[19] = "-1.5";
elementScale[15] = "3";
elementScale[16] = "0.3";
elementScale[17] = "0.2";
elementScale[18] = "1";
elementScale[19] = "35";
elementTint[15] = "0.00784314 0.00784314 0.996078 1";
elementTint[16] = "0.992157 0.992157 0.992157 1";
elementTint[17] = "0.996078 0.603922 0.00784314 1";
elementTint[18] = "0.2 0.00392157 0.47451 1";
elementTint[19] = "0.607843 0.607843 0.607843 1";
elementUseLightColor[15] = "1";
elementUseLightColor[18] = "1";
elementUseLightColor[19] = "1";
occlusionRadius = "0.25";
};
datablock LightFlareData(SunFlarePacificIsland)
{
overallScale = 2.0;
flareEnabled = true;
renderReflectPass = false;
flareTexture = "data/FPSGameplay/art/lights/lensflareSheet3.png";
elementRect[0] = "0 256 256 256";
elementDist[0] = "-0.6";
elementScale[0] = "3.5";
elementTint[0] = "0.537255 0.537255 0.537255 1";
elementRotate[0] = true;
elementUseLightColor[0] = true;
elementRect[1] = "128 128 128 128";
elementDist[1] = "0.1";
elementScale[1] = "1.5";
elementTint[1] = "0.996078 0.976471 0.721569 1";
elementRotate[1] = true;
elementUseLightColor[1] = true;
elementRect[2] = "0 0 64 64";
elementDist[2] = "0.4";
elementScale[2] = "0.25";
elementTint[2] = "0 0 1 1";
elementRotate[2] = true;
elementUseLightColor[2] = true;
elementRect[3] = "0 0 64 64";
elementDist[3] = "0.45";
elementScale[3] = 0.25;
elementTint[3] = "0 1 0 1";
elementRotate[3] = true;
elementUseLightColor[3] = true;
elementRect[4] = "0 0 64 64";
elementDist[4] = "0.5";
elementScale[4] = 0.25;
elementTint[4] = "1 0 0 1";
elementRotate[4] = true;
elementUseLightColor[4] = true;
elementRect[9] = "256 0 256 256";
elementDist[3] = "0.45";
elementScale[3] = "0.25";
elementScale[9] = "2";
elementRect[4] = "0 0 64 64";
elementRect[5] = "128 0 128 128";
elementDist[4] = "0.5";
elementDist[5] = "1.2";
elementScale[1] = "1.5";
elementScale[4] = "0.25";
elementScale[5] = "0.5";
elementTint[1] = "0.996078 0.976471 0.721569 1";
elementTint[2] = "0 0 1 1";
elementTint[5] = "0.721569 0 1 1";
elementRotate[5] = "0";
elementUseLightColor[5] = "1";
elementRect[0] = "0 256 256 256";
elementRect[1] = "128 128 128 128";
elementRect[2] = "0 0 64 64";
elementRect[3] = "0 0 64 64";
elementDist[0] = "-0.6";
elementDist[1] = "0.1";
elementDist[2] = "0.4";
elementScale[0] = "3.5";
elementScale[2] = "0.25";
elementTint[0] = "0.537255 0.537255 0.537255 1";
elementTint[3] = "0 1 0 1";
elementTint[4] = "1 0 0 1";
elementRect[6] = "64 64 64 64";
elementDist[6] = "0.9";
elementScale[6] = "4";
elementTint[6] = "0.00392157 0.721569 0.00392157 1";
elementRotate[6] = "0";
elementUseLightColor[6] = "1";
elementRect[7] = "64 64 64 64";
elementRect[8] = "64 64 64 64";
elementDist[7] = "0.25";
elementDist[8] = "0.18";
elementDist[9] = "0";
elementScale[7] = "2";
elementScale[8] = "0.5";
elementTint[7] = "0.6 0.0117647 0.741176 1";
elementTint[8] = "0.027451 0.690196 0.0117647 1";
elementTint[9] = "0.647059 0.647059 0.647059 1";
elementRotate[9] = "0";
elementUseLightColor[7] = "1";
elementUseLightColor[8] = "1";
elementRect[10] = "256 256 256 256";
elementRect[11] = "0 64 64 64";
elementRect[12] = "0 64 64 64";
elementRect[13] = "64 0 64 64";
elementDist[10] = "0";
elementDist[11] = "-0.3";
elementDist[12] = "-0.32";
elementDist[13] = "1";
elementScale[10] = "10";
elementScale[11] = "2.5";
elementScale[12] = "0.3";
elementScale[13] = "0.4";
elementTint[10] = "0.321569 0.321569 0.321569 1";
elementTint[11] = "0.443137 0.0431373 0.00784314 1";
elementTint[12] = "0.00784314 0.996078 0.0313726 1";
elementTint[13] = "0.996078 0.94902 0.00784314 1";
elementUseLightColor[10] = "1";
elementUseLightColor[11] = "1";
elementUseLightColor[13] = "1";
elementRect[14] = "0 0 64 64";
elementDist[14] = "0.15";
elementScale[14] = "0.8";
elementTint[14] = "0.505882 0.0470588 0.00784314 1";
elementRotate[14] = "1";
elementUseLightColor[9] = "1";
elementUseLightColor[14] = "1";
elementRect[15] = "64 64 64 64";
elementRect[16] = "0 64 64 64";
elementRect[17] = "0 0 64 64";
elementRect[18] = "0 64 64 64";
elementRect[19] = "256 0 256 256";
elementDist[15] = "0.8";
elementDist[16] = "0.7";
elementDist[17] = "1.4";
elementDist[18] = "-0.5";
elementDist[19] = "-1.5";
elementScale[15] = "3";
elementScale[16] = "0.3";
elementScale[17] = "0.2";
elementScale[18] = "1";
elementScale[19] = "35";
elementTint[15] = "0.00784314 0.00784314 0.996078 1";
elementTint[16] = "0.992157 0.992157 0.992157 1";
elementTint[17] = "0.996078 0.603922 0.00784314 1";
elementTint[18] = "0.2 0.00392157 0.47451 1";
elementTint[19] = "0.607843 0.607843 0.607843 1";
elementUseLightColor[15] = "1";
elementUseLightColor[18] = "1";
elementUseLightColor[19] = "1";
};
datablock LightFlareData( LightFlareExample0 )
{
overallScale = 2.0;
flareEnabled = true;
renderReflectPass = true;
flareTexture = "data/FPSGameplay/art/lights/lensFlareSheet1";
elementRect[0] = "0 512 512 512";
elementDist[0] = 0.0;
elementScale[0] = 0.5;
elementTint[0] = "1.0 1.0 1.0";
elementRotate[0] = false;
elementUseLightColor[0] = false;
elementRect[1] = "512 0 512 512";
elementDist[1] = 0.0;
elementScale[1] = 2.0;
elementTint[1] = "0.5 0.5 0.5";
elementRotate[1] = false;
elementUseLightColor[1] = false;
occlusionRadius = "0.25";
};
datablock LightFlareData( LightFlareExample1 )
{
overallScale = 2.0;
flareEnabled = true;
renderReflectPass = true;
flareTexture = "data/FPSGameplay/art/lights/lensFlareSheet1";
elementRect[0] = "512 512 512 512";
elementDist[0] = 0.0;
elementScale[0] = 0.5;
elementTint[0] = "1.0 1.0 1.0";
elementRotate[0] = false;
elementUseLightColor[0] = false;
elementRect[1] = "512 0 512 512";
elementDist[1] = 0.0;
elementScale[1] = 2.0;
elementTint[1] = "0.5 0.5 0.5";
elementRotate[1] = false;
elementUseLightColor[1] = false;
occlusionRadius = "0.25";
};
datablock LightFlareData( LightFlareExample2 )
{
overallScale = 2.0;
flareEnabled = true;
renderReflectPass = true;
flareTexture = "data/FPSGameplay/art/lights/lensFlareSheet0";
elementRect[0] = "512 512 512 512";
elementDist[0] = 0.0;
elementScale[0] = 0.5;
elementTint[0] = "1.0 1.0 1.0";
elementRotate[0] = true;
elementUseLightColor[0] = true;
elementRect[1] = "512 0 512 512";
elementDist[1] = 0.0;
elementScale[1] = 2.0;
elementTint[1] = "0.7 0.7 0.7";
elementRotate[1] = true;
elementUseLightColor[1] = true;
elementRect[2] = "1152 0 128 128";
elementDist[2] = 0.3;
elementScale[2] = 0.5;
elementTint[2] = "1.0 1.0 1.0";
elementRotate[2] = true;
elementUseLightColor[2] = true;
elementRect[3] = "1024 0 128 128";
elementDist[3] = 0.5;
elementScale[3] = 0.25;
elementTint[3] = "1.0 1.0 1.0";
elementRotate[3] = true;
elementUseLightColor[3] = true;
elementRect[4] = "1024 128 128 128";
elementDist[4] = 0.8;
elementScale[4] = 0.6;
elementTint[4] = "1.0 1.0 1.0";
elementRotate[4] = true;
elementUseLightColor[4] = true;
elementRect[5] = "1024 0 128 128";
elementDist[5] = 1.18;
elementScale[5] = 0.5;
elementTint[5] = "0.7 0.7 0.7";
elementRotate[5] = true;
elementUseLightColor[5] = true;
elementRect[6] = "1152 128 128 128";
elementDist[6] = 1.25;
elementScale[6] = 0.35;
elementTint[6] = "0.8 0.8 0.8";
elementRotate[6] = true;
elementUseLightColor[6] = true;
elementRect[7] = "1024 0 128 128";
elementDist[7] = 2.0;
elementScale[7] = 0.25;
elementTint[7] = "1.0 1.0 1.0";
elementRotate[7] = true;
elementUseLightColor[7] = true;
};

View file

@ -0,0 +1,24 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// This is the default save location for any Datablocks created in the
// Datablock Editor (this script is executed from onServerCreated())

View file

@ -0,0 +1,57 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// This is the default save location for any Decal datablocks created in the
// Decal Editor (this script is executed from onServerCreated())
datablock DecalData(ScorchBigDecal)
{
Material = "DECAL_scorch";
size = "5.0";
lifeSpan = "50000";
};
datablock DecalData(ScorchRXDecal)
{
Material = "DECAL_RocketEXP";
size = "5.0";
lifeSpan = "20000";
randomize = "1";
texRows = "2";
texCols = "2";
clippingAngle = "80";
screenStartRadius = "200";
screenEndRadius = "100";
};
datablock DecalData(bulletHoleDecal)
{
Material = "DECAL_bulletHole";
size = "0.25";
lifeSpan = "5000";
randomize = "1";
texRows = "2";
texCols = "2";
screenStartRadius = "20";
screenEndRadius = "5";
clippingAngle = "180";
};

View file

@ -0,0 +1,21 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------

View file

@ -0,0 +1,40 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// This is the default save location for any TSForestItemData(s) created in the
// Forest Editor Editor (this script is executed from onServerCreated())
datablock TSForestItemData(ExampleForestMesh)
{
shapeFile = "data/FPSGameplay/art/shapes/trees/defaulttree/defaulttree.DAE";
internalName = "ExampleForestMesh";
windScale = "1";
trunkBendScale = "0.02";
branchAmp = "0.05";
detailAmp = "0.1";
detailFreq = "0.2";
mass = "5";
rigidity = "20";
dampingCoefficient = "0.2";
tightnessCoefficient = "4";
};

View file

@ -0,0 +1,25 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// This is the default save location for any Particle datablocks created in the
// Particle Editor (this script is executed from onServerCreated())

View file

@ -0,0 +1,25 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// This is the default save location for any Particle Emitter datablocks created in the
// Particle Editor (this script is executed from onServerCreated())

View file

@ -0,0 +1,39 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
datablock MissionMarkerData(WayPointMarker)
{
category = "Misc";
shapeFile = "data/FPSGameplay/art/shapes/octahedron.dts";
};
datablock MissionMarkerData(SpawnSphereMarker)
{
category = "Misc";
shapeFile = "data/FPSGameplay/art/shapes/octahedron.dts";
};
datablock MissionMarkerData(CameraBookmarkMarker)
{
category = "Misc";
shapeFile = "data/FPSGameplay/art/shapes/camera.dts";
};

View file

@ -0,0 +1,243 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
datablock ParticleEmitterNodeData(DefaultEmitterNodeData)
{
timeMultiple = 1;
};
// Smoke
datablock ParticleData(Smoke)
{
textureName = "data/FPSGameplay/art/particles/smoke";
dragCoefficient = 0.3;
gravityCoefficient = -0.2; // rises slowly
inheritedVelFactor = 0.00;
lifetimeMS = 3000;
lifetimeVarianceMS = 250;
useInvAlpha = true;
spinRandomMin = -30.0;
spinRandomMax = 30.0;
sizes[0] = 1.5;
sizes[1] = 2.75;
sizes[2] = 6.5;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(SmokeEmitter)
{
ejectionPeriodMS = 400;
periodVarianceMS = 5;
ejectionVelocity = 0.0;
velocityVariance = 0.0;
thetaMin = 0.0;
thetaMax = 90.0;
particles = Smoke;
};
datablock ParticleEmitterNodeData(SmokeEmitterNode)
{
timeMultiple = 1;
};
// Ember
datablock ParticleData(EmberParticle)
{
textureName = "data/FPSGameplay/art/particles/ember";
dragCoefficient = 0.0;
windCoefficient = 0.0;
gravityCoefficient = -0.05; // rises slowly
inheritedVelFactor = 0.00;
lifetimeMS = 5000;
lifetimeVarianceMS = 0;
useInvAlpha = false;
spinRandomMin = -90.0;
spinRandomMax = 90.0;
spinSpeed = 1;
colors[0] = "1.000000 0.800000 0.000000 0.800000";
colors[1] = "1.000000 0.700000 0.000000 0.800000";
colors[2] = "1.000000 0.000000 0.000000 0.200000";
sizes[0] = 0.05;
sizes[1] = 0.1;
sizes[2] = 0.05;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(EmberEmitter)
{
ejectionPeriodMS = 100;
periodVarianceMS = 0;
ejectionVelocity = 0.75;
velocityVariance = 0.00;
ejectionOffset = 2.0;
thetaMin = 1.0;
thetaMax = 100.0;
particles = "EmberParticle";
};
datablock ParticleEmitterNodeData(EmberNode)
{
timeMultiple = 1;
};
// Fire
datablock ParticleData(FireParticle)
{
textureName = "data/FPSGameplay/art/particles/smoke";
dragCoefficient = 0.0;
windCoefficient = 0.0;
gravityCoefficient = -0.05; // rises slowly
inheritedVelFactor = 0.00;
lifetimeMS = 5000;
lifetimeVarianceMS = 1000;
useInvAlpha = false;
spinRandomMin = -90.0;
spinRandomMax = 90.0;
spinSpeed = 1.0;
colors[0] = "0.2 0.2 0.0 0.2";
colors[1] = "0.6 0.2 0.0 0.2";
colors[2] = "0.4 0.0 0.0 0.1";
colors[3] = "0.1 0.04 0.0 0.3";
sizes[0] = 0.5;
sizes[1] = 4.0;
sizes[2] = 5.0;
sizes[3] = 6.0;
times[0] = 0.0;
times[1] = 0.1;
times[2] = 0.2;
times[3] = 0.3;
};
datablock ParticleEmitterData(FireEmitter)
{
ejectionPeriodMS = 50;
periodVarianceMS = 0;
ejectionVelocity = 0.55;
velocityVariance = 0.00;
ejectionOffset = 1.0;
thetaMin = 1.0;
thetaMax = 100.0;
particles = "FireParticle";
};
datablock ParticleEmitterNodeData(FireNode)
{
timeMultiple = 1;
};
// Torch Fire
datablock ParticleData(TorchFire1)
{
textureName = "data/FPSGameplay/art/particles/smoke";
dragCoefficient = 0.0;
gravityCoefficient = -0.3; // rises slowly
inheritedVelFactor = 0.00;
lifetimeMS = 500;
lifetimeVarianceMS = 250;
useInvAlpha = false;
spinRandomMin = -30.0;
spinRandomMax = 30.0;
spinSpeed = 1;
colors[0] = "0.6 0.6 0.0 0.1";
colors[1] = "0.8 0.6 0.0 0.1";
colors[2] = "0.0 0.0 0.0 0.1";
sizes[0] = 0.5;
sizes[1] = 0.5;
sizes[2] = 2.4;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleData(TorchFire2)
{
textureName = "data/FPSGameplay/art/particles/smoke";
dragCoefficient = 0.0;
gravityCoefficient = -0.5; // rises slowly
inheritedVelFactor = 0.00;
lifetimeMS = 800;
lifetimeVarianceMS = 150;
useInvAlpha = false;
spinRandomMin = -30.0;
spinRandomMax = 30.0;
spinSpeed = 1;
colors[0] = "0.8 0.6 0.0 0.1";
colors[1] = "0.6 0.6 0.0 0.1";
colors[2] = "0.0 0.0 0.0 0.1";
sizes[0] = 0.3;
sizes[1] = 0.3;
sizes[2] = 0.3;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TorchFireEmitter)
{
ejectionPeriodMS = 15;
periodVarianceMS = 5;
ejectionVelocity = 0.25;
velocityVariance = 0.10;
thetaMin = 0.0;
thetaMax = 45.0;
particles = "TorchFire1" TAB "TorchFire2";
};
datablock ParticleEmitterNodeData(TorchFireEmitterNode)
{
timeMultiple = 1;
};

View file

@ -0,0 +1,71 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
datablock PhysicsShapeData( PhysicsCube )
{
category = "Physics";
shapeName = "art/shapes/cube/cube.dae";
emap = true;
//physics properties
mass = "0.5";
friction = "0.4";
staticFriction = "0.5";
restitution = "0.3";
linearDamping = "0.1";
angularDamping = "0.2";
linearSleepThreshold = "1.0";
angularSleepThreshold = "1.0";
buoyancyDensity = "0.9";
waterDampingScale = "10";
//damage - dynamic fields
radiusDamage = 0;
damageRadius = 0;
areaImpulse = 0;
invulnerable = true;
};
datablock PhysicsShapeData( PhysicsBoulder )
{
category = "Physics";
shapeName = "art/shapes/rocks/boulder.dts";
emap = true;
//physics properties
mass = "20";
friction = "0.2";
staticFriction = "0.3";
restitution = "0.8";
linearDamping = "0.1";
angularDamping = "0.2";
linearSleepThreshold = "1.0";
angularSleepThreshold = "1.0";
buoyancyDensity = "0.9";
waterDampingScale = "10";
//damage - dynamic fields
radiusDamage = 0;
damageRadius = 0;
areaImpulse = 0;
invulnerable = false;
};

View file

@ -0,0 +1,674 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Player Audio Profiles
//----------------------------------------------------------------------------
datablock SFXProfile(DeathCrySound)
{
fileName = "data/FPSGameplay/sound/orc_death";
description = AudioClose3d;
preload = true;
};
datablock SFXProfile(PainCrySound)
{
fileName = "data/FPSGameplay/sound/orc_pain";
description = AudioClose3d;
preload = true;
};
//----------------------------------------------------------------------------
datablock SFXProfile(FootLightSoftSound)
{
filename = "data/FPSGameplay/sound/lgtStep_mono_01";
description = AudioClosest3d;
preload = true;
};
datablock SFXProfile(FootLightHardSound)
{
filename = "data/FPSGameplay/sound/hvystep_ mono_01";
description = AudioClose3d;
preload = true;
};
datablock SFXProfile(FootLightMetalSound)
{
filename = "data/FPSGameplay/sound/metalstep_mono_01";
description = AudioClose3d;
preload = true;
};
datablock SFXProfile(FootLightSnowSound)
{
filename = "data/FPSGameplay/sound/snowstep_mono_01";
description = AudioClosest3d;
preload = true;
};
datablock SFXProfile(FootLightShallowSplashSound)
{
filename = "data/FPSGameplay/sound/waterstep_mono_01";
description = AudioClose3d;
preload = true;
};
datablock SFXProfile(FootLightWadingSound)
{
filename = "data/FPSGameplay/sound/waterstep_mono_01";
description = AudioClose3d;
preload = true;
};
datablock SFXProfile(FootLightUnderwaterSound)
{
filename = "data/FPSGameplay/sound/waterstep_mono_01";
description = AudioClosest3d;
preload = true;
};
//----------------------------------------------------------------------------
// Splash
//----------------------------------------------------------------------------
datablock ParticleData(PlayerSplashMist)
{
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 = "data/FPSGameplay/art/shapes/actors/common/splash";
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(PlayerSplashMistEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 3.0;
velocityVariance = 2.0;
ejectionOffset = 0.0;
thetaMin = 85;
thetaMax = 85;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvance = false;
lifetimeMS = 250;
particles = "PlayerSplashMist";
};
datablock ParticleData(PlayerBubbleParticle)
{
dragCoefficient = 0.0;
gravityCoefficient = -0.50;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 400;
lifetimeVarianceMS = 100;
useInvAlpha = false;
textureName = "data/FPSGameplay/art/shapes/actors/common/splash";
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.1;
sizes[1] = 0.3;
sizes[2] = 0.3;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(PlayerBubbleEmitter)
{
ejectionPeriodMS = 1;
periodVarianceMS = 0;
ejectionVelocity = 2.0;
ejectionOffset = 0.5;
velocityVariance = 0.5;
thetaMin = 0;
thetaMax = 80;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvance = false;
particles = "PlayerBubbleParticle";
};
datablock ParticleData(PlayerFoamParticle)
{
dragCoefficient = 2.0;
gravityCoefficient = -0.05;
inheritedVelFactor = 0.1;
constantAcceleration = 0.0;
lifetimeMS = 600;
lifetimeVarianceMS = 100;
useInvAlpha = false;
spinRandomMin = -90.0;
spinRandomMax = 500.0;
textureName = "data/FPSGameplay/art/particles/millsplash01";
colors[0] = "0.7 0.8 1.0 0.20";
colors[1] = "0.7 0.8 1.0 0.20";
colors[2] = "0.7 0.8 1.0 0.00";
sizes[0] = 0.2;
sizes[1] = 0.4;
sizes[2] = 1.6;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(PlayerFoamEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 3.0;
velocityVariance = 1.0;
ejectionOffset = 0.0;
thetaMin = 85;
thetaMax = 85;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvance = false;
particles = "PlayerFoamParticle";
};
datablock ParticleData( PlayerFoamDropletsParticle )
{
dragCoefficient = 1;
gravityCoefficient = 0.2;
inheritedVelFactor = 0.2;
constantAcceleration = -0.0;
lifetimeMS = 600;
lifetimeVarianceMS = 0;
textureName = "data/FPSGameplay/art/shapes/actors/common/splash";
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.8;
sizes[1] = 0.3;
sizes[2] = 0.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData( PlayerFoamDropletsEmitter )
{
ejectionPeriodMS = 7;
periodVarianceMS = 0;
ejectionVelocity = 2;
velocityVariance = 1.0;
ejectionOffset = 0.0;
thetaMin = 60;
thetaMax = 80;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvance = false;
orientParticles = true;
particles = "PlayerFoamDropletsParticle";
};
datablock ParticleData( PlayerWakeParticle )
{
textureName = "data/FPSGameplay/art/particles/wake";
dragCoefficient = "0.0";
gravityCoefficient = "0.0";
inheritedVelFactor = "0.0";
lifetimeMS = "2500";
lifetimeVarianceMS = "200";
windCoefficient = "0.0";
useInvAlpha = "1";
spinRandomMin = "30.0";
spinRandomMax = "30.0";
animateTexture = true;
framesPerSec = 1;
animTexTiling = "2 1";
animTexFrames = "0 1";
colors[0] = "1 1 1 0.1";
colors[1] = "1 1 1 0.7";
colors[2] = "1 1 1 0.3";
colors[3] = "0.5 0.5 0.5 0";
sizes[0] = "1.0";
sizes[1] = "2.0";
sizes[2] = "3.0";
sizes[3] = "3.5";
times[0] = "0.0";
times[1] = "0.25";
times[2] = "0.5";
times[3] = "1.0";
};
datablock ParticleEmitterData( PlayerWakeEmitter )
{
ejectionPeriodMS = "200";
periodVarianceMS = "10";
ejectionVelocity = "0";
velocityVariance = "0";
ejectionOffset = "0";
thetaMin = "89";
thetaMax = "90";
phiReferenceVel = "0";
phiVariance = "1";
alignParticles = "1";
alignDirection = "0 0 1";
particles = "PlayerWakeParticle";
};
datablock ParticleData( PlayerSplashParticle )
{
dragCoefficient = 1;
gravityCoefficient = 0.2;
inheritedVelFactor = 0.2;
constantAcceleration = -0.0;
lifetimeMS = 600;
lifetimeVarianceMS = 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] = 0.5;
sizes[2] = 0.5;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData( PlayerSplashEmitter )
{
ejectionPeriodMS = 1;
periodVarianceMS = 0;
ejectionVelocity = 3;
velocityVariance = 1.0;
ejectionOffset = 0.0;
thetaMin = 60;
thetaMax = 80;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvance = false;
orientParticles = true;
lifetimeMS = 100;
particles = "PlayerSplashParticle";
};
datablock SplashData(PlayerSplash)
{
numSegments = 15;
ejectionFreq = 15;
ejectionAngle = 40;
ringLifetime = 0.5;
lifetimeMS = 300;
velocity = 4.0;
startRadius = 0.0;
acceleration = -3.0;
texWrap = 5.0;
texture = "data/FPSGameplay/art/particles/millsplash01";
emitter[0] = PlayerSplashEmitter;
emitter[1] = PlayerSplashMistEmitter;
colors[0] = "0.7 0.8 1.0 0.0";
colors[1] = "0.7 0.8 1.0 0.3";
colors[2] = "0.7 0.8 1.0 0.7";
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;
};
//----------------------------------------------------------------------------
// Foot puffs
//----------------------------------------------------------------------------
datablock ParticleData(LightPuff)
{
dragCoefficient = 2.0;
gravityCoefficient = -0.01;
inheritedVelFactor = 0.6;
constantAcceleration = 0.0;
lifetimeMS = 800;
lifetimeVarianceMS = 100;
useInvAlpha = true;
spinRandomMin = -35.0;
spinRandomMax = 35.0;
colors[0] = "1.0 1.0 1.0 1.0";
colors[1] = "1.0 1.0 1.0 0.0";
sizes[0] = 0.1;
sizes[1] = 0.8;
times[0] = 0.3;
times[1] = 1.0;
times[2] = 1.0;
textureName = "data/FPSGameplay/art/particles/dustParticle.png";
};
datablock ParticleEmitterData(LightPuffEmitter)
{
ejectionPeriodMS = 35;
periodVarianceMS = 10;
ejectionVelocity = 0.2;
velocityVariance = 0.1;
ejectionOffset = 0.0;
thetaMin = 20;
thetaMax = 60;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvance = false;
useEmitterColors = true;
particles = "LightPuff";
};
//----------------------------------------------------------------------------
// Liftoff dust
//----------------------------------------------------------------------------
datablock ParticleData(LiftoffDust)
{
dragCoefficient = 1.0;
gravityCoefficient = -0.01;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 1000;
lifetimeVarianceMS = 100;
useInvAlpha = true;
spinRandomMin = -90.0;
spinRandomMax = 500.0;
colors[0] = "1.0 1.0 1.0 1.0";
sizes[0] = 1.0;
times[0] = 1.0;
textureName = "data/FPSGameplay/art/particles/dustParticle";
};
datablock ParticleEmitterData(LiftoffDustEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 2.0;
velocityVariance = 0.0;
ejectionOffset = 0.0;
thetaMin = 90;
thetaMax = 90;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvance = false;
useEmitterColors = true;
particles = "LiftoffDust";
};
//----------------------------------------------------------------------------
datablock DecalData(PlayerFootprint)
{
size = 0.4;
material = CommonPlayerFootprint;
};
datablock DebrisData( PlayerDebris )
{
explodeOnMaxBounce = false;
elasticity = 0.15;
friction = 0.5;
lifetime = 4.0;
lifetimeVariance = 0.0;
minSpinSpeed = 40;
maxSpinSpeed = 600;
numBounces = 5;
bounceVariance = 0;
staticOnMaxBounce = true;
gravModifier = 1.0;
useRadiusMass = true;
baseRadius = 1;
velocity = 20.0;
velocityVariance = 12.0;
};
// ----------------------------------------------------------------------------
// This is our default player datablock that all others will derive from.
// ----------------------------------------------------------------------------
datablock PlayerData(DefaultPlayerData)
{
renderFirstPerson = false;
firstPersonShadows = true;
computeCRC = false;
// Third person shape
shapeFile = "data/FPSGameplay/art/shapes/actors/Soldier/soldier_rigged.DAE";
cameraMaxDist = 3;
allowImageStateAnimation = true;
// First person arms
imageAnimPrefixFP = "soldier";
shapeNameFP[0] = "data/FPSGameplay/art/shapes/actors/Soldier/FP/FP_SoldierArms.DAE";
cmdCategory = "Clients";
cameraDefaultFov = 55.0;
cameraMinFov = 5.0;
cameraMaxFov = 65.0;
debrisShapeName = "data/FPSGameplay/art/shapes/actors/common/debris_player.dts";
debris = playerDebris;
throwForce = 30;
minLookAngle = "-1.4";
maxLookAngle = "0.9";
maxFreelookAngle = 3.0;
mass = 120;
drag = 1.3;
maxdrag = 0.4;
density = 1.1;
maxDamage = 100;
maxEnergy = 60;
repairRate = 0.33;
rechargeRate = 0.256;
runForce = 4320;
runEnergyDrain = 0;
minRunEnergy = 0;
maxForwardSpeed = 8;
maxBackwardSpeed = 6;
maxSideSpeed = 6;
sprintForce = 4320;
sprintEnergyDrain = 0;
minSprintEnergy = 0;
maxSprintForwardSpeed = 14;
maxSprintBackwardSpeed = 8;
maxSprintSideSpeed = 6;
sprintStrafeScale = 0.25;
sprintYawScale = 0.05;
sprintPitchScale = 0.05;
sprintCanJump = true;
crouchForce = 405;
maxCrouchForwardSpeed = 4.0;
maxCrouchBackwardSpeed = 2.0;
maxCrouchSideSpeed = 2.0;
swimForce = 4320;
maxUnderwaterForwardSpeed = 8.4;
maxUnderwaterBackwardSpeed = 7.8;
maxUnderwaterSideSpeed = 4.0;
jumpForce = "747";
jumpEnergyDrain = 0;
minJumpEnergy = 0;
jumpDelay = "15";
airControl = 0.3;
fallingSpeedThreshold = -6.0;
landSequenceTime = 0.33;
transitionToLand = false;
recoverDelay = 0;
recoverRunForceScale = 0;
minImpactSpeed = 10;
minLateralImpactSpeed = 20;
speedDamageScale = 0.4;
boundingBox = "0.65 0.75 1.85";
crouchBoundingBox = "0.65 0.75 1.3";
swimBoundingBox = "1 2 2";
pickupRadius = 1;
// Damage location details
boxHeadPercentage = 0.83;
boxTorsoPercentage = 0.49;
boxHeadLeftPercentage = 0.30;
boxHeadRightPercentage = 0.60;
boxHeadBackPercentage = 0.30;
boxHeadFrontPercentage = 0.60;
// Foot Prints
decalOffset = 0.25;
footPuffEmitter = "LightPuffEmitter";
footPuffNumParts = 10;
footPuffRadius = "0.25";
dustEmitter = "LightPuffEmitter";
splash = PlayerSplash;
splashVelocity = 4.0;
splashAngle = 67.0;
splashFreqMod = 300.0;
splashVelEpsilon = 0.60;
bubbleEmitTime = 0.4;
splashEmitter[0] = PlayerWakeEmitter;
splashEmitter[1] = PlayerFoamEmitter;
splashEmitter[2] = PlayerBubbleEmitter;
mediumSplashSoundVelocity = 10.0;
hardSplashSoundVelocity = 20.0;
exitSplashSoundVelocity = 5.0;
// Controls over slope of runnable/jumpable surfaces
runSurfaceAngle = 38;
jumpSurfaceAngle = 80;
maxStepHeight = 0.35; //two meters
minJumpSpeed = 20;
maxJumpSpeed = 30;
horizMaxSpeed = 68;
horizResistSpeed = 33;
horizResistFactor = 0.35;
upMaxSpeed = 80;
upResistSpeed = 25;
upResistFactor = 0.3;
footstepSplashHeight = 0.35;
//NOTE: some sounds commented out until wav's are available
// Footstep Sounds
FootSoftSound = FootLightSoftSound;
FootHardSound = FootLightHardSound;
FootMetalSound = FootLightMetalSound;
FootSnowSound = FootLightSnowSound;
FootShallowSound = FootLightShallowSplashSound;
FootWadingSound = FootLightWadingSound;
FootUnderwaterSound = FootLightUnderwaterSound;
//FootBubblesSound = FootLightBubblesSound;
//movingBubblesSound = ArmorMoveBubblesSound;
//waterBreathSound = WaterBreathMaleSound;
//impactSoftSound = ImpactLightSoftSound;
//impactHardSound = ImpactLightHardSound;
//impactMetalSound = ImpactLightMetalSound;
//impactSnowSound = ImpactLightSnowSound;
//impactWaterEasy = ImpactLightWaterEasySound;
//impactWaterMedium = ImpactLightWaterMediumSound;
//impactWaterHard = ImpactLightWaterHardSound;
groundImpactMinSpeed = "45";
groundImpactShakeFreq = "4.0 4.0 4.0";
groundImpactShakeAmp = "1.0 1.0 1.0";
groundImpactShakeDuration = 0.8;
groundImpactShakeFalloff = 10.0;
//exitingWater = ExitingWaterLightSound;
observeParameters = "0.5 4.5 4.5";
cameraMinDist = "0";
DecalData = "PlayerFootprint";
// Allowable Inventory Items
mainWeapon = Ryder;
maxInv[Lurker] = 1;
maxInv[LurkerClip] = 20;
maxInv[LurkerGrenadeLauncher] = 1;
maxInv[LurkerGrenadeAmmo] = 20;
maxInv[Ryder] = 1;
maxInv[RyderClip] = 10;
maxInv[ProxMine] = 5;
maxInv[DeployableTurret] = 5;
// available skins (see materials.cs in model folder)
availableSkins = "base DarkBlue DarkGreen LightGreen Orange Red Teal Violet Yellow";
};

View file

@ -0,0 +1,46 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
datablock RibbonNodeData(DefaultRibbonNodeData)
{
timeMultiple = 1.0;
};
//ribbon data////////////////////////////////////////
datablock RibbonData(BasicRibbon)
{
size[0] = 0.5;
color[0] = "1.0 0.0 0.0 1.0";
position[0] = 0.0;
size[1] = 0.0;
color[1] = "1.0 0.0 0.0 0.0";
position[1] = 1.0;
RibbonLength = 40;
fadeAwayStep = 0.1;
UseFadeOut = true;
RibbonMaterial = BasicRibbonMat;
category = "FX";
};

View file

@ -0,0 +1,60 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
datablock RigidShapeData( BouncingBoulder )
{
category = "RigidShape";
shapeFile = "data/FPSGameplay/art/shapes/rocks/boulder.dts";
emap = true;
// Rigid Body
mass = 200;
massCenter = "0 0 0"; // Center of mass for rigid body
massBox = "0 0 0"; // Size of box used for moment of inertia,
// if zero it defaults to object bounding box
drag = 0.2; // Drag coefficient
bodyFriction = 0.2;
bodyRestitution = 0.1;
minImpactSpeed = 5; // Impacts over this invoke the script callback
softImpactSpeed = 5; // Play SoftImpact Sound
hardImpactSpeed = 15; // Play HardImpact Sound
integration = 4; // Physics integration: TickSec/Rate
collisionTol = 0.1; // Collision distance tolerance
contactTol = 0.1; // Contact velocity tolerance
minRollSpeed = 10;
maxDrag = 0.5;
minDrag = 0.01;
triggerDustHeight = 1;
dustHeight = 10;
dragForce = 0.05;
vertFactor = 0.05;
normalForce = 0.05;
restorativeForce = 0.05;
rollForce = 0.05;
pitchForce = 0.05;
};

View file

@ -0,0 +1,22 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------

View file

@ -0,0 +1,176 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// DefaultTrigger is used by the mission editor. This is also an example
// of trigger methods and callbacks.
// A 3D sound played by the server at the location of the
// teleporter after an object has teleported.
datablock SFXProfile(TeleportEntrance)
{
fileName = "data/FPSGameplay/sound/orc_pain";
description = AudioDefault3D;
preload = true;
};
// The 2D sound played by the client after a teleport.
datablock SFXProfile(TeleportSound)
{
fileName = "data/FPSGameplay/sound/orc_death";
description = Audio2D;
preload = true;
};
datablock ParticleData(TeleporterFlash : DefaultParticle)
{
dragCoefficient = "5";
inheritedVelFactor = "0";
constantAcceleration = "0";
lifetimeMS = "500";
spinRandomMin = "-90";
spinRandomMax = "90";
textureName = "data/FPSGameplay/art/particles/flare.png";
animTexName = "data/FPSGameplay/art/particles/flare.png";
colors[0] = "0.678431 0.686275 0.913726 0.207";
colors[1] = "0 0.543307 1 0.759";
colors[2] = "0.0472441 0.181102 0.92126 0.838";
colors[3] = "0.141732 0.0393701 0.944882 0";
sizes[0] = "0";
sizes[1] = "0";
sizes[2] = "4";
sizes[3] = "0.1";
times[1] = "0.166667";
times[2] = "0.666667";
lifetimeVarianceMS = "0";
gravityCoefficient = "-9";
};
datablock ParticleEmitterData(TeleportFlash_Emitter : DefaultEmitter)
{
ejectionVelocity = "0.1";
particles = "TeleporterFlash";
thetaMax = "180";
softnessDistance = "1";
ejectionOffset = "0.417";
};
// Particles to use for the emitter at the teleporter
datablock ParticleData(TeleporterParticles)
{
lifetimeMS = "750";
lifetimeVarianceMS = "100";
textureName = "data/FPSGameplay/art/particles/Streak.png";
useInvAlpha = "0";
gravityCoefficient = "-1";
spinSpeed = "0";
spinRandomMin = "0";
spinRandomMax = "0";
colors[0] = "0.0980392 0.788235 0.92549 1";
colors[1] = "0.0627451 0.478431 0.952941 1";
colors[2] = "0.0509804 0.690196 0.964706 1";
sizes[0] = "1";
sizes[1] = "1";
sizes[2] = "1";
times[0] = 0.0;
times[1] = "0.415686";
times[2] = "0.74902";
animTexName = "data/FPSGameplay/art/particles/Streak.png";
inheritedVelFactor = "0.0998043";
constantAcceleration = "-2";
colors[3] = "0.694118 0.843137 0.945098 0";
sizes[3] = "1";
};
// Particle Emitter to be played when a teleport occours.
datablock ParticleEmitterData(TeleportEmitter)
{
ejectionPeriodMS = "25";
periodVarianceMS = "2";
ejectionVelocity = "0.25";
velocityVariance = "0.1";
ejectionOffset = "0.25";
thetaMin = "90";
thetaMax = "90";
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvance = false;
lifetimeMS = "1000";
particles = "TeleporterParticles";
blendStyle = "ADDITIVE";
};
// Ignore the name "explosion" for this. An Explosion in T3D
// is really an effect that plays a SFXProfile, particle emitters,
// point light, debris, and camera shake. Things normally associated with
// an explosion, such as damage and pushback, are calculated outside of the
// explosion object itself. Because of this, we use an ExplosionDatablock to
// attach visual effects to our teleporter.
datablock ExplosionData(EntranceEffect)
{
soundProfile = TeleportEntrance;
particleEmitter = "TeleportEmitter";
lifeTimeMS = "288";
lightStartRadius = "0";
lightEndRadius = "2.82353";
lightStartColor = "0.992126 0.992126 0.992126 1";
lightEndColor = "0 0.102362 0.992126 1";
lightStartBrightness = "0.784314";
lightEndBrightness = "4";
lightNormalOffset = "0";
emitter[0] = "RocketSplashEmitter";
times[0] = "0.247059";
particleRadius = "0.1";
particleDensity = "10";
playSpeed = "1";
};
datablock TriggerData(TeleporterTrigger : DefaultTrigger)
{
// Amount of time, in milliseconds, to wait before allowing another
// object to use this teleportat.
teleporterCooldown = 0;
// Amount to scale the object's exit velocity. Larger values will
// propel the object with greater force.
exitVelocityScale = 0;
// If true, the object will be oriented to the front
// of the exit teleporter. Otherwise the player will retain their original
// orientation.
reorientPlayer = true;
// If true, the teleporter will only trigger if the object
// enters the front of the teleporter.
oneSided = false;
// Effects to play at the entrance of the teleporter.
entranceEffect = EntranceEffect;
exiteffect = EntranceEffect;
// 2D Sound to play for the client being teleported.
teleportSound = TeleportSound;
};

View file

@ -0,0 +1,38 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// DefaultTrigger is used by the mission editor. This is also an example
// of trigger methods and callbacks.
datablock TriggerData(DefaultTrigger)
{
// The period is value is used to control how often the console
// onTriggerTick callback is called while there are any objects
// in the trigger. The default value is 100 MS.
tickPeriodMS = 100;
};
datablock TriggerData(ClientTrigger : DefaultTrigger)
{
clientSide = true;
};

View file

@ -0,0 +1,391 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
datablock SFXProfile(cheetahEngine)
{
preload = "1";
description = "AudioCloseLoop3D";
fileName = "data/FPSGameplay/sound/cheetah/cheetah_engine.ogg";
};
datablock SFXProfile(cheetahSqueal)
{
preload = "1";
description = "AudioDefault3D";
fileName = "data/FPSGameplay/sound/cheetah/cheetah_squeal.ogg";
};
datablock SFXProfile(hardImpact)
{
preload = "1";
description = "AudioDefault3D";
fileName = "data/FPSGameplay/sound/cheetah/hardImpact.ogg";
};
datablock SFXProfile(softImpact)
{
preload = "1";
description = "AudioDefault3D";
fileName = "data/FPSGameplay/sound/cheetah/softImpact.ogg";
};
datablock SFXProfile(DirtKickup)
{
preload = "1";
description = "AudioDefault3D";
fileName = "data/FPSGameplay/sound/cheetah/softImpact.ogg";
};
datablock SFXProfile(CheetahTurretFireSound)
{
//filename = "data/FPSGameplay/sound/cheetah/turret_firing.wav";
filename = "data/FPSGameplay/sound/turret/wpn_turret_fire.wav";
description = BulletFireDesc;
preload = true;
};
datablock ParticleData(CheetahTireParticle)
{
textureName = "data/FPSGameplay/art/particles/dustParticle";
dragCoefficient = "1.99902";
gravityCoefficient = "-0.100122";
inheritedVelFactor = "0.0998043";
constantAcceleration = 0.0;
lifetimeMS = 1000;
lifetimeVarianceMS = 400;
colors[0] = "0.456693 0.354331 0.259843 1";
colors[1] = "0.456693 0.456693 0.354331 0";
sizes[0] = "0.997986";
sizes[1] = "3.99805";
sizes[2] = "1.0";
sizes[3] = "1.0";
times[0] = "0.0";
times[1] = "1";
times[2] = "1";
times[3] = "1";
};
datablock ParticleEmitterData(CheetahTireEmitter)
{
ejectionPeriodMS = 20;
periodVarianceMS = 10;
ejectionVelocity = "14.57";
velocityVariance = 1.0;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 60;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvance = false;
particles = "CheetahTireParticle";
blendStyle = "ADDITIVE";
};
datablock ProjectileData(TurretProjectile)
{
projectileShapeName = "data/FPSGameplay/art/shapes/weapons/shared/rocket.dts";
directDamage = 10;
radiusDamage = 15;
damageRadius = 3;
areaImpulse = 1200;
explosion = RocketLauncherExplosion;
waterExplosion = RocketLauncherWaterExplosion;
decal = ScorchRXDecal;
splash = RocketSplash;
muzzleVelocity = 250;
velInheritFactor = 0.7;
armingDelay = 0;
lifetime = 5000;
fadeDelay = 4500;
bounceElasticity = 0;
bounceFriction = 0;
isBallistic = false;
gravityMod = 0.80;
damageType = "RocketDamage";
};
datablock ParticleEmitterData(TurretFireSmokeEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 5;
ejectionVelocity = 6.5;
velocityVariance = 1.0;
thetaMin = "0";
thetaMax = "0";
lifetimeMS = 350;
particles = "GunFireSmoke";
blendStyle = "NORMAL";
softParticles = "0";
alignParticles = "0";
orientParticles = "0";
};
datablock ShapeBaseImageData(TurretImage)
{
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/Cheetah/Cheetah_Turret.DAE";
emap = true;
// Specify mount point & offset for 3rd person, and eye offset
// for first person rendering.
mountPoint = 1;
firstPerson = false;
// When firing from a point offset from the eye, muzzle correction
// will adjust the muzzle vector to point to the eye LOS point.
// Since this weapon doesn't actually fire from the muzzle point,
// we need to turn this off.
correctMuzzleVector = false;
// Add the WeaponImage namespace as a parent, WeaponImage namespace
// provides some hooks into the inventory system.
className = "WeaponImage";
class = "WeaponImage";
// Projectile and Ammo
ammo = BulletAmmo;
projectile = TurretProjectile;
projectileType = Projectile;
projectileSpread = "0.01";
// Weapon lights up while firing
lightColor = "0.992126 0.968504 0.708661 1";
lightRadius = "4";
lightDuration = "100";
lightType = "WeaponFireLight";
lightBrightness = 2;
// Shake camera while firing.
shakeCamera = false;
// Images have a state system which controls how the animations
// are run, which sounds are played, script callbacks, etc. This
// state system is downloaded to the client so that clients can
// predict state changes and animate accordingly. The following
// system supports basic ready->fire->reload transitions as
// well as a no-ammo->dryfire idle state.
useRemainderDT = true;
// Initial start up state
stateName[0] = "Preactivate";
stateTransitionOnLoaded[0] = "Activate";
stateTransitionOnNoAmmo[0] = "NoAmmo";
// Activating the gun. Called when the weapon is first
// mounted and there is ammo.
stateName[1] = "Activate";
stateTransitionOnTimeout[1] = "Ready";
stateTimeoutValue[1] = 0.5;
stateSequence[1] = "Activate";
// Ready to fire, just waiting for the trigger
stateName[2] = "Ready";
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "Fire";
// Fire the weapon. Calls the fire script which does
// the actual work.
stateName[3] = "Fire";
stateTransitionOnTimeout[3] = "Reload";
stateTimeoutValue[3] = 0.1;
stateFire[3] = true;
stateRecoil[3] = "";
stateAllowImageChange[3] = false;
stateSequence[3] = "Fire";
stateSequenceRandomFlash[3] = true; // use muzzle flash sequence
stateScript[3] = "onFire";
stateSound[3] = CheetahTurretFireSound;
stateEmitter[3] = TurretFireSmokeEmitter;
stateEmitterTime[3] = 0.025;
// Play the reload animation, and transition into
stateName[4] = "Reload";
stateTransitionOnNoAmmo[4] = "NoAmmo";
stateWaitForTimeout[4] = "0";
stateTransitionOnTimeout[4] = "Ready";
stateTimeoutValue[4] = 1.2;
stateAllowImageChange[4] = false;
stateSequence[4] = "Reload";
//stateEjectShell[4] = true;
// No ammo in the weapon, just idle until something
// shows up. Play the dry fire sound if the trigger is
// pulled.
stateName[5] = "NoAmmo";
stateTransitionOnAmmo[5] = "Reload";
stateSequence[5] = "NoAmmo";
stateTransitionOnTriggerDown[5] = "DryFire";
// No ammo dry fire
stateName[6] = "DryFire";
stateTimeoutValue[6] = 1.0;
stateTransitionOnTimeout[6] = "NoAmmo";
stateScript[6] = "onDryFire";
};
//-----------------------------------------------------------------------------
// Information extacted from the shape.
//
// Wheel Sequences
// spring# Wheel spring motion: time 0 = wheel fully extended,
// the hub must be displaced, but not directly animated
// as it will be rotated in code.
// Other Sequences
// steering Wheel steering: time 0 = full right, 0.5 = center
// breakLight Break light, time 0 = off, 1 = breaking
//
// Wheel Nodes
// hub# Wheel hub, the hub must be in it's upper position
// from which the springs are mounted.
//
// The steering and animation sequences are optional.
// The center of the shape acts as the center of mass for the car.
//-----------------------------------------------------------------------------
datablock WheeledVehicleTire(CheetahCarTire)
{
// Tires act as springs and generate lateral and longitudinal
// forces to move the vehicle. These distortion/spring forces
// are what convert wheel angular velocity into forces that
// act on the rigid body.
shapeFile = "data/FPSGameplay/art/shapes/Cheetah/wheel.DAE";
staticFriction = 4.2;
kineticFriction = "1";
// Spring that generates lateral tire forces
lateralForce = 18000;
lateralDamping = 6000;
lateralRelaxation = 1;
// Spring that generates longitudinal tire forces
longitudinalForce = 18000;
longitudinalDamping = 4000;
longitudinalRelaxation = 1;
radius = "0.609998";
};
datablock WheeledVehicleTire(CheetahCarTireRear)
{
// Tires act as springs and generate lateral and longitudinal
// forces to move the vehicle. These distortion/spring forces
// are what convert wheel angular velocity into forces that
// act on the rigid body.
shapeFile = "data/FPSGameplay/art/shapes/Cheetah/wheelBack.DAE";
staticFriction = "7.2";
kineticFriction = "1";
// Spring that generates lateral tire forces
lateralForce = "19000";
lateralDamping = 6000;
lateralRelaxation = 1;
// Spring that generates longitudinal tire forces
longitudinalForce = 18000;
longitudinalDamping = 4000;
longitudinalRelaxation = 1;
radius = "0.840293";
};
datablock WheeledVehicleSpring(CheetahCarSpring)
{
// Wheel suspension properties
length = 0.5; // Suspension travel
force = 2800; // Spring force
damping = 3600; // Spring damping
antiSwayForce = 3; // Lateral anti-sway force
};
datablock WheeledVehicleData(CheetahCar)
{
category = "Vehicles";
shapeFile = "data/FPSGameplay/art/shapes/Cheetah/Cheetah_Body.DAE";
emap = 1;
mountPose[0] = sitting;
numMountPoints = 6;
useEyePoint = true; // Use the vehicle's camera node rather than the player's
maxSteeringAngle = 0.585; // Maximum steering angle, should match animation
// 3rd person camera settings
cameraRoll = false; // Roll the camera with the vehicle
cameraMaxDist = 7.8; // Far distance from vehicle
cameraOffset = 1.0; // Vertical offset from camera mount point
cameraLag = "0.3"; // Velocity lag of camera
cameraDecay = 1.25; // Decay per sec. rate of velocity lag
// Rigid Body
mass = "400";
massCenter = "0 0.5 0"; // Center of mass for rigid body
massBox = "0 0 0"; // Size of box used for moment of inertia,
// if zero it defaults to object bounding box
drag = 0.6; // Drag coefficient
bodyFriction = 0.6;
bodyRestitution = 0.4;
minImpactSpeed = 5; // Impacts over this invoke the script callback
softImpactSpeed = 5; // Play SoftImpact Sound
hardImpactSpeed = 15; // Play HardImpact Sound
integration = 8; // Physics integration: TickSec/Rate
collisionTol = "0.1"; // Collision distance tolerance
contactTol = "0.4"; // Contact velocity tolerance
// Engine
engineTorque = 4300; // Engine power
engineBrake = "5000"; // Braking when throttle is 0
brakeTorque = "10000"; // When brakes are applied
maxWheelSpeed = 50; // Engine scale by current speed / max speed
// Energy
maxEnergy = 100;
jetForce = 3000;
minJetEnergy = 30;
jetEnergyDrain = 2;
// Sounds
engineSound = cheetahEngine;
//squealSound = cheetahSqueal;
softImpactSound = softImpact;
hardImpactSound = hardImpact;
// Dynamic fields accessed via script
nameTag = 'Cheetah';
maxDismountSpeed = 10;
maxMountSpeed = 5;
mountPose0 = "sitting";
tireEmitter = "CheetahTireEmitter";
dustEmitter = "CheetahTireEmitter";
dustHeight = "1";
// Mount slots
turretSlot = 1;
rightBrakeSlot = 2;
leftBrakeSlot = 3;
};

View file

@ -0,0 +1,48 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// This file contains 'generic' datablocks usable by all weapon class items.
// ----------------------------------------------------------------------------
// Audio profiles
// ----------------------------------------------------------------------------
datablock SFXProfile(WeaponUseSound)
{
filename = "data/FPSGameplay/sound/weapons/Weapon_switch";
description = AudioClose3d;
preload = true;
};
datablock SFXProfile(WeaponPickupSound)
{
filename = "data/FPSGameplay/sound/weapons/Weapon_pickup";
description = AudioClose3d;
preload = true;
};
datablock SFXProfile(AmmoPickupSound)
{
filename = "data/FPSGameplay/sound/weapons/Ammo_pickup";
description = AudioClose3d;
preload = true;
};

View file

@ -0,0 +1,819 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Sounds
//--------------------------------------------------------------------------
datablock SFXProfile(LurkerFireSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_lurker_fire";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile(LurkerReloadSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_lurker_reload";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile(LurkerIdleSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_lurker_idle";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile(LurkerSwitchinSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_lurker_switchin";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile(LurkerGrenadeFireSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_lurker_grenadelaunch";
description = AudioClose3D;
preload = true;
};
datablock SFXPlayList(LurkerFireSoundList)
{
// Use a looped description so the list playback will loop.
description = AudioClose3D;
track[ 0 ] = LurkerFireSound;
};
/*datablock SFXProfile(BulletImpactSound)
{
filename = "data/FPSGameplay/sound/weapons/SCARFIRE";
description = AudioClose3D;
preload = true;
};*/
// ----------------------------------------------------------------------------
// Particles
// ----------------------------------------------------------------------------
datablock ParticleData(GunFireSmoke)
{
textureName = "data/FPSGameplay/art/particles/smoke";
dragCoefficient = 0;
gravityCoefficient = "-1";
windCoefficient = 0;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 500;
lifetimeVarianceMS = 200;
spinRandomMin = -180.0;
spinRandomMax = 180.0;
useInvAlpha = true;
colors[0] = "0.795276 0.795276 0.795276 0.692913";
colors[1] = "0.866142 0.866142 0.866142 0.346457";
colors[2] = "0.897638 0.834646 0.795276 0";
sizes[0] = "0.399805";
sizes[1] = "1.19941";
sizes[2] = "1.69993";
times[0] = 0.0;
times[1] = "0.498039";
times[2] = 1.0;
animTexName = "data/FPSGameplay/art/particles/smoke";
};
datablock ParticleEmitterData(GunFireSmokeEmitter)
{
ejectionPeriodMS = 20;
periodVarianceMS = 10;
ejectionVelocity = "0";
velocityVariance = "0";
thetaMin = "0";
thetaMax = "0";
lifetimeMS = 250;
particles = "GunFireSmoke";
blendStyle = "NORMAL";
softParticles = "0";
originalName = "GunFireSmokeEmitter";
alignParticles = "0";
orientParticles = "0";
};
datablock ParticleData(BulletDirtDust)
{
textureName = "data/FPSGameplay/art/particles/impact";
dragCoefficient = "1";
gravityCoefficient = "-0.100122";
windCoefficient = 0;
inheritedVelFactor = 0.0;
constantAcceleration = "-0.83";
lifetimeMS = 800;
lifetimeVarianceMS = 300;
spinRandomMin = -180.0;
spinRandomMax = 180.0;
useInvAlpha = true;
colors[0] = "0.496063 0.393701 0.299213 0.692913";
colors[1] = "0.692913 0.614173 0.535433 0.346457";
colors[2] = "0.897638 0.84252 0.795276 0";
sizes[0] = "0.997986";
sizes[1] = "2";
sizes[2] = "2.5";
times[0] = 0.0;
times[1] = "0.498039";
times[2] = 1.0;
animTexName = "data/FPSGameplay/art/particles/impact";
};
datablock ParticleEmitterData(BulletDirtDustEmitter)
{
ejectionPeriodMS = 20;
periodVarianceMS = 10;
ejectionVelocity = "1";
velocityVariance = 1.0;
thetaMin = 0.0;
thetaMax = 180.0;
lifetimeMS = 250;
particles = "BulletDirtDust";
blendStyle = "NORMAL";
};
//-----------------------------------------------------------------------------
// Explosion
//-----------------------------------------------------------------------------
datablock ExplosionData(BulletDirtExplosion)
{
soundProfile = BulletImpactSound;
lifeTimeMS = 65;
// Volume particles
particleEmitter = BulletDirtDustEmitter;
particleDensity = 4;
particleRadius = 0.3;
// Point emission
emitter[0] = BulletDirtSprayEmitter;
emitter[1] = BulletDirtSprayEmitter;
emitter[2] = BulletDirtRocksEmitter;
};
//--------------------------------------------------------------------------
// Shell ejected during reload.
//-----------------------------------------------------------------------------
datablock DebrisData(BulletShell)
{
shapeFile = "data/FPSGameplay/art/shapes/weapons/shared/RifleShell.DAE";
lifetime = 6.0;
minSpinSpeed = 300.0;
maxSpinSpeed = 400.0;
elasticity = 0.65;
friction = 0.05;
numBounces = 5;
staticOnMaxBounce = true;
snapOnMaxBounce = false;
ignoreWater = true;
fade = true;
};
//-----------------------------------------------------------------------------
// Projectile Object
//-----------------------------------------------------------------------------
datablock LightDescription( BulletProjectileLightDesc )
{
color = "0.0 0.5 0.7";
range = 3.0;
};
datablock ProjectileData( BulletProjectile )
{
projectileShapeName = "";
directDamage = 5;
radiusDamage = 0;
damageRadius = 0.5;
areaImpulse = 0.5;
impactForce = 1;
explosion = BulletDirtExplosion;
decal = BulletHoleDecal;
muzzleVelocity = 120;
velInheritFactor = 1;
armingDelay = 0;
lifetime = 992;
fadeDelay = 1472;
bounceElasticity = 0;
bounceFriction = 0;
isBallistic = false;
gravityMod = 1;
};
function BulletProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
// Apply impact force from the projectile.
// Apply damage to the object all shape base objects
if ( %col.getType() & $TypeMasks::GameBaseObjectType )
%col.damage(%obj,%pos,%this.directDamage,"BulletProjectile");
}
//-----------------------------------------------------------------------------
// Ammo Item
//-----------------------------------------------------------------------------
datablock ItemData(LurkerClip)
{
// Mission editor category
category = "AmmoClip";
// Add the Ammo namespace as a parent. The ammo namespace provides
// common ammo related functions and hooks into the inventory system.
className = "AmmoClip";
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Lurker/TP_Lurker.DAE";
mass = 1;
elasticity = 0.2;
friction = 0.6;
// Dynamic properties defined by the scripts
pickUpName = "Lurker clip";
count = 1;
maxInventory = 10;
};
datablock ItemData(LurkerAmmo)
{
// Mission editor category
category = "Ammo";
// Add the Ammo namespace as a parent. The ammo namespace provides
// common ammo related functions and hooks into the inventory system.
className = "Ammo";
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Lurker/TP_Lurker.DAE";
mass = 1;
elasticity = 0.2;
friction = 0.6;
// Dynamic properties defined by the scripts
pickUpName = "Lurker ammo";
maxInventory = 30;
clip = LurkerClip;
};
//--------------------------------------------------------------------------
// Weapon Item. This is the item that exists in the world, i.e. when it's
// been dropped, thrown or is acting as re-spawnable item. When the weapon
// is mounted onto a shape, the LurkerWeaponImage is used.
//-----------------------------------------------------------------------------
datablock ItemData(Lurker)
{
// Mission editor category
category = "Weapon";
// Hook into Item Weapon class hierarchy. The weapon namespace
// provides common weapon handling functions in addition to hooks
// into the inventory system.
className = "Weapon";
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Lurker/TP_Lurker.DAE";
mass = 1;
elasticity = 0.2;
friction = 0.6;
emap = true;
// Dynamic properties defined by the scripts
PreviewImage = 'lurker.png';
pickUpName = "Lurker rifle";
description = "Lurker";
image = LurkerWeaponImage;
reticle = "crossHair";
};
datablock ShapeBaseImageData(LurkerWeaponImage)
{
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Lurker/TP_Lurker.DAE";
shapeFileFP = "data/FPSGameplay/art/shapes/weapons/Lurker/FP_Lurker.DAE";
emap = true;
imageAnimPrefix = "Rifle";
imageAnimPrefixFP = "Rifle";
// Specify mount point & offset for 3rd person, and eye offset
// for first person rendering.
mountPoint = 0;
firstPerson = true;
useEyeNode = true;
animateOnServer = true;
// When firing from a point offset from the eye, muzzle correction
// will adjust the muzzle vector to point to the eye LOS point.
// Since this weapon doesn't actually fire from the muzzle point,
// we need to turn this off.
correctMuzzleVector = true;
// Add the WeaponImage namespace as a parent, WeaponImage namespace
// provides some hooks into the inventory system.
class = "WeaponImage";
className = "WeaponImage";
// Projectiles and Ammo.
item = Lurker;
ammo = LurkerAmmo;
clip = LurkerClip;
projectile = BulletProjectile;
projectileType = Projectile;
projectileSpread = "0.005";
altProjectile = GrenadeLauncherProjectile;
altProjectileSpread = "0.02";
casing = BulletShell;
shellExitDir = "1.0 0.3 1.0";
shellExitOffset = "0.15 -0.56 -0.1";
shellExitVariance = 15.0;
shellVelocity = 3.0;
// Weapon lights up while firing
lightType = "WeaponFireLight";
lightColor = "0.992126 0.968504 0.708661 1";
lightRadius = "4";
lightDuration = "100";
lightBrightness = 2;
// Shake camera while firing.
shakeCamera = false;
camShakeFreq = "0 0 0";
camShakeAmp = "0 0 0";
// Images have a state system which controls how the animations
// are run, which sounds are played, script callbacks, etc. This
// state system is downloaded to the client so that clients can
// predict state changes and animate accordingly. The following
// system supports basic ready->fire->reload transitions as
// well as a no-ammo->dryfire idle state.
useRemainderDT = true;
// Initial start up state
stateName[0] = "Preactivate";
stateTransitionOnLoaded[0] = "Activate";
stateTransitionOnNoAmmo[0] = "NoAmmo";
// Activating the gun. Called when the weapon is first
// mounted and there is ammo.
stateName[1] = "Activate";
stateTransitionGeneric0In[1] = "SprintEnter";
stateTransitionOnTimeout[1] = "Ready";
stateTimeoutValue[1] = 0.5;
stateSequence[1] = "switch_in";
stateSound[1] = LurkerSwitchinSound;
// Ready to fire, just waiting for the trigger
stateName[2] = "Ready";
stateTransitionGeneric0In[2] = "SprintEnter";
stateTransitionOnMotion[2] = "ReadyMotion";
stateTransitionOnTimeout[2] = "ReadyFidget";
stateTimeoutValue[2] = 10;
stateWaitForTimeout[2] = false;
stateScaleAnimation[2] = false;
stateScaleAnimationFP[2] = false;
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "Fire";
stateSequence[2] = "idle";
// Same as Ready state but plays a fidget sequence
stateName[3] = "ReadyFidget";
stateTransitionGeneric0In[3] = "SprintEnter";
stateTransitionOnMotion[3] = "ReadyMotion";
stateTransitionOnTimeout[3] = "Ready";
stateTimeoutValue[3] = 6;
stateWaitForTimeout[3] = false;
stateTransitionOnNoAmmo[3] = "NoAmmo";
stateTransitionOnTriggerDown[3] = "Fire";
stateSequence[3] = "idle_fidget1";
stateSound[3] = LurkerIdleSound;
// Ready to fire with player moving
stateName[4] = "ReadyMotion";
stateTransitionGeneric0In[4] = "SprintEnter";
stateTransitionOnNoMotion[4] = "Ready";
stateWaitForTimeout[4] = false;
stateScaleAnimation[4] = false;
stateScaleAnimationFP[4] = false;
stateSequenceTransitionIn[4] = true;
stateSequenceTransitionOut[4] = true;
stateTransitionOnNoAmmo[4] = "NoAmmo";
stateTransitionOnTriggerDown[4] = "Fire";
stateSequence[4] = "run";
// Fire the weapon. Calls the fire script which does
// the actual work.
stateName[5] = "Fire";
stateTransitionGeneric0In[5] = "SprintEnter";
stateTransitionOnTimeout[5] = "NewRound";
stateTimeoutValue[5] = 0.15;
stateFire[5] = true;
stateRecoil[5] = "";
stateAllowImageChange[5] = false;
stateSequence[5] = "fire";
stateScaleAnimation[5] = false;
stateSequenceNeverTransition[5] = true;
stateSequenceRandomFlash[5] = true; // use muzzle flash sequence
stateScript[5] = "onFire";
stateSound[5] = LurkerFireSoundList;
stateEmitter[5] = GunFireSmokeEmitter;
stateEmitterTime[5] = 0.025;
// Put another round into the chamber if one is available
stateName[6] = "NewRound";
stateTransitionGeneric0In[6] = "SprintEnter";
stateTransitionOnNoAmmo[6] = "NoAmmo";
stateTransitionOnTimeout[6] = "Ready";
stateWaitForTimeout[6] = "0";
stateTimeoutValue[6] = 0.05;
stateAllowImageChange[6] = false;
stateEjectShell[6] = true;
// No ammo in the weapon, just idle until something
// shows up. Play the dry fire sound if the trigger is
// pulled.
stateName[7] = "NoAmmo";
stateTransitionGeneric0In[7] = "SprintEnter";
stateTransitionOnMotion[7] = "NoAmmoMotion";
stateTransitionOnAmmo[7] = "ReloadClip";
stateTimeoutValue[7] = 0.1; // Slight pause to allow script to run when trigger is still held down from Fire state
stateScript[7] = "onClipEmpty";
stateSequence[7] = "idle";
stateScaleAnimation[7] = false;
stateScaleAnimationFP[7] = false;
stateTransitionOnTriggerDown[7] = "DryFire";
stateName[8] = "NoAmmoMotion";
stateTransitionGeneric0In[8] = "SprintEnter";
stateTransitionOnNoMotion[8] = "NoAmmo";
stateWaitForTimeout[8] = false;
stateScaleAnimation[8] = false;
stateScaleAnimationFP[8] = false;
stateSequenceTransitionIn[8] = true;
stateSequenceTransitionOut[8] = true;
stateTransitionOnTriggerDown[8] = "DryFire";
stateTransitionOnAmmo[8] = "ReloadClip";
stateSequence[8] = "run";
// No ammo dry fire
stateName[9] = "DryFire";
stateTransitionGeneric0In[9] = "SprintEnter";
stateTransitionOnAmmo[9] = "ReloadClip";
stateWaitForTimeout[9] = "0";
stateTimeoutValue[9] = 0.7;
stateTransitionOnTimeout[9] = "NoAmmo";
stateScript[9] = "onDryFire";
stateSound[9] = MachineGunDryFire;
// Play the reload clip animation
stateName[10] = "ReloadClip";
stateTransitionGeneric0In[10] = "SprintEnter";
stateTransitionOnTimeout[10] = "Ready";
stateWaitForTimeout[10] = true;
stateTimeoutValue[10] = 3.0;
stateReload[10] = true;
stateSequence[10] = "reload";
stateShapeSequence[10] = "Reload";
stateScaleShapeSequence[10] = true;
stateSound[10] = LurkerReloadSound;
// Start Sprinting
stateName[11] = "SprintEnter";
stateTransitionGeneric0Out[11] = "SprintExit";
stateTransitionOnTimeout[11] = "Sprinting";
stateWaitForTimeout[11] = false;
stateTimeoutValue[11] = 0.5;
stateWaitForTimeout[11] = false;
stateScaleAnimation[11] = false;
stateScaleAnimationFP[11] = false;
stateSequenceTransitionIn[11] = true;
stateSequenceTransitionOut[11] = true;
stateAllowImageChange[11] = false;
stateSequence[11] = "sprint";
// Sprinting
stateName[12] = "Sprinting";
stateTransitionGeneric0Out[12] = "SprintExit";
stateWaitForTimeout[12] = false;
stateScaleAnimation[12] = false;
stateScaleAnimationFP[12] = false;
stateSequenceTransitionIn[12] = true;
stateSequenceTransitionOut[12] = true;
stateAllowImageChange[12] = false;
stateSequence[12] = "sprint";
// Stop Sprinting
stateName[13] = "SprintExit";
stateTransitionGeneric0In[13] = "SprintEnter";
stateTransitionOnTimeout[13] = "Ready";
stateWaitForTimeout[13] = false;
stateTimeoutValue[13] = 0.5;
stateSequenceTransitionIn[13] = true;
stateSequenceTransitionOut[13] = true;
stateAllowImageChange[13] = false;
stateSequence[13] = "sprint";
};
//--------------------------------------------------------------------------
// Lurker Grenade Launcher
//--------------------------------------------------------------------------
datablock ItemData(LurkerGrenadeAmmo)
{
// Mission editor category
category = "Ammo";
// Add the Ammo namespace as a parent. The ammo namespace provides
// common ammo related functions and hooks into the inventory system.
className = "Ammo";
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Lurker/TP_Lurker.DAE";
mass = 1;
elasticity = 0.2;
friction = 0.6;
// Dynamic properties defined by the scripts
pickUpName = "Lurker grenade ammo";
maxInventory = 20;
};
datablock ItemData(LurkerGrenadeLauncher)
{
// Mission editor category
category = "Weapon";
// Hook into Item Weapon class hierarchy. The weapon namespace
// provides common weapon handling functions in addition to hooks
// into the inventory system.
className = "Weapon";
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Lurker/TP_Lurker.DAE";
mass = 1;
elasticity = 0.2;
friction = 0.6;
emap = true;
// Dynamic properties defined by the scripts
PreviewImage = 'lurker.png';
pickUpName = "a Lurker grenade launcher";
description = "Lurker Grenade Launcher";
image = LurkerGrenadeLauncherImage;
reticle = "crossHair";
};
datablock ShapeBaseImageData(LurkerGrenadeLauncherImage)
{
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Lurker/TP_Lurker.DAE";
shapeFileFP = "data/FPSGameplay/art/shapes/weapons/Lurker/FP_Lurker.DAE";
emap = true;
imageAnimPrefix = "Rifle";
imageAnimPrefixFP = "Rifle";
// Specify mount point & offset for 3rd person, and eye offset
// for first person rendering.
mountPoint = 0;
firstPerson = true;
useEyeNode = true;
animateOnServer = true;
// When firing from a point offset from the eye, muzzle correction
// will adjust the muzzle vector to point to the eye LOS point.
// Since this weapon doesn't actually fire from the muzzle point,
// we need to turn this off.
correctMuzzleVector = true;
// Add the WeaponImage namespace as a parent, WeaponImage namespace
// provides some hooks into the inventory system.
class = "WeaponImage";
className = "WeaponImage";
// Projectiles and Ammo.
item = LurkerGrenadeLauncher;
ammo = LurkerGrenadeAmmo;
projectile = GrenadeLauncherProjectile;
projectileType = Projectile;
projectileSpread = "0.02";
// Weapon lights up while firing
lightType = "WeaponFireLight";
lightColor = "0.992126 0.968504 0.708661 1";
lightRadius = "4";
lightDuration = "100";
lightBrightness = 2;
// Shake camera while firing.
shakeCamera = false;
camShakeFreq = "0 0 0";
camShakeAmp = "0 0 0";
// Images have a state system which controls how the animations
// are run, which sounds are played, script callbacks, etc. This
// state system is downloaded to the client so that clients can
// predict state changes and animate accordingly. The following
// system supports basic ready->fire->reload transitions as
// well as a no-ammo->dryfire idle state.
useRemainderDT = true;
// Initial start up state
stateName[0] = "Preactivate";
stateTransitionOnLoaded[0] = "Activate";
stateTransitionOnNoAmmo[0] = "NoAmmo";
// Activating the gun. Called when the weapon is first
// mounted and there is ammo.
stateName[1] = "Activate";
stateTransitionGeneric0In[1] = "SprintEnter";
stateTransitionOnTimeout[1] = "Ready";
stateTimeoutValue[1] = 0.5;
stateSequence[1] = "switch_in";
stateSound[1] = LurkerSwitchinSound;
// Ready to fire, just waiting for the trigger
stateName[2] = "Ready";
stateTransitionGeneric0In[2] = "SprintEnter";
stateTransitionOnMotion[2] = "ReadyMotion";
stateTransitionOnTimeout[2] = "ReadyFidget";
stateTimeoutValue[2] = 10;
stateWaitForTimeout[2] = false;
stateScaleAnimation[2] = false;
stateScaleAnimationFP[2] = false;
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "Fire";
stateSequence[2] = "idle";
// Same as Ready state but plays a fidget sequence
stateName[3] = "ReadyFidget";
stateTransitionGeneric0In[3] = "SprintEnter";
stateTransitionOnMotion[3] = "ReadyMotion";
stateTransitionOnTimeout[3] = "Ready";
stateTimeoutValue[3] = 6;
stateWaitForTimeout[3] = false;
stateTransitionOnNoAmmo[3] = "NoAmmo";
stateTransitionOnTriggerDown[3] = "Fire";
stateSequence[3] = "idle_fidget1";
stateSound[3] = LurkerIdleSound;
// Ready to fire with player moving
stateName[4] = "ReadyMotion";
stateTransitionGeneric0In[4] = "SprintEnter";
stateTransitionOnNoMotion[4] = "Ready";
stateWaitForTimeout[4] = false;
stateScaleAnimation[4] = false;
stateScaleAnimationFP[4] = false;
stateSequenceTransitionIn[4] = true;
stateSequenceTransitionOut[4] = true;
stateTransitionOnNoAmmo[4] = "NoAmmo";
stateTransitionOnTriggerDown[4] = "Fire";
stateSequence[4] = "run";
// Fire the weapon. Calls the fire script which does
// the actual work.
stateName[5] = "Fire";
stateTransitionGeneric0In[5] = "SprintEnter";
stateTransitionOnTimeout[5] = "NewRound";
stateTimeoutValue[5] = 1.2;
stateFire[5] = true;
stateRecoil[5] = "";
stateAllowImageChange[5] = false;
stateSequence[5] = "fire_alt";
stateScaleAnimation[5] = true;
stateSequenceNeverTransition[5] = true;
stateSequenceRandomFlash[5] = true; // use muzzle flash sequence
stateScript[5] = "onFire";
stateSound[5] = LurkerGrenadeFireSound;
stateEmitter[5] = GunFireSmokeEmitter;
stateEmitterTime[5] = 0.025;
stateEjectShell[5] = true;
// Put another round into the chamber
stateName[6] = "NewRound";
stateTransitionGeneric0In[6] = "SprintEnter";
stateTransitionOnNoAmmo[6] = "NoAmmo";
stateTransitionOnTimeout[6] = "Ready";
stateWaitForTimeout[6] = "0";
stateTimeoutValue[6] = 0.05;
stateAllowImageChange[6] = false;
// No ammo in the weapon, just idle until something
// shows up. Play the dry fire sound if the trigger is
// pulled.
stateName[7] = "NoAmmo";
stateTransitionGeneric0In[7] = "SprintEnter";
stateTransitionOnMotion[7] = "NoAmmoReadyMotion";
stateTransitionOnAmmo[7] = "ReloadClip";
stateTimeoutValue[7] = 0.1; // Slight pause to allow script to run when trigger is still held down from Fire state
stateScript[7] = "onClipEmpty";
stateSequence[7] = "idle";
stateScaleAnimation[7] = false;
stateScaleAnimationFP[7] = false;
stateTransitionOnTriggerDown[7] = "DryFire";
stateName[8] = "NoAmmoReadyMotion";
stateTransitionGeneric0In[8] = "SprintEnter";
stateTransitionOnNoMotion[8] = "NoAmmo";
stateWaitForTimeout[8] = false;
stateScaleAnimation[8] = false;
stateScaleAnimationFP[8] = false;
stateSequenceTransitionIn[8] = true;
stateSequenceTransitionOut[8] = true;
stateTransitionOnAmmo[8] = "ReloadClip";
stateTransitionOnTriggerDown[8] = "DryFire";
stateSequence[8] = "run";
// No ammo dry fire
stateName[9] = "DryFire";
stateTransitionGeneric0In[9] = "SprintEnter";
stateTimeoutValue[9] = 1.0;
stateTransitionOnTimeout[9] = "NoAmmo";
stateScript[9] = "onDryFire";
// Play the reload clip animation
stateName[10] = "ReloadClip";
stateTransitionGeneric0In[10] = "SprintEnter";
stateTransitionOnTimeout[10] = "Ready";
stateWaitForTimeout[10] = true;
stateTimeoutValue[10] = 3.0;
stateReload[10] = true;
stateSequence[10] = "reload";
stateShapeSequence[10] = "Reload";
stateScaleShapeSequence[10] = true;
// Start Sprinting
stateName[11] = "SprintEnter";
stateTransitionGeneric0Out[11] = "SprintExit";
stateTransitionOnTimeout[11] = "Sprinting";
stateWaitForTimeout[11] = false;
stateTimeoutValue[11] = 0.5;
stateWaitForTimeout[11] = false;
stateScaleAnimation[11] = false;
stateScaleAnimationFP[11] = false;
stateSequenceTransitionIn[11] = true;
stateSequenceTransitionOut[11] = true;
stateAllowImageChange[11] = false;
stateSequence[11] = "sprint";
// Sprinting
stateName[12] = "Sprinting";
stateTransitionGeneric0Out[12] = "SprintExit";
stateWaitForTimeout[12] = false;
stateScaleAnimation[12] = false;
stateScaleAnimationFP[12] = false;
stateSequenceTransitionIn[12] = true;
stateSequenceTransitionOut[12] = true;
stateAllowImageChange[12] = false;
stateSequence[12] = "sprint";
// Stop Sprinting
stateName[13] = "SprintExit";
stateTransitionGeneric0In[13] = "SprintEnter";
stateTransitionOnTimeout[13] = "Ready";
stateWaitForTimeout[13] = false;
stateTimeoutValue[13] = 0.5;
stateSequenceTransitionIn[13] = true;
stateSequenceTransitionOut[13] = true;
stateAllowImageChange[13] = false;
stateSequence[13] = "sprint";
};

View file

@ -0,0 +1,402 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Sounds
//--------------------------------------------------------------------------
// Added for Lesson 5 - Adding Weapons - 23 Sep 11
datablock SFXProfile(WeaponTemplateFireSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_fire";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile(WeaponTemplateReloadSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_reload";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile(WeaponTemplateSwitchinSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_switchin";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile(WeaponTemplateIdleSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_idle";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile(WeaponTemplateGrenadeSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_grenadelaunch";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile(WeaponTemplateMineSwitchinSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_mine_switchin";
description = AudioClose3D;
preload = true;
};
//-----------------------------------------------------------------------------
// Added 28 Sep 11
datablock LightDescription( BulletProjectileLightDesc )
{
color = "0.0 0.5 0.7";
range = 3.0;
};
datablock ProjectileData( BulletProjectile )
{
projectileShapeName = "";
directDamage = 5;
radiusDamage = 0;
damageRadius = 0.5;
areaImpulse = 0.5;
impactForce = 1;
explosion = BulletDirtExplosion;
decal = BulletHoleDecal;
muzzleVelocity = 120;
velInheritFactor = 1;
armingDelay = 0;
lifetime = 992;
fadeDelay = 1472;
bounceElasticity = 0;
bounceFriction = 0;
isBallistic = false;
gravityMod = 1;
};
function BulletProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
// Apply impact force from the projectile.
// Apply damage to the object all shape base objects
if ( %col.getType() & $TypeMasks::GameBaseObjectType )
%col.damage(%obj,%pos,%this.directDamage,"BulletProjectile");
}
//-----------------------------------------------------------------------------
datablock ProjectileData( WeaponTemplateProjectile )
{
projectileShapeName = "";
directDamage = 5;
radiusDamage = 0;
damageRadius = 0.5;
areaImpulse = 0.5;
impactForce = 1;
muzzleVelocity = 120;
velInheritFactor = 1;
armingDelay = 0;
lifetime = 992;
fadeDelay = 1472;
bounceElasticity = 0;
bounceFriction = 0;
isBallistic = false;
gravityMod = 1;
};
function WeaponTemplateProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
// Apply impact force from the projectile.
// Apply damage to the object all shape base objects
if ( %col.getType() & $TypeMasks::GameBaseObjectType )
%col.damage(%obj,%pos,%this.directDamage,"WeaponTemplateProjectile");
}
//-----------------------------------------------------------------------------
// Ammo Item
//-----------------------------------------------------------------------------
datablock ItemData(WeaponTemplateAmmo)
{
// Mission editor category
category = "Ammo";
// Add the Ammo namespace as a parent. The ammo namespace provides
// common ammo related functions and hooks into the inventory system.
className = "Ammo";
// Basic Item properties
shapeFile = "";
mass = 1;
elasticity = 0.2;
friction = 0.6;
// Dynamic properties defined by the scripts
pickUpName = "";
maxInventory = 1000;
};
//--------------------------------------------------------------------------
// Weapon Item. This is the item that exists in the world, i.e. when it's
// been dropped, thrown or is acting as re-spawnable item. When the weapon
// is mounted onto a shape, the NewWeaponTemplate is used.
//-----------------------------------------------------------------------------
datablock ItemData(WeaponTemplateItem)
{
// Mission editor category
category = "Weapon";
// Hook into Item Weapon class hierarchy. The weapon namespace
// provides common weapon handling functions in addition to hooks
// into the inventory system.
className = "Weapon";
// Basic Item properties
shapeFile = "";
mass = 1;
elasticity = 0.2;
friction = 0.6;
emap = true;
// Dynamic properties defined by the scripts
pickUpName = "A basic weapon";
description = "Weapon";
image = WeaponTemplateImage;
reticle = "crossHair";
};
datablock ShapeBaseImageData(WeaponTemplateImage)
{
// FP refers to first person specific features
// Defines what art file to use.
shapeFile = "data/FPSGameplay/art/shapes/weapons/Lurker/TP_Lurker.DAE";
shapeFileFP = "data/FPSGameplay/art/shapes/weapons/Lurker/FP_Lurker.DAE";
// Whether or not to enable environment mapping
//emap = true;
//imageAnimPrefixFP = "";
// Specify mount point & offset for 3rd person, and eye offset
// for first person rendering.
mountPoint = 0;
//firstPerson = true;
//eyeOffset = "0.001 -0.05 -0.065";
// When firing from a point offset from the eye, muzzle correction
// will adjust the muzzle vector to point to the eye LOS point.
// Since this weapon doesn't actually fire from the muzzle point,
// we need to turn this off.
//correctMuzzleVector = true;
// Add the WeaponImage namespace as a parent, WeaponImage namespace
// provides some hooks into the inventory system.
class = "WeaponImage";
className = "WeaponImage";
// Projectiles and Ammo.
item = WeaponTemplateItem;
ammo = WeaponTemplateAmmo;
//projectile = BulletProjectile;
//projectileType = Projectile;
//projectileSpread = "0.005";
// Properties associated with the shell casing that gets ejected during firing
//casing = BulletShell;
//shellExitDir = "1.0 0.3 1.0";
//shellExitOffset = "0.15 -0.56 -0.1";
//shellExitVariance = 15.0;
//shellVelocity = 3.0;
// Properties associated with a light that occurs when the weapon fires
//lightType = "";
//lightColor = "0.992126 0.968504 0.708661 1";
//lightRadius = "4";
//lightDuration = "100";
//lightBrightness = 2;
// Properties associated with shaking the camera during firing
//shakeCamera = false;
//camShakeFreq = "0 0 0";
//camShakeAmp = "0 0 0";
// Images have a state system which controls how the animations
// are run, which sounds are played, script callbacks, etc. This
// state system is downloaded to the client so that clients can
// predict state changes and animate accordingly. The following
// system supports basic ready->fire->reload transitions as
// well as a no-ammo->dryfire idle state.
// If true, allow multiple timeout transitions to occur within a single tick
// useful if states have a very small timeout
//useRemainderDT = true;
// Initial start up state
stateName[0] = "Preactivate";
stateTransitionOnLoaded[0] = "Activate";
stateTransitionOnNoAmmo[0] = "NoAmmo";
// Activating the gun. Called when the weapon is first
// mounted and there is ammo.
stateName[1] = "Activate";
stateTransitionGeneric0In[1] = "SprintEnter";
stateTransitionOnTimeout[1] = "Ready";
stateTimeoutValue[1] = 0.5;
stateSequence[1] = "switch_in";
// Ready to fire, just waiting for the trigger
stateName[2] = "Ready";
stateTransitionGeneric0In[2] = "SprintEnter";
stateTransitionOnMotion[2] = "ReadyMotion";
stateTransitionOnTimeout[2] = "ReadyFidget";
stateTimeoutValue[2] = 10;
stateWaitForTimeout[2] = false;
stateScaleAnimation[2] = false;
stateScaleAnimationFP[2] = false;
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "Fire";
stateSequence[2] = "idle";
// Same as Ready state but plays a fidget sequence
stateName[3] = "ReadyFidget";
stateTransitionGeneric0In[3] = "SprintEnter";
stateTransitionOnMotion[3] = "ReadyMotion";
stateTransitionOnTimeout[3] = "Ready";
stateTimeoutValue[3] = 6;
stateWaitForTimeout[3] = false;
stateTransitionOnNoAmmo[3] = "NoAmmo";
stateTransitionOnTriggerDown[3] = "Fire";
stateSequence[3] = "idle_fidget1";
// Ready to fire with player moving
stateName[4] = "ReadyMotion";
stateTransitionGeneric0In[4] = "SprintEnter";
stateTransitionOnNoMotion[4] = "Ready";
stateWaitForTimeout[4] = false;
stateScaleAnimation[4] = false;
stateScaleAnimationFP[4] = false;
stateSequenceTransitionIn[4] = true;
stateSequenceTransitionOut[4] = true;
stateTransitionOnNoAmmo[4] = "NoAmmo";
stateTransitionOnTriggerDown[4] = "Fire";
stateSequence[4] = "run";
// Fire the weapon. Calls the fire script which does
// the actual work.
stateName[5] = "Fire";
stateTransitionGeneric0In[5] = "SprintEnter";
stateTransitionOnTimeout[5] = "Reload";
stateTimeoutValue[5] = 0.15;
stateFire[5] = true;
stateRecoil[5] = "";
stateAllowImageChange[5] = false;
stateSequence[5] = "fire";
stateScaleAnimation[5] = false;
stateSequenceNeverTransition[5] = true;
stateSequenceRandomFlash[5] = true; // use muzzle flash sequence
stateScript[5] = "onFire";
stateSound[5] = WeaponTemplateFireSound;
stateEmitter[5] = GunFireSmokeEmitter;
stateEmitterTime[5] = 0.025;
// Play the reload animation, and transition into
stateName[6] = "Reload";
stateTransitionGeneric0In[6] = "SprintEnter";
stateTransitionOnNoAmmo[6] = "NoAmmo";
stateTransitionOnTimeout[6] = "Ready";
stateWaitForTimeout[6] = "0";
stateTimeoutValue[6] = 0.05;
stateAllowImageChange[6] = false;
//stateSequence[6] = "reload";
stateEjectShell[6] = true;
// No ammo in the weapon, just idle until something
// shows up. Play the dry fire sound if the trigger is
// pulled.
stateName[7] = "NoAmmo";
stateTransitionGeneric0In[7] = "SprintEnter";
stateTransitionOnAmmo[7] = "ReloadClip";
stateScript[7] = "onClipEmpty";
// No ammo dry fire
stateName[8] = "DryFire";
stateTransitionGeneric0In[8] = "SprintEnter";
stateTimeoutValue[8] = 1.0;
stateTransitionOnTimeout[8] = "NoAmmo";
stateScript[8] = "onDryFire";
// Play the reload clip animation
stateName[9] = "ReloadClip";
stateTransitionGeneric0In[9] = "SprintEnter";
stateTransitionOnTimeout[9] = "Ready";
stateWaitForTimeout[9] = true;
stateTimeoutValue[9] = 3.0;
stateReload[9] = true;
stateSequence[9] = "reload";
stateShapeSequence[9] = "Reload";
stateScaleShapeSequence[9] = true;
// Start Sprinting
stateName[10] = "SprintEnter";
stateTransitionGeneric0Out[10] = "SprintExit";
stateTransitionOnTimeout[10] = "Sprinting";
stateWaitForTimeout[10] = false;
stateTimeoutValue[10] = 0.5;
stateWaitForTimeout[10] = false;
stateScaleAnimation[10] = false;
stateScaleAnimationFP[10] = false;
stateSequenceTransitionIn[10] = true;
stateSequenceTransitionOut[10] = true;
stateAllowImageChange[10] = false;
stateSequence[10] = "sprint";
// Sprinting
stateName[11] = "Sprinting";
stateTransitionGeneric0Out[11] = "SprintExit";
stateWaitForTimeout[11] = false;
stateScaleAnimation[11] = false;
stateScaleAnimationFP[11] = false;
stateSequenceTransitionIn[11] = true;
stateSequenceTransitionOut[11] = true;
stateAllowImageChange[11] = false;
stateSequence[11] = "sprint";
// Stop Sprinting
stateName[12] = "SprintExit";
stateTransitionGeneric0In[12] = "SprintEnter";
stateTransitionOnTimeout[12] = "Ready";
stateWaitForTimeout[12] = false;
stateTimeoutValue[12] = 0.5;
stateSequenceTransitionIn[12] = true;
stateSequenceTransitionOut[12] = true;
stateAllowImageChange[12] = false;
stateSequence[12] = "sprint";
};

View file

@ -0,0 +1,230 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
datablock SFXProfile( MineArmedSound )
{
filename = "data/FPSGameplay/sound/weapons/mine_armed";
description = AudioClose3d;
preload = true;
};
datablock SFXProfile( MineSwitchinSound )
{
filename = "data/FPSGameplay/sound/weapons/wpn_proximitymine_switchin";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile( MineTriggeredSound )
{
filename = "data/FPSGameplay/sound/weapons/mine_trigger";
description = AudioClose3d;
preload = true;
};
datablock ProximityMineData( ProxMine )
{
// ShapeBaseData fields
category = "Weapon";
shapeFile = "data/FPSGameplay/art/shapes/weapons/ProxMine/TP_ProxMine.DAE";
explosion = GrenadeLauncherExplosion;
// ItemData fields
sticky = true;
mass = 2;
elasticity = 0.2;
friction = 0.6;
simpleServerCollision = false;
// ProximityMineData fields
armingDelay = 3.5;
armingSound = MineArmedSound;
autoTriggerDelay = 0;
triggerOnOwner = true;
triggerRadius = 3.0;
triggerDelay = 0.45;
triggerSound = MineTriggeredSound;
explosionOffset = 0.1;
// dynamic fields
pickUpName = "a proximity mine";
description = "Proximity Mine";
maxInventory = 20;
image = ProxMineImage;
previewImage = 'mine.png';
reticle = 'blank';
zoomReticle = 'blank';
damageType = "MineDamage"; // type of damage applied to objects in radius
radiusDamage = 300; // amount of damage to apply to objects in radius
damageRadius = 8; // search radius to damage objects when exploding
areaImpulse = 2000; // magnitude of impulse to apply to objects in radius
};
datablock ShapeBaseImageData( ProxMineImage )
{
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/ProxMine/TP_ProxMine.DAE";
shapeFileFP = "data/FPSGameplay/art/shapes/weapons/ProxMine/FP_ProxMine.DAE";
imageAnimPrefix = "ProxMine";
imageAnimPrefixFP = "ProxMine";
// Specify mount point & offset for 3rd person, and eye offset
// for first person rendering.
mountPoint = 0;
firstPerson = true;
useEyeNode = true;
// When firing from a point offset from the eye, muzzle correction
// will adjust the muzzle vector to point to the eye LOS point.
// Since this weapon doesn't actually fire from the muzzle point,
// we need to turn this off.
correctMuzzleVector = false;
// Add the WeaponImage namespace as a parent, WeaponImage namespace
// provides some hooks into the inventory system.
class = "WeaponImage";
className = "WeaponImage";
// Projectiles and Ammo.
item = ProxMine;
// Shake camera while firing.
shakeCamera = false;
camShakeFreq = "0 0 0";
camShakeAmp = "0 0 0";
// Images have a state system which controls how the animations
// are run, which sounds are played, script callbacks, etc. This
// state system is downloaded to the client so that clients can
// predict state changes and animate accordingly. The following
// system supports basic ready->fire->reload transitions as
// well as a no-ammo->dryfire idle state.
// Initial start up state
stateName[0] = "Preactivate";
stateTransitionOnLoaded[0] = "Activate";
stateTransitionOnNoAmmo[0] = "Activate";
// Activating the gun. Called when the weapon is first
// mounted and there is ammo.
stateName[1] = "Activate";
stateTransitionGeneric0In[1] = "SprintEnter";
stateTransitionOnTimeout[1] = "Ready";
stateTimeoutValue[1] = 3.0;
stateSequence[1] = "switch_in";
stateShapeSequence[1] = "Reload";
stateSound[1] = MineSwitchinSound;
// Ready to fire, just waiting for the trigger
stateName[2] = "Ready";
stateTransitionGeneric0In[2] = "SprintEnter";
stateTransitionOnMotion[2] = "ReadyMotion";
stateTransitionOnTriggerDown[2] = "Fire";
stateScaleAnimation[2] = false;
stateScaleAnimationFP[2] = false;
stateSequence[2] = "idle";
// Ready to fire with player moving
stateName[3] = "ReadyMotion";
stateTransitionGeneric0In[3] = "SprintEnter";
stateTransitionOnNoMotion[3] = "Ready";
stateScaleAnimation[3] = false;
stateScaleAnimationFP[3] = false;
stateSequenceTransitionIn[3] = true;
stateSequenceTransitionOut[3] = true;
stateTransitionOnTriggerDown[3] = "Fire";
stateSequence[3] = "run";
// Wind up to throw the ProxMine
stateName[4] = "Fire";
stateTransitionGeneric0In[4] = "SprintEnter";
stateTransitionOnTimeout[4] = "Fire2";
stateTimeoutValue[4] = 0.8;
stateFire[4] = true;
stateRecoil[4] = "";
stateAllowImageChange[4] = false;
stateSequence[4] = "Fire";
stateSequenceNeverTransition[4] = true;
stateShapeSequence[4] = "Fire";
// Throw the actual mine
stateName[5] = "Fire2";
stateTransitionGeneric0In[5] = "SprintEnter";
stateTransitionOnTriggerUp[5] = "Reload";
stateTimeoutValue[5] = 0.7;
stateAllowImageChange[5] = false;
stateSequenceNeverTransition[5] = true;
stateSequence[5] = "fire_release";
stateShapeSequence[5] = "Fire_Release";
stateScript[5] = "onFire";
// Play the reload animation, and transition into
stateName[6] = "Reload";
stateTransitionGeneric0In[6] = "SprintEnter";
stateTransitionOnTimeout[6] = "Ready";
stateWaitForTimeout[6] = true;
stateTimeoutValue[6] = 3.0;
stateSequence[6] = "switch_in";
stateShapeSequence[6] = "Reload";
stateSound[6] = MineSwitchinSound;
// Start Sprinting
stateName[7] = "SprintEnter";
stateTransitionGeneric0Out[7] = "SprintExit";
stateTransitionOnTimeout[7] = "Sprinting";
stateWaitForTimeout[7] = false;
stateTimeoutValue[7] = 0.25;
stateWaitForTimeout[7] = false;
stateScaleAnimation[7] = true;
stateScaleAnimationFP[7] = true;
stateSequenceTransitionIn[7] = true;
stateSequenceTransitionOut[7] = true;
stateAllowImageChange[7] = false;
stateSequence[7] = "run2sprint";
// Sprinting
stateName[8] = "Sprinting";
stateTransitionGeneric0Out[8] = "SprintExit";
stateWaitForTimeout[8] = false;
stateScaleAnimation[8] = false;
stateScaleAnimationFP[8] = false;
stateSequenceTransitionIn[8] = true;
stateSequenceTransitionOut[8] = true;
stateAllowImageChange[8] = false;
stateSequence[8] = "sprint";
// Stop Sprinting
stateName[9] = "SprintExit";
stateTransitionGeneric0In[9] = "SprintEnter";
stateTransitionOnTimeout[9] = "Ready";
stateWaitForTimeout[9] = false;
stateTimeoutValue[9] = 0.5;
stateSequenceTransitionIn[9] = true;
stateSequenceTransitionOut[9] = true;
stateAllowImageChange[9] = false;
stateSequence[9] = "sprint2run";
};

View file

@ -0,0 +1,365 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Sounds
//--------------------------------------------------------------------------
datablock SFXProfile(RyderFireSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_ryder_fire";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile(RyderReloadSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_ryder_reload";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile(RyderSwitchinSound)
{
filename = "data/FPSGameplay/sound/weapons/wpn_ryder_switchin";
description = AudioClose3D;
preload = true;
};
// ----------------------------------------------------------------------------
// Particles
// ----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Explosion
//-----------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Shell ejected during reload.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Projectile Object
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Ammo Item
//-----------------------------------------------------------------------------
datablock ItemData(RyderClip)
{
// Mission editor category
category = "AmmoClip";
// Add the Ammo namespace as a parent. The ammo namespace provides
// common ammo related functions and hooks into the inventory system.
className = "AmmoClip";
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Ryder/TP_Ryder.DAE";
mass = 1;
elasticity = 0.2;
friction = 0.6;
// Dynamic properties defined by the scripts
pickUpName = "Ryder clip";
count = 1;
maxInventory = 10;
};
datablock ItemData(RyderAmmo)
{
// Mission editor category
category = "Ammo";
// Add the Ammo namespace as a parent. The ammo namespace provides
// common ammo related functions and hooks into the inventory system.
className = "Ammo";
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Ryder/TP_Ryder.DAE";
mass = 1;
elasticity = 0.2;
friction = 0.6;
// Dynamic properties defined by the scripts
pickUpName = "Ryder bullet";
maxInventory = 8;
clip = RyderClip;
};
//--------------------------------------------------------------------------
// Weapon Item. This is the item that exists in the world, i.e. when it's
// been dropped, thrown or is acting as re-spawnable item. When the weapon
// is mounted onto a shape, the SoldierWeaponImage is used.
//-----------------------------------------------------------------------------
datablock ItemData(Ryder)
{
// Mission editor category
category = "Weapon";
// Hook into Item Weapon class hierarchy. The weapon namespace
// provides common weapon handling functions in addition to hooks
// into the inventory system.
className = "Weapon";
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Ryder/TP_Ryder.DAE";
mass = 1;
elasticity = 0.2;
friction = 0.6;
emap = true;
PreviewImage = 'ryder.png';
// Dynamic properties defined by the scripts
pickUpName = "Ryder pistol";
description = "Ryder";
image = RyderWeaponImage;
reticle = "crossHair";
};
datablock ShapeBaseImageData(RyderWeaponImage)
{
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Ryder/TP_Ryder.DAE";
shapeFileFP = "data/FPSGameplay/art/shapes/weapons/Ryder/FP_Ryder.DAE";
emap = true;
imageAnimPrefix = "Pistol";
imageAnimPrefixFP = "Pistol";
// Specify mount point & offset for 3rd person, and eye offset
// for first person rendering.
mountPoint = 0;
firstPerson = true;
useEyeNode = true;
animateOnServer = true;
// When firing from a point offset from the eye, muzzle correction
// will adjust the muzzle vector to point to the eye LOS point.
// Since this weapon doesn't actually fire from the muzzle point,
// we need to turn this off.
correctMuzzleVector = true;
// Add the WeaponImage namespace as a parent, WeaponImage namespace
// provides some hooks into the inventory system.
class = "WeaponImage";
className = "WeaponImage";
// Projectiles and Ammo.
item = Ryder;
ammo = RyderAmmo;
clip = RyderClip;
projectile = BulletProjectile;
projectileType = Projectile;
projectileSpread = "0.0";
altProjectile = GrenadeLauncherProjectile;
altProjectileSpread = "0.02";
casing = BulletShell;
shellExitDir = "1.0 0.3 1.0";
shellExitOffset = "0.15 -0.56 -0.1";
shellExitVariance = 15.0;
shellVelocity = 3.0;
// Weapon lights up while firing
lightType = "WeaponFireLight";
lightColor = "0.992126 0.968504 0.700787 1";
lightRadius = "4";
lightDuration = "100";
lightBrightness = 2;
// Shake camera while firing.
shakeCamera = "1";
camShakeFreq = "10 10 10";
camShakeAmp = "5 5 5";
// Images have a state system which controls how the animations
// are run, which sounds are played, script callbacks, etc. This
// state system is downloaded to the client so that clients can
// predict state changes and animate accordingly. The following
// system supports basic ready->fire->reload transitions as
// well as a no-ammo->dryfire idle state.
useRemainderDT = true;
// Initial start up state
stateName[0] = "Preactivate";
stateTransitionOnLoaded[0] = "Activate";
stateTransitionOnNoAmmo[0] = "NoAmmo";
// Activating the gun. Called when the weapon is first
// mounted and there is ammo.
stateName[1] = "Activate";
stateTransitionGeneric0In[1] = "SprintEnter";
stateTransitionOnTimeout[1] = "Ready";
stateTimeoutValue[1] = 1.5;
stateSequence[1] = "switch_in";
stateSound[1] = RyderSwitchinSound;
// Ready to fire, just waiting for the trigger
stateName[2] = "Ready";
stateTransitionGeneric0In[2] = "SprintEnter";
stateTransitionOnMotion[2] = "ReadyMotion";
stateScaleAnimation[2] = false;
stateScaleAnimationFP[2] = false;
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "Fire";
stateSequence[2] = "idle";
// Ready to fire with player moving
stateName[3] = "ReadyMotion";
stateTransitionGeneric0In[3] = "SprintEnter";
stateTransitionOnNoMotion[3] = "Ready";
stateWaitForTimeout[3] = false;
stateScaleAnimation[3] = false;
stateScaleAnimationFP[3] = false;
stateSequenceTransitionIn[3] = true;
stateSequenceTransitionOut[3] = true;
stateTransitionOnNoAmmo[3] = "NoAmmo";
stateTransitionOnTriggerDown[3] = "Fire";
stateSequence[3] = "run";
// Fire the weapon. Calls the fire script which does
// the actual work.
stateName[4] = "Fire";
stateTransitionGeneric0In[4] = "SprintEnter";
stateTransitionOnTimeout[4] = "WaitForRelease";
stateTimeoutValue[4] = 0.23;
stateWaitForTimeout[4] = true;
stateFire[4] = true;
stateRecoil[4] = "";
stateAllowImageChange[4] = false;
stateSequence[4] = "fire";
stateScaleAnimation[4] = true;
stateSequenceNeverTransition[4] = true;
stateSequenceRandomFlash[4] = true; // use muzzle flash sequence
stateScript[4] = "onFire";
stateEmitter[4] = GunFireSmokeEmitter;
stateEmitterTime[4] = 0.025;
stateEjectShell[4] = true;
stateSound[4] = RyderFireSound;
// Wait for the player to release the trigger
stateName[5] = "WaitForRelease";
stateTransitionGeneric0In[5] = "SprintEnter";
stateTransitionOnTriggerUp[5] = "NewRound";
stateTimeoutValue[5] = 0.05;
stateWaitForTimeout[5] = true;
stateAllowImageChange[5] = false;
// Put another round in the chamber
stateName[6] = "NewRound";
stateTransitionGeneric0In[6] = "SprintEnter";
stateTransitionOnNoAmmo[6] = "NoAmmo";
stateTransitionOnTimeout[6] = "Ready";
stateWaitForTimeout[6] = "0";
stateTimeoutValue[6] = 0.05;
stateAllowImageChange[6] = false;
// No ammo in the weapon, just idle until something
// shows up. Play the dry fire sound if the trigger is
// pulled.
stateName[7] = "NoAmmo";
stateTransitionGeneric0In[7] = "SprintEnter";
stateTransitionOnMotion[7] = "NoAmmoMotion";
stateTransitionOnAmmo[7] = "ReloadClip";
stateTimeoutValue[7] = 0.1; // Slight pause to allow script to run when trigger is still held down from Fire state
stateScript[7] = "onClipEmpty";
stateTransitionOnTriggerDown[7] = "DryFire";
stateSequence[7] = "idle";
stateScaleAnimation[7] = false;
stateScaleAnimationFP[7] = false;
stateName[8] = "NoAmmoMotion";
stateTransitionGeneric0In[8] = "SprintEnter";
stateTransitionOnNoMotion[8] = "NoAmmo";
stateWaitForTimeout[8] = false;
stateScaleAnimation[8] = false;
stateScaleAnimationFP[8] = false;
stateSequenceTransitionIn[8] = true;
stateSequenceTransitionOut[8] = true;
stateTransitionOnAmmo[8] = "ReloadClip";
stateTransitionOnTriggerDown[8] = "DryFire";
stateSequence[8] = "run";
// No ammo dry fire
stateName[9] = "DryFire";
stateTransitionGeneric0In[9] = "SprintEnter";
stateTransitionOnAmmo[9] = "ReloadClip";
stateWaitForTimeout[9] = "0";
stateTimeoutValue[9] = 0.7;
stateTransitionOnTimeout[9] = "NoAmmo";
stateScript[9] = "onDryFire";
// Play the reload clip animation
stateName[10] = "ReloadClip";
stateTransitionGeneric0In[10] = "SprintEnter";
stateTransitionOnTimeout[10] = "Ready";
stateWaitForTimeout[10] = true;
stateTimeoutValue[10] = 2.0;
stateReload[10] = true;
stateSequence[10] = "reload";
stateShapeSequence[10] = "Reload";
stateScaleShapeSequence[10] = true;
stateSound[10] = RyderReloadSound;
// Start Sprinting
stateName[11] = "SprintEnter";
stateTransitionGeneric0Out[11] = "SprintExit";
stateTransitionOnTimeout[11] = "Sprinting";
stateWaitForTimeout[11] = false;
stateTimeoutValue[11] = 0.5;
stateWaitForTimeout[11] = false;
stateScaleAnimation[11] = false;
stateScaleAnimationFP[11] = false;
stateSequenceTransitionIn[11] = true;
stateSequenceTransitionOut[11] = true;
stateAllowImageChange[11] = false;
stateSequence[11] = "sprint";
// Sprinting
stateName[12] = "Sprinting";
stateTransitionGeneric0Out[12] = "SprintExit";
stateWaitForTimeout[12] = false;
stateScaleAnimation[12] = false;
stateScaleAnimationFP[12] = false;
stateSequenceTransitionIn[12] = true;
stateSequenceTransitionOut[12] = true;
stateAllowImageChange[12] = false;
stateSequence[12] = "sprint";
// Stop Sprinting
stateName[13] = "SprintExit";
stateTransitionGeneric0In[13] = "SprintEnter";
stateTransitionOnTimeout[13] = "Ready";
stateWaitForTimeout[13] = false;
stateTimeoutValue[13] = 0.5;
stateSequenceTransitionIn[13] = true;
stateSequenceTransitionOut[13] = true;
stateAllowImageChange[13] = false;
stateSequence[13] = "sprint";
camShakeDuration = "0.2";
};

View file

@ -0,0 +1,559 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
datablock SFXProfile(TargetAquiredSound)
{
filename = "";
description = AudioClose3D;
preload = false;
};
datablock SFXProfile(TargetLostSound)
{
filename = "";
description = AudioClose3D;
preload = false;
};
datablock SFXProfile(TurretDestroyed)
{
filename = "";
description = AudioClose3D;
preload = false;
};
datablock SFXProfile(TurretThrown)
{
filename = "";
description = AudioClose3D;
preload = false;
};
datablock SFXProfile(TurretFireSound)
{
filename = "data/FPSGameplay/sound/turret/wpn_turret_fire";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile(TurretActivatedSound)
{
filename = "data/FPSGameplay/sound/turret/wpn_turret_deploy";
description = AudioClose3D;
preload = true;
};
datablock SFXProfile(TurretScanningSound)
{
filename = "data/FPSGameplay/sound/turret/wpn_turret_scan";
description = AudioCloseLoop3D;
preload = true;
};
datablock SFXProfile(TurretSwitchinSound)
{
filename = "data/FPSGameplay/sound/turret/wpn_turret_switchin";
description = AudioClose3D;
preload = true;
};
//-----------------------------------------------------------------------------
// Turret Bullet Projectile
//-----------------------------------------------------------------------------
datablock ProjectileData( TurretBulletProjectile )
{
projectileShapeName = "";
directDamage = 5;
radiusDamage = 0;
damageRadius = 0.5;
areaImpulse = 0.5;
impactForce = 1;
damageType = "TurretDamage"; // Type of damage applied by this weapon
explosion = BulletDirtExplosion;
decal = BulletHoleDecal;
muzzleVelocity = 120;
velInheritFactor = 1;
armingDelay = 0;
lifetime = 992;
fadeDelay = 1472;
bounceElasticity = 0;
bounceFriction = 0;
isBallistic = false;
gravityMod = 1;
};
function TurretBulletProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
// Apply impact force from the projectile.
// Apply damage to the object all shape base objects
if ( %col.getType() & $TypeMasks::GameBaseObjectType )
%col.damage(%obj,%pos,%this.directDamage,%this.damageType);
}
//-----------------------------------------------------------------------------
// Turret Bullet Ammo
//-----------------------------------------------------------------------------
datablock ItemData(AITurretAmmo)
{
// Mission editor category
category = "Ammo";
// Add the Ammo namespace as a parent. The ammo namespace provides
// common ammo related functions and hooks into the inventory system.
className = "Ammo";
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Turret/Turret_Legs.DAE";
mass = 1;
elasticity = 0.2;
friction = 0.6;
// Dynamic properties defined by the scripts
pickUpName = "turret ammo";
};
//-----------------------------------------------------------------------------
// AI Turret Weapon
//-----------------------------------------------------------------------------
datablock ItemData(AITurretHead)
{
// Mission editor category
category = "Weapon";
// Hook into Item Weapon class hierarchy. The weapon namespace
// provides common weapon handling functions in addition to hooks
// into the inventory system.
className = "Weapon";
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Turret/Turret_Head.DAE";
mass = 1;
elasticity = 0.2;
friction = 0.6;
emap = true;
// Dynamic properties defined by the scripts
pickUpName = "an AI turret head";
description = "AI Turret Head";
image = AITurretHeadImage;
reticle = "crossHair";
};
datablock ShapeBaseImageData(AITurretHeadImage)
{
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Turret/Turret_Head.DAE";
emap = true;
// Specify mount point
mountPoint = 0;
// Add the WeaponImage namespace as a parent, WeaponImage namespace
// provides some hooks into the inventory system.
class = "WeaponImage";
className = "WeaponImage";
// Projectiles and Ammo.
item = AITurretHead;
ammo = AITurretAmmo;
projectile = TurretBulletProjectile;
projectileType = Projectile;
projectileSpread = "0.02";
casing = BulletShell;
shellExitDir = "1.0 0.3 1.0";
shellExitOffset = "0.15 -0.56 -0.1";
shellExitVariance = 15.0;
shellVelocity = 3.0;
// Weapon lights up while firing
lightType = "WeaponFireLight";
lightColor = "0.992126 0.968504 0.708661 1";
lightRadius = "4";
lightDuration = "100";
lightBrightness = 2;
// Shake camera while firing.
shakeCamera = false;
camShakeFreq = "0 0 0";
camShakeAmp = "0 0 0";
// Images have a state system which controls how the animations
// are run, which sounds are played, script callbacks, etc. This
// state system is downloaded to the client so that clients can
// predict state changes and animate accordingly. The following
// system supports basic ready->fire->reload transitions as
// well as a no-ammo->dryfire idle state.
useRemainderDT = true;
// Initial start up state
stateName[0] = "Preactivate";
stateIgnoreLoadedForReady[0] = false;
stateTransitionOnLoaded[0] = "Activate";
stateTransitionOnNotLoaded[0] = "WaitingDeployment"; // If the turret weapon is not loaded then it has not yet been deployed
stateTransitionOnNoAmmo[0] = "NoAmmo";
// Activating the gun. Called when the weapon is first
// mounted and there is ammo.
stateName[1] = "Activate";
stateTransitionGeneric0In[1] = "Destroyed";
stateTransitionOnTimeout[1] = "Ready";
stateTimeoutValue[1] = 0.5;
stateSequence[1] = "Activate";
// Ready to fire, just waiting for the trigger
stateName[2] = "Ready";
stateTransitionGeneric0In[2] = "Destroyed";
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "Fire";
stateSequence[2] = "scan";
// Fire the weapon. Calls the fire script which does
// the actual work.
stateName[3] = "Fire";
stateTransitionGeneric0In[3] = "Destroyed";
stateTransitionOnTimeout[3] = "Reload";
stateTimeoutValue[3] = 0.2;
stateFire[3] = true;
stateRecoil[3] = "LightRecoil";
stateAllowImageChange[3] = false;
stateSequence[3] = "fire";
stateSequenceRandomFlash[3] = true; // use muzzle flash sequence
stateScript[3] = "onFire";
stateSound[3] = TurretFireSound;
stateEmitter[3] = GunFireSmokeEmitter;
stateEmitterTime[3] = 0.025;
stateEjectShell[3] = true;
// Play the reload animation, and transition into
stateName[4] = "Reload";
stateTransitionGeneric0In[4] = "Destroyed";
stateTransitionOnNoAmmo[4] = "NoAmmo";
stateTransitionOnTimeout[4] = "Ready";
stateWaitForTimeout[4] = "0";
stateTimeoutValue[4] = 0.0;
stateAllowImageChange[4] = false;
stateSequence[4] = "Reload";
// No ammo in the weapon, just idle until something
// shows up. Play the dry fire sound if the trigger is
// pulled.
stateName[5] = "NoAmmo";
stateTransitionGeneric0In[5] = "Destroyed";
stateTransitionOnAmmo[5] = "Reload";
stateSequence[5] = "NoAmmo";
stateTransitionOnTriggerDown[5] = "DryFire";
// No ammo dry fire
stateName[6] = "DryFire";
stateTransitionGeneric0In[6] = "Destroyed";
stateTimeoutValue[6] = 1.0;
stateTransitionOnTimeout[6] = "NoAmmo";
stateScript[6] = "onDryFire";
// Waiting for the turret to be deployed
stateName[7] = "WaitingDeployment";
stateTransitionGeneric0In[7] = "Destroyed";
stateTransitionOnLoaded[7] = "Deployed";
stateSequence[7] = "wait_deploy";
// Turret has been deployed
stateName[8] = "Deployed";
stateTransitionGeneric0In[8] = "Destroyed";
stateTransitionOnTimeout[8] = "Ready";
stateWaitForTimeout[8] = true;
stateTimeoutValue[8] = 2.5; // Same length as turret base's Deploy state
stateSequence[8] = "deploy";
// Turret has been destroyed
stateName[9] = "Destroyed";
stateSequence[9] = "destroyed";
};
//-----------------------------------------------------------------------------
// AI Turret
//-----------------------------------------------------------------------------
datablock AITurretShapeData(AITurret)
{
category = "Turrets";
shapeFile = "data/FPSGameplay/art/shapes/weapons/Turret/Turret_Legs.DAE";
maxDamage = 70;
destroyedLevel = 70;
explosion = GrenadeExplosion;
simpleServerCollision = false;
zRotOnly = false;
// Rotation settings
minPitch = 15;
maxPitch = 80;
maxHeading = 90;
headingRate = 50;
pitchRate = 50;
// Scan settings
maxScanPitch = 10;
maxScanHeading = 30;
maxScanDistance = 20;
trackLostTargetTime = 2;
maxWeaponRange = 30;
weaponLeadVelocity = 0;
// Weapon mounting
numWeaponMountPoints = 1;
weapon[0] = AITurretHead;
weaponAmmo[0] = AITurretAmmo;
weaponAmmoAmount[0] = 10000;
maxInv[AITurretHead] = 1;
maxInv[AITurretAmmo] = 10000;
// Initial start up state
stateName[0] = "Preactivate";
stateTransitionOnAtRest[0] = "Scanning";
stateTransitionOnNotAtRest[0] = "Thrown";
// Scan for targets
stateName[1] = "Scanning";
stateScan[1] = true;
stateTransitionOnTarget[1] = "Target";
stateSequence[1] = "scan";
stateScript[1] = "OnScanning";
// Have a target
stateName[2] = "Target";
stateTransitionOnNoTarget[2] = "NoTarget";
stateTransitionOnTimeout[2] = "Firing";
stateTimeoutValue[2] = 2.0;
stateScript[2] = "OnTarget";
// Fire at target
stateName[3] = "Firing";
stateFire[3] = true;
stateTransitionOnNoTarget[3] = "NoTarget";
stateScript[3] = "OnFiring";
// Lost target
stateName[4] = "NoTarget";
stateTransitionOnTimeout[4] = "Scanning";
stateTimeoutValue[4] = 2.0;
stateScript[4] = "OnNoTarget";
// Player thrown turret
stateName[5] = "Thrown";
stateTransitionOnAtRest[5] = "Deploy";
stateSequence[5] = "throw";
stateScript[5] = "OnThrown";
// Player thrown turret is deploying
stateName[6] = "Deploy";
stateTransitionOnTimeout[6] = "Scanning";
stateTimeoutValue[6] = 2.5;
stateSequence[6] = "deploy";
stateScaleAnimation[6] = true;
stateScript[6] = "OnDeploy";
// Special state that is set when the turret is destroyed.
// This state is set in the onDestroyed() callback.
stateName[7] = "Destroyed";
stateSequence[7] = "destroyed";
};
//-----------------------------------------------------------------------------
// Deployable AI Turret
//-----------------------------------------------------------------------------
datablock AITurretShapeData(DeployableTurret : AITurret)
{
// Mission editor category
category = "Weapon";
className = "DeployableTurretWeapon";
startLoaded = false;
// Basic Item properties
mass = 1.5;
elasticity = 0.1;
friction = 0.6;
simpleServerCollision = false;
// Dynamic properties defined by the scripts
PreviewImage = 'turret.png';
pickUpName = "a deployable turret";
description = "Deployable Turret";
image = DeployableTurretImage;
reticle = "blank";
zoomReticle = 'blank';
};
datablock ShapeBaseImageData(DeployableTurretImage)
{
// Basic Item properties
shapeFile = "data/FPSGameplay/art/shapes/weapons/Turret/TP_Turret.DAE";
shapeFileFP = "data/FPSGameplay/art/shapes/weapons/Turret/FP_Turret.DAE";
emap = true;
imageAnimPrefix = "Turret";
imageAnimPrefixFP = "Turret";
// Specify mount point & offset for 3rd person, and eye offset
// for first person rendering.
mountPoint = 0;
firstPerson = true;
useEyeNode = true;
// Don't allow a player to sprint with a turret
sprintDisallowed = true;
class = "DeployableTurretWeaponImage";
className = "DeployableTurretWeaponImage";
// Projectiles and Ammo.
item = DeployableTurret;
// Shake camera while firing.
shakeCamera = false;
camShakeFreq = "0 0 0";
camShakeAmp = "0 0 0";
// Images have a state system which controls how the animations
// are run, which sounds are played, script callbacks, etc. This
// state system is downloaded to the client so that clients can
// predict state changes and animate accordingly. The following
// system supports basic ready->fire->reload transitions as
// well as a no-ammo->dryfire idle state.
// Initial start up state
stateName[0] = "Preactivate";
stateTransitionOnLoaded[0] = "Activate";
stateTransitionOnNoAmmo[0] = "Activate";
// Activating the gun. Called when the weapon is first
// mounted and there is ammo.
stateName[1] = "Activate";
stateTransitionGeneric0In[1] = "SprintEnter";
stateTransitionOnTimeout[1] = "Ready";
stateTimeoutValue[1] = 0.66;
stateSequence[1] = "switch_in";
stateSound[1] = TurretSwitchinSound;
// Ready to fire, just waiting for the trigger
stateName[2] = "Ready";
stateTransitionGeneric0In[2] = "SprintEnter";
stateTransitionOnMotion[2] = "ReadyMotion";
stateTransitionOnTriggerDown[2] = "Fire";
stateScaleAnimation[2] = false;
stateScaleAnimationFP[2] = false;
stateSequence[2] = "idle";
// Ready to fire with player moving
stateName[3] = "ReadyMotion";
stateTransitionGeneric0In[3] = "SprintEnter";
stateTransitionOnNoMotion[3] = "Ready";
stateScaleAnimation[3] = false;
stateScaleAnimationFP[3] = false;
stateSequenceTransitionIn[3] = true;
stateSequenceTransitionOut[3] = true;
stateTransitionOnTriggerDown[3] = "Fire";
stateSequence[3] = "run";
// Wind up to throw the Turret
stateName[4] = "Fire";
stateTransitionGeneric0In[4] = "SprintEnter";
stateTransitionOnTimeout[4] = "Fire2";
stateTimeoutValue[4] = 0.66;
stateFire[4] = true;
stateRecoil[4] = "";
stateAllowImageChange[4] = false;
stateSequence[4] = "Fire";
stateSequenceNeverTransition[4] = true;
stateShapeSequence[4] = "Recoil";
// Throw the actual Turret
stateName[5] = "Fire2";
stateTransitionGeneric0In[5] = "SprintEnter";
stateTransitionOnTriggerUp[5] = "Reload";
stateTimeoutValue[5] = 0.1;
stateAllowImageChange[5] = false;
stateScript[5] = "onFire";
stateShapeSequence[5] = "Fire_Release";
// Play the reload animation, and transition into
stateName[6] = "Reload";
stateTransitionGeneric0In[6] = "SprintEnter";
stateTransitionOnTimeout[6] = "Ready";
stateWaitForTimeout[6] = true;
stateTimeoutValue[6] = 0.66;
stateSequence[6] = "switch_in";
// Start Sprinting
stateName[7] = "SprintEnter";
stateTransitionGeneric0Out[7] = "SprintExit";
stateTransitionOnTimeout[7] = "Sprinting";
stateWaitForTimeout[7] = false;
stateTimeoutValue[7] = 0.25;
stateWaitForTimeout[7] = false;
stateScaleAnimation[7] = true;
stateScaleAnimationFP[7] = true;
stateSequenceTransitionIn[7] = true;
stateSequenceTransitionOut[7] = true;
stateAllowImageChange[7] = false;
stateSequence[7] = "sprint";
// Sprinting
stateName[8] = "Sprinting";
stateTransitionGeneric0Out[8] = "SprintExit";
stateWaitForTimeout[8] = false;
stateScaleAnimation[8] = false;
stateScaleAnimationFP[8] = false;
stateSequenceTransitionIn[8] = true;
stateSequenceTransitionOut[8] = true;
stateAllowImageChange[8] = false;
stateSequence[8] = "sprint";
// Stop Sprinting
stateName[9] = "SprintExit";
stateTransitionGeneric0In[9] = "SprintEnter";
stateTransitionOnTimeout[9] = "Ready";
stateWaitForTimeout[9] = false;
stateTimeoutValue[9] = 0.5;
stateSequenceTransitionIn[9] = true;
stateSequenceTransitionOut[9] = true;
stateAllowImageChange[9] = false;
stateSequence[9] = "sprint";
};

View file

@ -0,0 +1,917 @@
//-----------------------------------------------------------------------------
// Torque
// Copyright GarageGames, LLC 2011
//-----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Placeholder projectile and explosion with required sounds, debris, and
// particle datablocks. These datablocks existed in now removed scripts, but
// were used within some that remain: see Lurker.cs, Ryder.cs, ProxMine.cs
//
// These effects should be made more generic or new fx created for unique usage.
//
// I've removed all effects that are not required for the current weapons. On
// reflection I really went overboard when originally making these effects!
// ----------------------------------------------------------------------------
$GrenadeUpVectorOffset = "0 0 1";
// ---------------------------------------------------------------------------
// Sounds
// ---------------------------------------------------------------------------
datablock SFXProfile(GrenadeExplosionSound)
{
filename = "data/FPSGameplay/sound/weapons/GRENADELAND.wav";
description = AudioDefault3d;
preload = true;
};
datablock SFXProfile(GrenadeLauncherExplosionSound)
{
filename = "data/FPSGameplay/sound/weapons/Crossbow_explosion";
description = AudioDefault3d;
preload = true;
};
// ----------------------------------------------------------------------------
// Lights for the projectile(s)
// ----------------------------------------------------------------------------
datablock LightDescription(GrenadeLauncherLightDesc)
{
range = 1.0;
color = "1 1 1";
brightness = 2.0;
animationType = PulseLightAnim;
animationPeriod = 0.25;
//flareType = SimpleLightFlare0;
};
// ---------------------------------------------------------------------------
// Debris
// ---------------------------------------------------------------------------
datablock ParticleData(GrenadeDebrisFireParticle)
{
textureName = "data/FPSGameplay/art/particles/impact";
dragCoeffiecient = 0;
gravityCoefficient = -1.00366;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 300;
lifetimeVarianceMS = 100;
useInvAlpha = false;
spinSpeed = 1;
spinRandomMin = -280.0;
spinRandomMax = 280.0;
colors[0] = "1 0.590551 0.188976 0.0944882";
colors[1] = "0.677165 0.590551 0.511811 0.496063";
colors[2] = "0.645669 0.645669 0.645669 0";
sizes[0] = 0.2;
sizes[1] = 0.5;
sizes[2] = 0.2;
times[0] = 0.0;
times[1] = 0.494118;
times[2] = 1.0;
animTexName = "data/FPSGameplay/art/particles/impact";
colors[3] = "1 1 1 0.407";
sizes[3] = "0.5";
};
datablock ParticleEmitterData(GrenadeDebrisFireEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 0;
velocityVariance = 0;
thetaMin = 0.0;
thetaMax = 25;
phiReferenceVel = 0;
phiVariance = 360;
ejectionoffset = 0.3;
particles = "GrenadeDebrisFireParticle";
orientParticles = "1";
blendStyle = "NORMAL";
};
datablock DebrisData(GrenadeDebris)
{
shapeFile = "data/FPSGameplay/art/shapes/weapons/Grenade/grenadeDebris.dae";
emitters[0] = GrenadeDebrisFireEmitter;
elasticity = 0.4;
friction = 0.25;
numBounces = 3;
bounceVariance = 1;
explodeOnMaxBounce = false;
staticOnMaxBounce = false;
snapOnMaxBounce = false;
minSpinSpeed = 200;
maxSpinSpeed = 600;
render2D = false;
lifetime = 4;
lifetimeVariance = 1.5;
velocity = 15;
velocityVariance = 5;
fade = true;
useRadiusMass = true;
baseRadius = 0.3;
gravModifier = 1.0;
terminalVelocity = 20;
ignoreWater = false;
};
// ----------------------------------------------------------------------------
// Splash effects
// ----------------------------------------------------------------------------
datablock ParticleData(GrenadeSplashMist)
{
dragCoefficient = 1.0;
windCoefficient = 2.0;
gravityCoefficient = 0.3;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 600;
lifetimeVarianceMS = 100;
useInvAlpha = false;
spinRandomMin = -90.0;
spinRandomMax = 500.0;
spinSpeed = 1;
textureName = "data/FPSGameplay/art/particles/smoke";
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.2;
sizes[1] = 0.4;
sizes[2] = 0.8;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(GrenadeSplashMistEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 3.0;
velocityVariance = 2.0;
ejectionOffset = 0.15;
thetaMin = 85;
thetaMax = 85;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvance = false;
lifetimeMS = 250;
particles = "GrenadeSplashMist";
};
datablock ParticleData(GrenadeSplashParticle)
{
dragCoefficient = 1;
windCoefficient = 0.9;
gravityCoefficient = 0.3;
inheritedVelFactor = 0.2;
constantAcceleration = -1.4;
lifetimeMS = 600;
lifetimeVarianceMS = 200;
textureName = "data/FPSGameplay/art/particles/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.25;
sizes[2] = 0.25;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(GrenadeSplashEmitter)
{
ejectionPeriodMS = 4;
periodVarianceMS = 0;
ejectionVelocity = 7.3;
velocityVariance = 2.0;
ejectionOffset = 0.0;
thetaMin = 30;
thetaMax = 80;
phiReferenceVel = 00;
phiVariance = 360;
overrideAdvance = false;
orientParticles = true;
orientOnVelocity = true;
lifetimeMS = 100;
particles = "GrenadeSplashParticle";
};
datablock ParticleData(GrenadeSplashRingParticle)
{
textureName = "data/FPSGameplay/art/particles/wake";
dragCoefficient = 0.0;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.0;
lifetimeMS = 2500;
lifetimeVarianceMS = 200;
windCoefficient = 0.0;
useInvAlpha = 1;
spinRandomMin = 30.0;
spinRandomMax = 30.0;
spinSpeed = 1;
animateTexture = true;
framesPerSec = 1;
animTexTiling = "2 1";
animTexFrames = "0 1";
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] = 2.0;
sizes[1] = 4.0;
sizes[2] = 8.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(GrenadeSplashRingEmitter)
{
lifetimeMS = "100";
ejectionPeriodMS = 200;
periodVarianceMS = 10;
ejectionVelocity = 0;
velocityVariance = 0;
ejectionOffset = 0;
thetaMin = 89;
thetaMax = 90;
phiReferenceVel = 0;
phiVariance = 1;
alignParticles = 1;
alignDirection = "0 0 1";
particles = "GrenadeSplashRingParticle";
};
datablock SplashData(GrenadeSplash)
{
// SplashData doesn't have a render function in the source,
// so everything but the emitter array is useless here.
emitter[0] = GrenadeSplashEmitter;
emitter[1] = GrenadeSplashMistEmitter;
emitter[2] = GrenadeSplashRingEmitter;
//numSegments = 15;
//ejectionFreq = 15;
//ejectionAngle = 40;
//ringLifetime = 0.5;
//lifetimeMS = 300;
//velocity = 4.0;
//startRadius = 0.0;
//acceleration = -3.0;
//texWrap = 5.0;
//texture = "data/FPSGameplay/art/images/particles//splash";
//colors[0] = "0.7 0.8 1.0 0.0";
//colors[1] = "0.7 0.8 1.0 0.3";
//colors[2] = "0.7 0.8 1.0 0.7";
//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;
};
// ----------------------------------------------------------------------------
// Explosion Particle effects
// ----------------------------------------------------------------------------
datablock ParticleData(GrenadeExpFire)
{
textureName = "data/FPSGameplay/art/particles/fireball.png";
dragCoeffiecient = 0;
windCoeffiecient = 0.5;
gravityCoefficient = -1;
inheritedVelFactor = 0;
constantAcceleration = 0;
lifetimeMS = 1200;//3000;
lifetimeVarianceMS = 100;//200;
useInvAlpha = false;
spinRandomMin = 0;
spinRandomMax = 1;
spinSpeed = 1;
colors[0] = "0.886275 0.854902 0.733333 0.795276";
colors[1] = "0.356863 0.34902 0.321569 0.266";
colors[2] = "0.0235294 0.0235294 0.0235294 0.207";
sizes[0] = 1;//2;
sizes[1] = 5;
sizes[2] = 7;//0.5;
times[0] = 0.0;
times[1] = 0.25;
times[2] = 0.5;
animTexName = "data/FPSGameplay/art/particles/fireball.png";
times[3] = "1";
dragCoefficient = "1.99902";
sizes[3] = "10";
colors[3] = "0 0 0 0";
};
datablock ParticleEmitterData(GrenadeExpFireEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 5;//0;
ejectionVelocity = 1;//1.0;
velocityVariance = 0;//0.5;
thetaMin = 0.0;
thetaMax = 45;
lifetimeMS = 250;
particles = "GrenadeExpFire";
blendStyle = "ADDITIVE";
};
datablock ParticleData(GrenadeExpDust)
{
textureName = "data/FPSGameplay/art/particles/smoke.png";
dragCoefficient = 0.498534;
gravityCoefficient = 0;
inheritedVelFactor = 1;
constantAcceleration = 0.0;
lifetimeMS = 2000;
lifetimeVarianceMS = 250;
useInvAlpha = 0;
spinSpeed = 1;
spinRandomMin = -90.0;
spinRandomMax = 90.0;
colors[0] = "0.992126 0.992126 0.992126 0.96063";
colors[1] = "0.11811 0.11811 0.11811 0.929134";
colors[2] = "0.00392157 0.00392157 0.00392157 0.362205";
sizes[0] = 1.59922;
sizes[1] = 4.99603;
sizes[2] = 9.99817;
times[0] = 0.0;
times[1] = 0.494118;
times[2] = 1.0;
animTexName = "data/FPSGameplay/art/particles/smoke.png";
colors[3] = "0.996078 0.996078 0.996078 0";
sizes[3] = "15";
};
datablock ParticleEmitterData(GrenadeExpDustEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 8;
velocityVariance = 0.0;
ejectionOffset = 0.0;
thetaMin = 85;
thetaMax = 85;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = 0;
lifetimeMS = 2000;
particles = "GrenadeExpDust";
blendStyle = "NORMAL";
};
datablock ParticleData(GrenadeExpSpark)
{
textureName = "data/FPSGameplay/art/particles/Sparkparticle";
dragCoefficient = 1;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = 0.0;
lifetimeMS = 500;
lifetimeVarianceMS = 250;
colors[0] = "0.6 0.4 0.3 1";
colors[1] = "0.6 0.4 0.3 1";
colors[2] = "1.0 0.4 0.3 0";
sizes[0] = 0.5;
sizes[1] = 0.75;
sizes[2] = 1;
times[0] = 0;
times[1] = 0.5;
times[2] = 1;
};
datablock ParticleEmitterData(GrenadeExpSparkEmitter)
{
ejectionPeriodMS = 2;
periodVarianceMS = 0;
ejectionVelocity = 20;
velocityVariance = 10;
ejectionOffset = 0.0;
thetaMin = 0;
thetaMax = 120;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
orientParticles = true;
lifetimeMS = 100;
particles = "GrenadeExpSpark";
};
datablock ParticleData(GrenadeExpSparks)
{
textureName = "data/FPSGameplay/art/particles/droplet";
dragCoefficient = 1;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = 0.0;
lifetimeMS = 500;
lifetimeVarianceMS = 350;
colors[0] = "0.6 0.4 0.3 1.0";
colors[1] = "0.6 0.4 0.3 0.6";
colors[2] = "1.0 0.4 0.3 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(GrenadeExpSparksEmitter)
{
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 = "GrenadeExpSparks";
};
datablock ParticleData(GrenadeExpSmoke)
{
textureName = "data/FPSGameplay/art/particles/smoke";
dragCoeffiecient = 0;
gravityCoefficient = -0.40293;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 800;
lifetimeVarianceMS = 299;
useInvAlpha = true;
spinSpeed = 1;
spinRandomMin = -80.0;
spinRandomMax = 0;
colors[0] = "0.8 0.8 0.8 0.4";
colors[1] = "0.5 0.5 0.5 0.5";
colors[2] = "0.75 0.75 0.75 0";
sizes[0] = 4.49857;
sizes[1] = 7.49863;
sizes[2] = 11.2495;
times[0] = 0;
times[1] = 0.498039;
times[2] = 1;
animTexName = "data/FPSGameplay/art/particles/smoke";
times[3] = "1";
};
datablock ParticleEmitterData(GrenadeExpSmokeEmitter)
{
ejectionPeriodMS = 15;
periodVarianceMS = 5;
ejectionVelocity = 2.4;
velocityVariance = 1.2;
thetaMin = 0.0;
thetaMax = 180.0;
ejectionOffset = 1;
particles = "GrenadeExpSmoke";
blendStyle = "NORMAL";
};
// ----------------------------------------------------------------------------
// Dry/Air Explosion Objects
// ----------------------------------------------------------------------------
datablock ExplosionData(GrenadeExplosion)
{
soundProfile = GrenadeExplosionSound;
lifeTimeMS = 400; // Quick flash, short burn, and moderate dispersal
// Volume particles
particleEmitter = GrenadeExpFireEmitter;
particleDensity = 75;
particleRadius = 2.25;
// Point emission
emitter[0] = GrenadeExpDustEmitter;
emitter[1] = GrenadeExpSparksEmitter;
emitter[2] = GrenadeExpSmokeEmitter;
// Camera Shaking
shakeCamera = true;
camShakeFreq = "10.0 11.0 9.0";
camShakeAmp = "15.0 15.0 15.0";
camShakeDuration = 1.5;
camShakeRadius = 20;
// Exploding debris
debris = GrenadeDebris;
debrisThetaMin = 10;
debrisThetaMax = 60;
debrisNum = 4;
debrisNumVariance = 2;
debrisVelocity = 25;
debrisVelocityVariance = 5;
lightStartRadius = 4.0;
lightEndRadius = 0.0;
lightStartColor = "1.0 1.0 1.0";
lightEndColor = "1.0 1.0 1.0";
lightStartBrightness = 4.0;
lightEndBrightness = 0.0;
lightNormalOffset = 2.0;
};
// ----------------------------------------------------------------------------
// Water Explosion
// ----------------------------------------------------------------------------
datablock ParticleData(GLWaterExpDust)
{
textureName = "data/FPSGameplay/art/particles/steam";
dragCoefficient = 1.0;
gravityCoefficient = -0.01;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 2500;
lifetimeVarianceMS = 250;
useInvAlpha = false;
spinSpeed = 1;
spinRandomMin = -90.0;
spinRandomMax = 500.0;
colors[0] = "0.6 0.6 1.0 0.5";
colors[1] = "0.6 0.6 1.0 0.3";
sizes[0] = 0.25;
sizes[1] = 1.5;
times[0] = 0.0;
times[1] = 1.0;
times[2] = 1.0;
};
datablock ParticleEmitterData(GLWaterExpDustEmitter)
{
ejectionPeriodMS = 1;
periodVarianceMS = 0;
ejectionVelocity = 10;
velocityVariance = 0.0;
ejectionOffset = 0.0;
thetaMin = 85;
thetaMax = 85;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
lifetimeMS = 75;
particles = "GLWaterExpDust";
};
datablock ParticleData(GLWaterExpSparks)
{
textureName = "data/FPSGameplay/art/particles/spark_wet";
dragCoefficient = 1;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.2;
constantAcceleration = 0.0;
lifetimeMS = 500;
lifetimeVarianceMS = 250;
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(GLWaterExpSparkEmitter)
{
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 = "GLWaterExpSparks";
};
datablock ParticleData(GLWaterExpSmoke)
{
textureName = "data/FPSGameplay/art/particles/smoke";
dragCoeffiecient = 0.4;
gravityCoefficient = -0.25;
inheritedVelFactor = 0.025;
constantAcceleration = -1.1;
lifetimeMS = 1250;
lifetimeVarianceMS = 0;
useInvAlpha = false;
spinSpeed = 1;
spinRandomMin = -200.0;
spinRandomMax = 200.0;
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(GLWaterExpSmokeEmitter)
{
ejectionPeriodMS = 15;
periodVarianceMS = 0;
ejectionVelocity = 6.25;
velocityVariance = 0.25;
thetaMin = 0.0;
thetaMax = 90.0;
lifetimeMS = 250;
particles = "GLWaterExpSmoke";
};
datablock ParticleData(GLWaterExpBubbles)
{
textureName = "data/FPSGameplay/art/particles/millsplash01";
dragCoefficient = 0.0;
gravityCoefficient = -0.05;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 1500;
lifetimeVarianceMS = 250;
useInvAlpha = false;
spinRandomMin = -100.0;
spinRandomMax = 100.0;
spinSpeed = 1;
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.2;
sizes[1] = 0.4;
sizes[2] = 0.8;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(GLWaterExpBubbleEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 1.0;
ejectionOffset = 3.0;
velocityVariance = 0.5;
thetaMin = 0;
thetaMax = 80;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
particles = "GLWaterExpBubbles";
};
datablock ExplosionData(GrenadeLauncherWaterExplosion)
{
//soundProfile = GLWaterExplosionSound;
emitter[0] = GLWaterExpDustEmitter;
emitter[1] = GLWaterExpSparkEmitter;
emitter[2] = GLWaterExpSmokeEmitter;
emitter[3] = GLWaterExpBubbleEmitter;
shakeCamera = true;
camShakeFreq = "10.0 11.0 9.0";
camShakeAmp = "20.0 20.0 20.0";
camShakeDuration = 1.5;
camShakeRadius = 20.0;
lightStartRadius = 20.0;
lightEndRadius = 0.0;
lightStartColor = "0.9 0.9 0.8";
lightEndColor = "0.6 0.6 1.0";
lightStartBrightness = 2.0;
lightEndBrightness = 0.0;
};
// ----------------------------------------------------------------------------
// Dry/Air Explosion Objects
// ----------------------------------------------------------------------------
datablock ExplosionData(GrenadeSubExplosion)
{
offset = 0.25;
emitter[0] = GrenadeExpSparkEmitter;
lightStartRadius = 4.0;
lightEndRadius = 0.0;
lightStartColor = "0.9 0.7 0.7";
lightEndColor = "0.9 0.7 0.7";
lightStartBrightness = 2.0;
lightEndBrightness = 0.0;
};
datablock ExplosionData(GrenadeLauncherExplosion)
{
soundProfile = GrenadeLauncherExplosionSound;
lifeTimeMS = 400; // Quick flash, short burn, and moderate dispersal
// Volume particles
particleEmitter = GrenadeExpFireEmitter;
particleDensity = 75;
particleRadius = 2.25;
// Point emission
emitter[0] = GrenadeExpDustEmitter;
emitter[1] = GrenadeExpSparksEmitter;
emitter[2] = GrenadeExpSmokeEmitter;
// Sub explosion objects
subExplosion[0] = GrenadeSubExplosion;
// Camera Shaking
shakeCamera = true;
camShakeFreq = "10.0 11.0 9.0";
camShakeAmp = "15.0 15.0 15.0";
camShakeDuration = 1.5;
camShakeRadius = 20;
// Exploding debris
debris = GrenadeDebris;
debrisThetaMin = 10;
debrisThetaMax = 60;
debrisNum = 4;
debrisNumVariance = 2;
debrisVelocity = 25;
debrisVelocityVariance = 5;
lightStartRadius = 4.0;
lightEndRadius = 0.0;
lightStartColor = "1.0 1.0 1.0";
lightEndColor = "1.0 1.0 1.0";
lightStartBrightness = 4.0;
lightEndBrightness = 0.0;
lightNormalOffset = 2.0;
};
// ----------------------------------------------------------------------------
// Underwater Grenade projectile trail
// ----------------------------------------------------------------------------
datablock ParticleData(GrenadeTrailWaterParticle)
{
textureName = "data/FPSGameplay/art/particles/bubble";
dragCoefficient = 0.0;
gravityCoefficient = 0.1;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 1500;
lifetimeVarianceMS = 600;
useInvAlpha = false;
spinRandomMin = -100.0;
spinRandomMax = 100.0;
spinSpeed = 1;
colors[0] = "0.7 0.8 1.0 1.0";
colors[1] = "0.7 0.8 1.0 0.4";
colors[2] = "0.7 0.8 1.0 0.0";
sizes[0] = 0.05;
sizes[1] = 0.05;
sizes[2] = 0.05;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(GrenadeTrailWaterEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 1.0;
ejectionOffset = 0.1;
velocityVariance = 0.5;
thetaMin = 0.0;
thetaMax = 80.0;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvances = false;
particles = GrenadeTrailWaterParticle;
};
// ----------------------------------------------------------------------------
// Normal-fire Projectile Object
// ----------------------------------------------------------------------------
datablock ParticleData(GrenadeProjSmokeTrail)
{
textureName = "data/FPSGameplay/art/particles/smoke";
dragCoeffiecient = 0.0;
gravityCoefficient = -0.2;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 750;
lifetimeVarianceMS = 250;
useInvAlpha = true;
spinRandomMin = -60;
spinRandomMax = 60;
spinSpeed = 1;
colors[0] = "0.9 0.8 0.8 0.6";
colors[1] = "0.6 0.6 0.6 0.9";
colors[2] = "0.3 0.3 0.3 0";
sizes[0] = 0.25;
sizes[1] = 0.5;
sizes[2] = 0.75;
times[0] = 0.0;
times[1] = 0.4;
times[2] = 1.0;
};
datablock ParticleEmitterData(GrenadeProjSmokeTrailEmitter)
{
ejectionPeriodMS = 10;
periodVarianceMS = 0;
ejectionVelocity = 0.75;
velocityVariance = 0;
thetaMin = 0.0;
thetaMax = 0.0;
phiReferenceVel = 90;
phiVariance = 0;
particles = "GrenadeProjSmokeTrail";
};
datablock ProjectileData(GrenadeLauncherProjectile)
{
projectileShapeName = "data/FPSGameplay/art/shapes/weapons/shared/rocket.dts";
directDamage = 30;
radiusDamage = 30;
damageRadius = 5;
areaImpulse = 2000;
explosion = GrenadeLauncherExplosion;
waterExplosion = GrenadeLauncherWaterExplosion;
decal = ScorchRXDecal;
splash = GrenadeSplash;
particleEmitter = GrenadeProjSmokeTrailEmitter;
particleWaterEmitter = GrenadeTrailWaterEmitter;
muzzleVelocity = 30;
velInheritFactor = 0.3;
armingDelay = 2000;
lifetime = 10000;
fadeDelay = 4500;
bounceElasticity = 0.4;
bounceFriction = 0.3;
isBallistic = true;
gravityMod = 0.9;
lightDesc = GrenadeLauncherLightDesc;
damageType = "GrenadeDamage";
};

View file

@ -0,0 +1,504 @@
// ----------------------------------------------------------------------------
// Placeholder explosion with required sounds, debris, and particle datablocks.
// These datablocks existed in now removed scripts, but were used within some
// that remain: see cheetahCar.cs
//
// These should be made more generic or new fx created for the cheetah turret's
// projectile explosion effects.
//
// I've removed all effects that are not required for the current weapons. On
// reflection I really went overboard when originally designing these effects!
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Sound
// ----------------------------------------------------------------------------
datablock SFXProfile(RocketLauncherExplosionSound)
{
filename = "data/FPSGameplay/sound/weapons/Crossbow_explosion";
description = AudioDefault3d;
preload = true;
};
//----------------------------------------------------------------------------
// Debris
//----------------------------------------------------------------------------
datablock ParticleData(RocketDebrisTrailParticle)
{
textureName = "data/FPSGameplay/art/particles/impact";
dragCoeffiecient = 0;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 1200;//1000;
lifetimeVarianceMS = 299;//500;
useInvAlpha = true;//false;
spinSpeed = 1;
spinRandomMin = -300.0;
spinRandomMax = 0;
colors[0] = "1 0.897638 0.795276 0.4";
colors[1] = "0.795276 0.795276 0.795276 0.6";
colors[2] = "0 0 0 0";
sizes[0] = 0.5;//1.0;
sizes[1] = 2;
sizes[2] = 1;//1.0;
times[0] = 0.0;
times[1] = 0.498039;
times[2] = 1.0;
animTexName = "data/FPSGameplay/art/particles/impact";
times[3] = "1";
};
datablock ParticleEmitterData(RocketDebrisTrailEmitter)
{
ejectionPeriodMS = 6;//8;
periodVarianceMS = 2;//4;
ejectionVelocity = 1.0;
velocityVariance = 0.5;
thetaMin = 0.0;
thetaMax = 180.0;
phiReferenceVel = 0;
phiVariance = 360;
ejectionoffset = 0.0;//0.3;
particles = "RocketDebrisTrailParticle";
};
datablock DebrisData(RocketDebris)
{
shapeFile = "data/FPSGameplay/art/shapes/weapons/shared/rocket.dts";
emitters[0] = RocketDebrisTrailEmitter;
elasticity = 0.5;
friction = 0.5;
numBounces = 1;//2;
bounceVariance = 1;
explodeOnMaxBounce = true;
staticOnMaxBounce = false;
snapOnMaxBounce = false;
minSpinSpeed = 400;
maxSpinSpeed = 800;
render2D = false;
lifetime = 0.25;//0.5;//1;//2;
lifetimeVariance = 0.0;//0.25;//0.5;
velocity = 35;//30;//15;
velocityVariance = 10;//5;
fade = true;
useRadiusMass = true;
baseRadius = 0.3;
gravModifier = 1.0;
terminalVelocity = 45;
ignoreWater = false;
};
// ----------------------------------------------------------------------------
// Splash effects
// ----------------------------------------------------------------------------
datablock ParticleData(RocketSplashMist)
{
dragCoefficient = 1.0;
windCoefficient = 2.0;
gravityCoefficient = 0.3;
inheritedVelFactor = 0.0;
constantAcceleration = 0.0;
lifetimeMS = 600;
lifetimeVarianceMS = 100;
useInvAlpha = false;
spinRandomMin = -90.0;
spinRandomMax = 500.0;
spinSpeed = 1;
textureName = "data/FPSGameplay/art/particles/smoke";
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.2;//0.5;
sizes[1] = 0.4;//0.5;
sizes[2] = 0.8;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(RocketSplashMistEmitter)
{
ejectionPeriodMS = 5;
periodVarianceMS = 0;
ejectionVelocity = 3.0;
velocityVariance = 2.0;
ejectionOffset = 0.15;
thetaMin = 85;
thetaMax = 85;
phiReferenceVel = 0;
phiVariance = 360;
overrideAdvance = false;
lifetimeMS = 250;
particles = "RocketSplashMist";
};
datablock ParticleData(RocketSplashParticle)
{
dragCoefficient = 1;
windCoefficient = 0.9;
gravityCoefficient = 0.3;
inheritedVelFactor = 0.2;
constantAcceleration = -1.4;
lifetimeMS = 600;
lifetimeVarianceMS = 200;
textureName = "data/FPSGameplay/art/particles/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.25;
sizes[2] = 0.25;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(RocketSplashEmitter)
{
ejectionPeriodMS = 4;
periodVarianceMS = 0;
ejectionVelocity = 7.3;
velocityVariance = 2.0;
ejectionOffset = 0.0;
thetaMin = 30;
thetaMax = 80;
phiReferenceVel = 00;
phiVariance = 360;
overrideAdvance = false;
orientParticles = true;
orientOnVelocity = true;
lifetimeMS = 100;
particles = "RocketSplashParticle";
};
datablock ParticleData(RocketSplashRingParticle)
{
textureName = "data/FPSGameplay/art/particles/wake";
dragCoefficient = 0.0;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.0;
lifetimeMS = 2500;
lifetimeVarianceMS = 200;
windCoefficient = 0.0;
useInvAlpha = 1;
spinRandomMin = 30.0;
spinRandomMax = 30.0;
spinSpeed = 1;
animateTexture = true;
framesPerSec = 1;
animTexTiling = "2 1";
animTexFrames = "0 1";
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] = 2.0;
sizes[1] = 4.0;
sizes[2] = 8.0;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(RocketSplashRingEmitter)
{
lifetimeMS = "100";
ejectionPeriodMS = 200;
periodVarianceMS = 10;
ejectionVelocity = 0;
velocityVariance = 0;
ejectionOffset = 0;
thetaMin = 89;
thetaMax = 90;
phiReferenceVel = 0;
phiVariance = 1;
alignParticles = 1;
alignDirection = "0 0 1";
particles = "RocketSplashRingParticle";
};
datablock SplashData(RocketSplash)
{
// numSegments = 15;
// ejectionFreq = 15;
// ejectionAngle = 40;
// ringLifetime = 0.5;
// lifetimeMS = 300;
// velocity = 4.0;
// startRadius = 0.0;
// acceleration = -3.0;
// texWrap = 5.0;
// texture = "data/FPSGameplay/art/images/particles/splash";
emitter[0] = RocketSplashEmitter;
emitter[1] = RocketSplashMistEmitter;
emitter[2] = RocketSplashRingEmitter;
// colors[0] = "0.7 0.8 1.0 0.0";
// colors[1] = "0.7 0.8 1.0 0.3";
// colors[2] = "0.7 0.8 1.0 0.7";
// 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;
};
// ----------------------------------------------------------------------------
// Explosion Particle effects
// ----------------------------------------------------------------------------
datablock ParticleData(RocketExpFire)
{
gravityCoefficient = "-0.50061";
lifetimeMS = "400";
lifetimeVarianceMS = "299";
spinSpeed = "1";
spinRandomMin = "-200";
spinRandomMax = "0";
textureName = "data/FPSGameplay/art/particles/smoke";
animTexName = "data/FPSGameplay/art/particles/smoke";
colors[0] = "1 0.897638 0.795276 1";
colors[1] = "0.795276 0.393701 0 0.6";
colors[2] = "0 0 0 0";
sizes[0] = "1.99902";
sizes[1] = "7.99915";
sizes[2] = "3.99805";
times[1] = "0.392157";
times[2] = "1";
times[3] = "1";
};
datablock ParticleEmitterData(RocketExpFireEmitter)
{
ejectionPeriodMS = "10";
periodVarianceMS = "5";
ejectionVelocity = "3";
velocityVariance = "2";
particles = "RocketExpFire";
blendStyle = "NORMAL";
};
datablock ParticleData(RocketExpFireball)
{
textureName = "data/FPSGameplay/art/particles/fireball.png";
lifetimeMS = "300";
lifetimeVarianceMS = "299";
spinSpeed = "1";
spinRandomMin = "-400";
spinRandomMax = "0";
animTexName = "data/FPSGameplay/art/particles/fireball.png";
colors[0] = "1 0.897638 0.795276 0.2";
colors[1] = "1 0.496063 0 0.6";
colors[2] = "0.0944882 0.0944882 0.0944882 0";
sizes[0] = "0.997986";
sizes[1] = "1.99902";
sizes[2] = "2.99701";
times[1] = "0.498039";
times[2] = "1";
times[3] = "1";
gravityCoefficient = "-1";
};
datablock ParticleEmitterData(RocketExpFireballEmitter)
{
particles = "RocketExpFireball";
blendStyle = "ADDITIVE";
ejectionPeriodMS = "10";
periodVarianceMS = "5";
ejectionVelocity = "4";
velocityVariance = "2";
ejectionOffset = "2";
thetaMax = "120";
};
datablock ParticleData(RocketExpSmoke)
{
lifetimeMS = 1200;//"1250";
lifetimeVarianceMS = 299;//200;//"250";
textureName = "data/FPSGameplay/art/particles/smoke";
animTexName = "data/FPSGameplay/art/particles/smoke";
useInvAlpha = "1";
gravityCoefficient = "-0.100122";
spinSpeed = "1";
spinRandomMin = "-100";
spinRandomMax = "0";
colors[0] = "0.897638 0.795276 0.692913 0.4";//"0.192157 0.192157 0.192157 0.0944882";
colors[1] = "0.897638 0.897638 0.897638 0.8";//"0.454902 0.454902 0.454902 0.897638";
colors[2] = "0.4 0.4 0.4 0";//"1 1 1 0";
sizes[0] = "1.99597";
sizes[1] = "3.99805";
sizes[2] = "7.99915";
times[1] = "0.494118";
times[2] = "1";
times[3] = "1";
};
datablock ParticleEmitterData(RocketExpSmokeEmitter)
{
ejectionPeriodMS = "15";
periodVarianceMS = "5";
//ejectionOffset = "1";
thetaMax = "180";
particles = "RocketExpSmoke";
blendStyle = "NORMAL";
};
datablock ParticleData(RocketExpSparks)
{
textureName = "data/FPSGameplay/art/particles/droplet.png";
lifetimeMS = "100";
lifetimeVarianceMS = "50";
animTexName = "data/FPSGameplay/art/particles/droplet.png";
inheritedVelFactor = "0.391389";
sizes[0] = "1.99902";
sizes[1] = "2.49954";
sizes[2] = "0.997986";
colors[0] = "1.0 0.9 0.8 0.2";
colors[1] = "1.0 0.9 0.8 0.8";
colors[2] = "0.8 0.4 0.0 0.0";
times[0] = "0";
times[1] = "0.34902";
times[2] = "1";
times[3] = "1";
};
datablock ParticleEmitterData(RocketExpSparksEmitter)
{
particles = "RocketExpSparks";
blendStyle = "NORMAL";
ejectionPeriodMS = "10";
periodVarianceMS = "5";
ejectionVelocity = "60";
velocityVariance = "10";
thetaMax = "120";
phiReferenceVel = 0;
phiVariance = "360";
ejectionOffset = "0";
orientParticles = true;
orientOnVelocity = true;
};
datablock ParticleData(RocketExpSubFireParticles)
{
textureName = "data/FPSGameplay/art/particles/fireball.png";
gravityCoefficient = "-0.202686";
lifetimeMS = "400";
lifetimeVarianceMS = "299";
spinSpeed = "1";
spinRandomMin = "-200";
spinRandomMax = "0";
animTexName = "data/FPSGameplay/art/particles/fireball.png";
colors[0] = "1 0.897638 0.795276 0.2";
colors[1] = "1 0.496063 0 1";
colors[2] = "0.0944882 0.0944882 0.0944882 0";
sizes[0] = "0.997986";
sizes[1] = "1.99902";
sizes[2] = "2.99701";
times[1] = "0.498039";
times[2] = "1";
times[3] = "1";
};
datablock ParticleEmitterData(RocketExpSubFireEmitter)
{
particles = "RocketExpSubFireParticles";
blendStyle = "ADDITIVE";
ejectionPeriodMS = "10";
periodVarianceMS = "5";
ejectionVelocity = "4";
velocityVariance = "2";
thetaMax = "120";
};
datablock ParticleData(RocketExpSubSmoke)
{
textureName = "data/FPSGameplay/art/particles/smoke";
gravityCoefficient = "-0.40293";
lifetimeMS = "800";
lifetimeVarianceMS = "299";
spinSpeed = "1";
spinRandomMin = "-200";
spinRandomMax = "0";
animTexName = "data/FPSGameplay/art/particles/smoke";
colors[0] = "0.4 0.35 0.3 0.393701";
colors[1] = "0.45 0.45 0.45 0.795276";
colors[2] = "0.4 0.4 0.4 0";
sizes[0] = "1.99902";
sizes[1] = "3.99805";
sizes[2] = "7.99915";
times[1] = "0.4";
times[2] = "1";
times[3] = "1";
};
datablock ParticleEmitterData(RocketExpSubSmokeEmitter)
{
particles = "RocketExpSubSmoke";
ejectionPeriodMS = "30";
periodVarianceMS = "10";
ejectionVelocity = "2";
velocityVariance = "1";
ejectionOffset = 1;//"2";
blendStyle = "NORMAL";
};
// ----------------------------------------------------------------------------
// Dry/Air Explosion Objects
// ----------------------------------------------------------------------------
datablock ExplosionData(RocketSubExplosion)
{
lifeTimeMS = 100;
offset = 0.4;
emitter[0] = RocketExpSubFireEmitter;
emitter[1] = RocketExpSubSmokeEmitter;
};
datablock ExplosionData(RocketLauncherExplosion)
{
soundProfile = RocketLauncherExplosionSound;
lifeTimeMS = 200; // I want a quick bang and dissipation, not a slow burn-out
// Volume particles
particleEmitter = RocketExpSmokeEmitter;
particleDensity = 10;//20;
particleRadius = 1;//2;
// Point emission
emitter[0] = RocketExpFireEmitter;
emitter[1] = RocketExpSparksEmitter;
emitter[2] = RocketExpSparksEmitter;
emitter[3] = RocketExpFireballEmitter;
// Sub explosion objects
subExplosion[0] = RocketSubExplosion;
// Camera Shaking
shakeCamera = true;
camShakeFreq = "10.0 11.0 9.0";
camShakeAmp = "15.0 15.0 15.0";
camShakeDuration = 1.5;
camShakeRadius = 20;
// Exploding debris
debris = RocketDebris;
debrisThetaMin = 0;//10;
debrisThetaMax = 90;//80;
debrisNum = 5;
debrisNumVariance = 2;
debrisVelocity = 1;//2;
debrisVelocityVariance = 0.2;//0.5;
lightStartRadius = 6.0;
lightEndRadius = 0.0;
lightStartColor = "1.0 0.7 0.2";
lightEndColor = "0.9 0.7 0.0";
lightStartBrightness = 2.5;
lightEndBrightness = 0.0;
lightNormalOffset = 3.0;
};

View file

@ -0,0 +1,162 @@
//-----------------------------------------------------------------------------
// Chat edit window
//-----------------------------------------------------------------------------
new GuiControl(MessageHud)
{
profile = "GuiDefaultProfile";
horizSizing = "width";
vertSizing = "height";
position = "0 0";
extent = "640 480";
minExtent = "8 8";
visible = "0";
noCursor = true;
new GuiBitmapBorderCtrl(MessageHud_Frame) {
profile = "ChatHudBorderProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "120 375";
extent = "400 40";
minExtent = "8 8";
visible = "1";
new GuiBitmapCtrl() {
profile = "GuiDefaultProfile";
horizSizing = "width";
vertSizing = "height";
position = "8 8";
extent = "384 24";
minExtent = "8 8";
visible = "1";
helpTag = "0";
bitmap = "data/UI/art/gui/hudfill.png";
wrap = "0";
};
new GuiTextCtrl(MessageHud_Text)
{
profile = "ChatHudTextProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "14 12";
extent = "10 22";
minExtent = "8 8";
visible = "1";
};
new GuiTextEditCtrl(MessageHud_Edit)
{
profile = "ChatHudEditProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "0 13";
extent = "10 22";
minExtent = "8 8";
visible = "1";
altCommand = "$ThisControl.eval();";
escapeCommand = "MessageHud_Edit.onEscape();";
historySize = "5";
maxLength = "120";
};
};
};
//--- OBJECT WRITE BEGIN ---
new GuiControl(MainChatHud) {
profile = "GuiModelessDialogProfile";
horizSizing = "width";
vertSizing = "height";
position = "0 0";
extent = "640 480";
minExtent = "8 8";
visible = "1";
helpTag = "0";
noCursor = "1";
new GuiControl() {
profile = "GuiModelessDialogProfile";
horizSizing = "relative";
vertSizing = "bottom";
position = "0 0";
extent = "400 300";
minExtent = "8 8";
visible = "1";
helpTag = "0";
new GuiBitmapBorderCtrl(OuterChatHud) {
profile = "ChatHudBorderProfile";
horizSizing = "width";
vertSizing = "bottom";
position = "0 0";
extent = "272 88";
minExtent = "8 8";
visible = "1";
helpTag = "0";
useVariable = "0";
tile = "0";
new GuiBitmapCtrl() {
profile = "GuiDefaultProfile";
horizSizing = "width";
vertSizing = "height";
position = "8 8";
extent = "256 72";
minExtent = "8 8";
visible = "1";
helpTag = "0";
bitmap = "data/UI/art/gui/hudfill.png";
wrap = "0";
};
new GuiButtonCtrl(chatPageDown) {
profile = "GuiButtonProfile";
horizSizing = "left";
vertSizing = "top";
position = "220 58";
extent = "36 14";
minExtent = "8 8";
visible = "0";
helpTag = "0";
text = "Dwn";
groupNum = "-1";
buttonType = "PushButton";
};
new GuiScrollCtrl(ChatScrollHud) {
profile = "ChatHudScrollProfile";
horizSizing = "width";
vertSizing = "height";
position = "8 8";
extent = "256 72";
minExtent = "8 8";
visible = "1";
helpTag = "0";
willFirstRespond = "1";
hScrollBar = "alwaysOff";
vScrollBar = "alwaysOff";
lockHorizScroll = "true";
lockVertScroll = "false";
constantThumbHeight = "0";
childMargin = "0 0";
new GuiMessageVectorCtrl(ChatHud) {
profile = "ChatHudMessageProfile";
horizSizing = "width";
vertSizing = "height";
position = "1 1";
extent = "252 16";
minExtent = "8 8";
visible = "1";
helpTag = "0";
lineSpacing = "0";
lineContinuedIndex = "10";
allowedMatches[0] = "http";
allowedMatches[1] = "tgeserver";
matchColor = "0 0 255 255";
maxColorIndex = "5";
};
};
};
};
};
//--- OBJECT WRITE END ---

View file

@ -0,0 +1,80 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// PlayGui is the main TSControl through which the game is viewed.
// The PlayGui also contains the hud controls.
//-----------------------------------------------------------------------------
function PlayGui::onWake(%this)
{
// Turn off any shell sounds...
// sfxStop( ... );
$enableDirectInput = "1";
activateDirectInput();
// Message hud dialog
if ( isObject( MainChatHud ) )
{
Canvas.pushDialog( MainChatHud );
chatHud.attach(HudMessageVector);
}
// just update the action map here
moveMap.push();
// hack city - these controls are floating around and need to be clamped
if ( isFunction( "refreshCenterTextCtrl" ) )
schedule(0, 0, "refreshCenterTextCtrl");
if ( isFunction( "refreshBottomTextCtrl" ) )
schedule(0, 0, "refreshBottomTextCtrl");
}
function PlayGui::onSleep(%this)
{
if ( isObject( MainChatHud ) )
Canvas.popDialog( MainChatHud );
// pop the keymaps
moveMap.pop();
}
function PlayGui::clearHud( %this )
{
Canvas.popDialog( MainChatHud );
while ( %this.getCount() > 0 )
%this.getObject( 0 ).delete();
}
//-----------------------------------------------------------------------------
function refreshBottomTextCtrl()
{
BottomPrintText.position = "0 0";
}
function refreshCenterTextCtrl()
{
CenterPrintText.position = "0 0";
}

View file

@ -0,0 +1,381 @@
//--- OBJECT WRITE BEGIN ---
%guiContent = new GameTSCtrl(PlayGui) {
cameraZRot = "0";
forceFOV = "0";
reflectPriority = "1";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
isContainer = "1";
Profile = "GuiContentProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "0 0";
Extent = "1024 768";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "1";
Enabled = "1";
helpTag = "0";
noCursor = "1";
new GuiBitmapCtrl(CenterPrintDlg) {
bitmap = "data/UI/art/gui/hudfill.png";
wrap = "0";
isContainer = "0";
Profile = "CenterPrintProfile";
HorizSizing = "center";
VertSizing = "center";
position = "237 375";
Extent = "550 20";
MinExtent = "8 8";
canSave = "1";
Visible = "0";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
new GuiMLTextCtrl(CenterPrintText) {
lineSpacing = "2";
allowColorChars = "0";
maxChars = "-1";
useURLMouseCursor = "0";
isContainer = "0";
Profile = "CenterPrintTextProfile";
HorizSizing = "center";
VertSizing = "center";
position = "0 0";
Extent = "546 12";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
};
};
new GuiBitmapCtrl(BottomPrintDlg) {
bitmap = "data/UI/art/gui/hudfill.png";
wrap = "0";
isContainer = "0";
Profile = "CenterPrintProfile";
HorizSizing = "center";
VertSizing = "top";
position = "237 719";
Extent = "550 20";
MinExtent = "8 8";
canSave = "1";
Visible = "0";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
new GuiMLTextCtrl(BottomPrintText) {
lineSpacing = "2";
allowColorChars = "0";
maxChars = "-1";
useURLMouseCursor = "0";
isContainer = "0";
Profile = "CenterPrintTextProfile";
HorizSizing = "center";
VertSizing = "center";
position = "0 0";
Extent = "546 12";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
};
};
new GuiBitmapCtrl(LagIcon) {
bitmap = "data/UI/art/gui/lagIcon.png";
wrap = "0";
isContainer = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "572 3";
Extent = "32 32";
MinExtent = "8 8";
canSave = "1";
Visible = "0";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
};
new GuiShapeNameHud() {
fillColor = "0 0 0 0.25";
frameColor = "0 1 0 1";
textColor = "0 1 0 1";
showFill = "0";
showFrame = "0";
verticalOffset = "0.2";
distanceFade = "0.1";
isContainer = "0";
Profile = "GuiModelessDialogProfile";
HorizSizing = "width";
VertSizing = "height";
position = "0 0";
Extent = "1024 768";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
};
new GuiCrossHairHud(Reticle) {
damageFillColor = "0 1 0 1";
damageFrameColor = "1 0.6 0 1";
damageRect = "50 4";
damageOffset = "0 10";
bitmap = "data/FPSGameplay/art/gui/weaponHud/blank.png";
wrap = "0";
isContainer = "0";
Profile = "GuiModelessDialogProfile";
HorizSizing = "center";
VertSizing = "center";
position = "496 368";
Extent = "32 32";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
};
new GuiCrossHairHud(ZoomReticle) {
damageFillColor = "0 1 0 1";
damageFrameColor = "1 0.6 0 1";
damageRect = "50 4";
damageOffset = "0 10";
bitmap = "data/FPSGameplay/art/gui/weaponHud/bino.png";
wrap = "0";
isContainer = "0";
Profile = "GuiModelessDialogProfile";
HorizSizing = "width";
VertSizing = "height";
position = "0 0";
Extent = "1024 768";
MinExtent = "8 8";
canSave = "1";
Visible = "0";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
};
new GuiBitmapBorderCtrl(WeaponHUD) {
isContainer = "0";
Profile = "ChatHudBorderProfile";
HorizSizing = "right";
VertSizing = "top";
position = "78 693";
Extent = "124 72";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
new GuiBitmapCtrl() {
bitmap = "data/UI/art/hudfill.png";
wrap = "0";
isContainer = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "width";
VertSizing = "height";
position = "8 8";
Extent = "108 56";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
};
new GuiBitmapCtrl(PreviewImage) {
bitmap = "data/FPSGameplay/art/gui/weaponHud/blank.png";
wrap = "0";
isContainer = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "width";
VertSizing = "height";
position = "8 8";
Extent = "108 56";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
};
new GuiTextCtrl(AmmoAmount) {
maxLength = "255";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "0";
AnchorBottom = "0";
AnchorLeft = "0";
AnchorRight = "0";
isContainer = "0";
Profile = "HudTextItalicProfile";
HorizSizing = "right";
VertSizing = "top";
position = "40 8";
Extent = "120 16";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
canSaveDynamicFields = "0";
};
};
new GuiHealthTextHud() {
fillColor = "0 0 0 0.65";
frameColor = "0 0 0 1";
textColor = "1 1 1 1";
warningColor = "1 0 0 1";
showFill = "1";
showFrame = "1";
showTrueValue = "0";
showEnergy = "0";
warnThreshold = "25";
pulseThreshold = "15";
pulseRate = "750";
position = "5 693";
extent = "72 72";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "top";
profile = "GuiBigTextProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiControl(DamageHUD) {
position = "384 256";
extent = "256 256";
minExtent = "8 2";
horizSizing = "center";
vertSizing = "center";
profile = "GuiDefaultProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "1";
canSave = "1";
canSaveDynamicFields = "0";
new GuiBitmapCtrl() {
bitmap = "data/FPSGameplay/art/gui/damageFront.png";
wrap = "0";
position = "0 0";
extent = "256 32";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiDefaultProfile";
visible = "0";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "Damage_Front";
hidden = "1";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiBitmapCtrl() {
bitmap = "data/FPSGameplay/art/gui/damageTop.png";
wrap = "0";
position = "0 0";
extent = "256 32";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiDefaultProfile";
visible = "0";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "Damage_Top";
hidden = "1";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiBitmapCtrl() {
bitmap = "data/FPSGameplay/art/gui/damageBottom.png";
wrap = "0";
position = "0 224";
extent = "256 32";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiDefaultProfile";
visible = "0";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "Damage_Bottom";
hidden = "1";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiBitmapCtrl() {
bitmap = "data/FPSGameplay/art/gui/damageLeft.png";
wrap = "0";
position = "0 0";
extent = "32 256";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiDefaultProfile";
visible = "0";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "Damage_Left";
hidden = "1";
canSave = "1";
canSaveDynamicFields = "0";
};
new GuiBitmapCtrl() {
bitmap = "data/FPSGameplay/art/gui/damageRight.png";
wrap = "0";
position = "224 0";
extent = "32 256";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiDefaultProfile";
visible = "0";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "Damage_Right";
hidden = "1";
canSave = "1";
canSaveDynamicFields = "0";
};
};
};
//--- OBJECT WRITE END ---

View file

@ -0,0 +1,178 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
//
// Copyright (c) 2001 GarageGames.Com
//-----------------------------------------------------------------------------
//--- OBJECT WRITE BEGIN ---
%guiContent = new GuiControl(PlayerListGui) {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "1";
Profile = "GuiModelessDialogProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "0 0";
Extent = "1024 768";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
noCursor = true;
new GuiBitmapBorderCtrl() {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "0";
Profile = "ChatHudBorderProfile";
HorizSizing = "center";
VertSizing = "center";
Position = "362 263";
Extent = "299 242";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
new GuiBitmapCtrl() {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "0";
Profile = "ChatHudScrollProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "8 8";
Extent = "283 226";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
bitmap = "data/FPSGameplay/art/gui/hudfill.png";
wrap = "0";
new GuiScrollCtrl() {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "1";
Profile = "ChatHudScrollProfile";
HorizSizing = "width";
VertSizing = "height";
Position = "0 24";
Extent = "228 202";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
willFirstRespond = "1";
hScrollBar = "alwaysOff";
vScrollBar = "dynamic";
lockHorizScroll = "true";
lockVertScroll = "false";
constantThumbHeight = "0";
childMargin = "0 0";
mouseWheelScrollSpeed = "-1";
new GuiTextListCtrl(PlayerListGuiList) {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "1";
Profile = "HudTextNormalProfile";
HorizSizing = "width";
VertSizing = "height";
Position = "1 1";
Extent = "226 9";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
enumerate = "0";
resizeCell = "1";
columns = "0 98 153 200";
fitParentWidth = "1";
clipColumnText = "0";
};
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "0";
Profile = "HudTextBoldProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "104 2";
Extent = "33 18";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Score";
maxLength = "255";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "0";
Profile = "HudTextBoldProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "158 2";
Extent = "30 18";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Kills";
maxLength = "255";
};
new GuiTextCtrl() {
canSaveDynamicFields = "0";
Enabled = "1";
isContainer = "0";
Profile = "HudTextBoldProfile";
HorizSizing = "right";
VertSizing = "bottom";
Position = "206 2";
Extent = "37 18";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
tooltipprofile = "GuiToolTipProfile";
hovertime = "1000";
Margin = "0 0 0 0";
Padding = "0 0 0 0";
AnchorTop = "1";
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Deaths";
maxLength = "255";
};
};
};
};
//--- OBJECT WRITE END ---

View file

@ -0,0 +1,106 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
function VolumetricFog::onEnterFog(%this,%obj)
{
// This method is called whenever the control object (Camera or Player)
// %obj enters the fog area.
// echo("Control Object " @ %obj @ " enters fog " @ %this);
}
function VolumetricFog::onLeaveFog(%this,%obj)
{
// This method is called whenever the control object (Camera or Player)
// %obj leaves the fog area.
// echo("Control Object " @ %obj @ " left fog " @ %this);
}
function VolumetricFog::Dissolve(%this,%speed,%delete)
{
// This method dissolves the fog at speed milliseconds
%this.isBuilding = true;
if (%this.FogDensity > 0)
{
%this.setFogDensity(%this.FogDensity - 0.005);
%this.schedule(%speed,Dissolve,%speed,%delete);
}
else
{
%this.isBuilding = false;
%this.SetFogDensity(0.0);
if (%delete !$= "" && %delete !$="0" && %delete !$="false")
%this.schedule(250,delete);
}
}
function VolumetricFog::Thicken(%this,%speed, %end_density)
{
// This method thickens the fog at speed milliseconds to a density of %end_density
%this.isBuilding = true;
if (%this.FogDensity + 0.005 < %end_density)
{
%this.setFogDensity(%this.FogDensity + 0.005);
%this.schedule(%speed,Thicken,%speed, %end_density);
}
else
{
%this.setFogDensity(%end_density);
%this.isBuilding = false;
}
}
function GenerateFog(%pos,%scale,%color,%density)
{
// This function can be used to generate some fog caused by massive gunfire etc.
// Change shape and modulation data to your likings.
%fog=new VolumetricFog() {
shapeName = "data/FPSGameplay/art/environment/Fog_Sphere.dts";
fogColor = %color;
fogDensity = "0.0";
ignoreWater = "0";
MinSize = "250";
FadeSize = "750";
texture = "data/FPSGameplay/art/environment/FogMod_heavy.dds";
tiles = "1";
modStrength = "0.2";
PrimSpeed = "-0.01 0.04";
SecSpeed = "0.02 0.02";
position = %pos;
rotation = "0 0 1 20.354";
scale = %scale;
canSave = "1";
canSaveDynamicFields = "1";
};
if (isObject(%fog))
{
MissionCleanup.add(%fog);
%fog.Thicken(500,%density);
}
return %fog;
}

View file

@ -0,0 +1,333 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// AIPlayer callbacks
// The AIPlayer class implements the following callbacks:
//
// PlayerData::onStop(%this,%obj)
// PlayerData::onMove(%this,%obj)
// PlayerData::onReachDestination(%this,%obj)
// PlayerData::onMoveStuck(%this,%obj)
// PlayerData::onTargetEnterLOS(%this,%obj)
// PlayerData::onTargetExitLOS(%this,%obj)
// PlayerData::onAdd(%this,%obj)
//
// Since the AIPlayer doesn't implement it's own datablock, these callbacks
// all take place in the PlayerData namespace.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Demo Pathed AIPlayer.
//-----------------------------------------------------------------------------
function DemoPlayer::onReachDestination(%this,%obj)
{
//echo( %obj @ " onReachDestination" );
// Moves to the next node on the path.
// Override for all player. Normally we'd override this for only
// a specific player datablock or class of players.
if (%obj.path !$= "")
{
if (%obj.currentNode == %obj.targetNode)
%this.onEndOfPath(%obj,%obj.path);
else
%obj.moveToNextNode();
}
}
function DemoPlayer::onMoveStuck(%this,%obj)
{
//echo( %obj @ " onMoveStuck" );
}
function DemoPlayer::onTargetExitLOS(%this,%obj)
{
//echo( %obj @ " onTargetExitLOS" );
}
function DemoPlayer::onTargetEnterLOS(%this,%obj)
{
//echo( %obj @ " onTargetEnterLOS" );
}
function DemoPlayer::onEndOfPath(%this,%obj,%path)
{
%obj.nextTask();
}
function DemoPlayer::onEndSequence(%this,%obj,%slot)
{
echo("Sequence Done!");
%obj.stopThread(%slot);
%obj.nextTask();
}
//-----------------------------------------------------------------------------
// AIPlayer static functions
//-----------------------------------------------------------------------------
function AIPlayer::spawnAtLocation(%name, %spawnPoint)
{
// Create the demo player object
%player = new AiPlayer()
{
dataBlock = DemoPlayer;
path = "";
};
MissionCleanup.add(%player);
%player.setShapeName(%name);
%player.setTransform(%spawnPoint);
return %player;
}
function AIPlayer::spawnOnPath(%name, %path)
{
// Spawn a player and place him on the first node of the path
if (!isObject(%path))
return 0;
%node = %path.getObject(0);
%player = AIPlayer::spawnAtLocation(%name, %node.getTransform());
return %player;
}
//-----------------------------------------------------------------------------
// AIPlayer methods
//-----------------------------------------------------------------------------
function AIPlayer::followPath(%this,%path,%node)
{
// Start the player following a path
if (!isObject(%path))
{
%this.path = "";
return;
}
if (%node > %path.getCount() - 1)
%this.targetNode = %path.getCount() - 1;
else
%this.targetNode = %node;
if (%this.path $= %path)
%this.moveToNode(%this.currentNode);
else
{
%this.path = %path;
%this.moveToNode(0);
}
}
function AIPlayer::moveToNextNode(%this)
{
%pathNodeCount=%this.path.getCount();
%slowdown=0;
%targetNode=%this.currentNode + 1;
if (%this.path.isLooping) {
%targetNode %= %pathNodeCount;
} else {
if (%targetNode >= %pathNodeCount-1) {
%targetNode=%pathNodeCount-1;
if (%currentNode < %targetNode)
%slowdown=1;
}
}
%this.moveToNode(%targetNode, %slowdown);
}
function AIPlayer::moveToNode(%this,%index,%slowdown)
{
// Move to the given path node index
%this.currentNode = %index;
%node = %this.path.getObject(%index);
%this.setMoveDestination(%node.getTransform(),%slowdown);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
function AIPlayer::pushTask(%this,%method)
{
if (%this.taskIndex $= "")
{
%this.taskIndex = 0;
%this.taskCurrent = -1;
}
%this.task[%this.taskIndex] = %method;
%this.taskIndex++;
if (%this.taskCurrent == -1)
%this.executeTask(%this.taskIndex - 1);
}
function AIPlayer::clearTasks(%this)
{
%this.taskIndex = 0;
%this.taskCurrent = -1;
}
function AIPlayer::nextTask(%this)
{
if (%this.taskCurrent != -1)
if (%this.taskCurrent < %this.taskIndex - 1)
%this.executeTask(%this.taskCurrent++);
else
%this.taskCurrent = -1;
}
function AIPlayer::executeTask(%this,%index)
{
%this.taskCurrent = %index;
eval(%this.getId() @"."@ %this.task[%index] @";");
}
//-----------------------------------------------------------------------------
function AIPlayer::singleShot(%this)
{
// The shooting delay is used to pulse the trigger
%this.setImageTrigger(0, true);
%this.setImageTrigger(0, false);
%delay = %this.getDataBlock().shootingDelay;
if (%delay $= "")
%delay = 1000;
%this.trigger = %this.schedule(%delay, singleShot);
}
//-----------------------------------------------------------------------------
function AIPlayer::wait(%this, %time)
{
%this.schedule(%time * 1000, "nextTask");
}
function AIPlayer::done(%this,%time)
{
%this.schedule(0, "delete");
}
function AIPlayer::fire(%this,%bool)
{
if (%bool)
{
cancel(%this.trigger);
%this.singleShot();
}
else
cancel(%this.trigger);
%this.nextTask();
}
function AIPlayer::aimAt(%this,%object)
{
echo("Aim: "@ %object);
%this.setAimObject(%object);
%this.nextTask();
}
function AIPlayer::animate(%this,%seq)
{
//%this.stopThread(0);
//%this.playThread(0,%seq);
%this.setActionThread(%seq);
}
// ----------------------------------------------------------------------------
// Some handy getDistance/nearestTarget functions for the AI to use
// ----------------------------------------------------------------------------
function AIPlayer::getTargetDistance(%this, %target)
{
echo("\c4AIPlayer::getTargetDistance("@ %this @", "@ %target @")");
$tgt = %target;
%tgtPos = %target.getPosition();
%eyePoint = %this.getWorldBoxCenter();
%distance = VectorDist(%tgtPos, %eyePoint);
echo("Distance to target = "@ %distance);
return %distance;
}
function AIPlayer::getNearestPlayerTarget(%this)
{
echo("\c4AIPlayer::getNearestPlayerTarget("@ %this @")");
%index = -1;
%botPos = %this.getPosition();
%count = ClientGroup.getCount();
for(%i = 0; %i < %count; %i++)
{
%client = ClientGroup.getObject(%i);
if (%client.player $= "" || %client.player == 0)
return -1;
%playerPos = %client.player.getPosition();
%tempDist = VectorDist(%playerPos, %botPos);
if (%i == 0)
{
%dist = %tempDist;
%index = %i;
}
else
{
if (%dist > %tempDist)
{
%dist = %tempDist;
%index = %i;
}
}
}
return %index;
}
//-----------------------------------------------------------------------------
function AIPlayer::think(%player)
{
// Thinking allows us to consider other things...
%player.schedule(500, think);
}
function AIPlayer::spawn(%path)
{
%player = AIPlayer::spawnOnPath("Shootme", %path);
if (isObject(%player))
{
%player.followPath(%path, -1);
// slow this sucker down, I'm tired of chasing him!
%player.setMoveSpeed(0.5);
//%player.mountImage(xxxImage, 0);
//%player.setInventory(xxxAmmo, 1000);
//%player.think();
return %player;
}
else
return 0;
}

View file

@ -0,0 +1,85 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// Global movement speed that affects all cameras. This should be moved
// into the camera datablock.
$Camera::movementSpeed = 30;
function Observer::onTrigger(%this,%obj,%trigger,%state)
{
// state = 0 means that a trigger key was released
if (%state == 0)
return;
// Default player triggers: 0=fire 1=altFire 2=jump
%client = %obj.getControllingClient();
switch$ (%obj.mode)
{
case "Observer":
// Do something interesting.
case "Corpse":
// Viewing dead corpse, so we probably want to respawn.
$Game.preparePlayer(%client);
// Set the camera back into observer mode, since in
// debug mode we like to switch to it.
%this.setMode(%obj,"Observer");
}
}
function Observer::setMode(%this,%obj,%mode,%arg1,%arg2,%arg3)
{
switch$ (%mode)
{
case "Observer":
// Let the player fly around
%obj.setFlyMode();
case "Corpse":
// Lock the camera down in orbit around the corpse,
// which should be arg1
%transform = %arg1.getTransform();
%obj.setOrbitMode(%arg1, %transform, 0.5, 4.5, 4.5);
}
%obj.mode = %mode;
}
//-----------------------------------------------------------------------------
// Camera methods
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
function Camera::onAdd(%this,%obj)
{
// Default start mode
%this.setMode(%this.mode);
}
function Camera::setMode(%this,%mode,%arg1,%arg2,%arg3)
{
// Punt this one over to our datablock
%this.getDatablock().setMode(%this,%mode,%arg1,%arg2,%arg3);
}

View file

@ -0,0 +1,92 @@
//---------------------------------------------------------------------------
// Server side client chat'n
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// silly spam protection...
$SPAM_PROTECTION_PERIOD = 10000;
$SPAM_MESSAGE_THRESHOLD = 4;
$SPAM_PENALTY_PERIOD = 10000;
$SPAM_MESSAGE = '\c3FLOOD PROTECTION:\cr You must wait another %1 seconds.';
function GameConnection::spamMessageTimeout(%this)
{
if(%this.spamMessageCount > 0)
%this.spamMessageCount--;
}
function GameConnection::spamReset(%this)
{
%this.isSpamming = false;
}
function spamAlert(%client)
{
if($Pref::Server::FloodProtectionEnabled != true)
return(false);
if(!%client.isSpamming && (%client.spamMessageCount >= $SPAM_MESSAGE_THRESHOLD))
{
%client.spamProtectStart = getSimTime();
%client.isSpamming = true;
%client.schedule($SPAM_PENALTY_PERIOD, spamReset);
}
if(%client.isSpamming)
{
%wait = mFloor(($SPAM_PENALTY_PERIOD - (getSimTime() - %client.spamProtectStart)) / 1000);
messageClient(%client, "", $SPAM_MESSAGE, %wait);
return(true);
}
%client.spamMessageCount++;
%client.schedule($SPAM_PROTECTION_PERIOD, spamMessageTimeout);
return(false);
}
//---------------------------------------------------------------------------
function chatMessageClient( %client, %sender, %voiceTag, %voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 )
{
//see if the client has muted the sender
if ( !%client.muted[%sender] )
commandToClient( %client, 'ChatMessage', %sender, %voiceTag, %voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 );
}
function chatMessageTeam( %sender, %team, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 )
{
if ( ( %msgString $= "" ) || spamAlert( %sender ) )
return;
%count = ClientGroup.getCount();
for ( %i = 0; %i < %count; %i++ )
{
%obj = ClientGroup.getObject( %i );
if ( %obj.team == %sender.team )
chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 );
}
}
function chatMessageAll( %sender, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 )
{
if ( ( %msgString $= "" ) || spamAlert( %sender ) )
return;
%count = ClientGroup.getCount();
for ( %i = 0; %i < %count; %i++ )
{
%obj = ClientGroup.getObject( %i );
if(%sender.team != 0)
chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 );
else
{
// message sender is an observer -- only send message to other observers
if(%obj.team == %sender.team)
chatMessageClient( %obj, %sender, %sender.voiceTag, %sender.voicePitch, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10 );
}
}
}

View file

@ -0,0 +1,162 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
function CheetahCar::onAdd(%this, %obj)
{
Parent::onAdd(%this, %obj);
%obj.setWheelTire(0,CheetahCarTire);
%obj.setWheelTire(1,CheetahCarTire);
%obj.setWheelTire(2,CheetahCarTireRear);
%obj.setWheelTire(3,CheetahCarTireRear);
// Setup the car with some tires & springs
for (%i = %obj.getWheelCount() - 1; %i >= 0; %i--)
{
%obj.setWheelPowered(%i, true);
%obj.setWheelSpring(%i, CheetahCarSpring);
}
// Steer with the front tires
%obj.setWheelSteering(0, 1);
%obj.setWheelSteering(1, 1);
// Add tail lights
%obj.rightBrakeLight = new PointLight()
{
radius = "1";
isEnabled = "0";
color = "1 0 0.141176 1";
brightness = "2";
castShadows = "1";
priority = "1";
animate = "0";
animationPeriod = "1";
animationPhase = "1";
flareScale = "1";
attenuationRatio = "0 1 1";
shadowType = "DualParaboloidSinglePass";
texSize = "512";
overDarkFactor = "2000 1000 500 100";
shadowDistance = "400";
shadowSoftness = "0.15";
numSplits = "1";
logWeight = "0.91";
fadeStartDistance = "0";
lastSplitTerrainOnly = "0";
representedInLightmap = "0";
shadowDarkenColor = "0 0 0 -1";
includeLightmappedGeometryInShadow = "0";
rotation = "1 0 0 0";
canSave = "1";
canSaveDynamicFields = "1";
splitFadeDistances = "10 20 30 40";
};
%obj.leftBrakeLight = new PointLight()
{
radius = "1";
isEnabled = "0";
color = "1 0 0.141176 1";
brightness = "2";
castShadows = "1";
priority = "1";
animate = "0";
animationPeriod = "1";
animationPhase = "1";
flareScale = "1";
attenuationRatio = "0 1 1";
shadowType = "DualParaboloidSinglePass";
texSize = "512";
overDarkFactor = "2000 1000 500 100";
shadowDistance = "400";
shadowSoftness = "0.15";
numSplits = "1";
logWeight = "0.91";
fadeStartDistance = "0";
lastSplitTerrainOnly = "0";
representedInLightmap = "0";
shadowDarkenColor = "0 0 0 -1";
includeLightmappedGeometryInShadow = "0";
rotation = "1 0 0 0";
canSave = "1";
canSaveDynamicFields = "1";
splitFadeDistances = "10 20 30 40";
};
// Mount a ShapeBaseImageData
%didMount = %obj.mountImage(TurretImage, %this.turretSlot);
// Mount the brake lights
%obj.mountObject(%obj.rightBrakeLight, %this.rightBrakeSlot);
%obj.mountObject(%obj.leftBrakeLight, %this.leftBrakeSlot);
}
function CheetahCar::onRemove(%this, %obj)
{
Parent::onRemove(%this, %obj);
if(isObject(%obj.rightBrakeLight))
%obj.rightBrakeLight.delete();
if(isObject(%obj.leftBrakeLight))
%obj.leftBrakeLight.delete();
if(isObject(%obj.turret))
%obj.turret.delete();
}
function serverCmdtoggleBrakeLights(%client)
{
%car = %client.player.getControlObject();
if (%car.getClassName() $= "WheeledVehicle")
{
if(%car.rightBrakeLight.isEnabled)
{
%car.rightBrakeLight.setLightEnabled(0);
%car.leftBrakeLight.setLightEnabled(0);
}
else
{
%car.rightBrakeLight.setLightEnabled(1);
%car.leftBrakeLight.setLightEnabled(1);
}
}
}
// Callback invoked when an input move trigger state changes when the CheetahCar
// is the control object
function CheetahCar::onTrigger(%this, %obj, %index, %state)
{
// Pass trigger states on to TurretImage (to fire weapon)
switch ( %index )
{
case 0: %obj.setImageTrigger( %this.turretSlot, %state );
case 1: %obj.setImageAltTrigger( %this.turretSlot, %state );
}
}
function TurretImage::onMount(%this, %obj, %slot)
{
// Load the gun
%obj.setImageAmmo(%slot, true);
}

View file

@ -0,0 +1,140 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Misc server commands avialable to clients
//-----------------------------------------------------------------------------
function serverCmdSuicide(%client)
{
if (isObject(%client.player))
%client.player.kill("Suicide");
}
function serverCmdPlayCel(%client,%anim)
{
if (isObject(%client.player))
%client.player.playCelAnimation(%anim);
}
function serverCmdTestAnimation(%client, %anim)
{
if (isObject(%client.player))
%client.player.playTestAnimation(%anim);
}
function serverCmdPlayDeath(%client)
{
if (isObject(%client.player))
%client.player.playDeathAnimation();
}
// ----------------------------------------------------------------------------
// Throw/Toss
// ----------------------------------------------------------------------------
function serverCmdThrow(%client, %data)
{
%player = %client.player;
if(!isObject(%player) || %player.getState() $= "Dead" || !$Game::Running)
return;
switch$ (%data)
{
case "Weapon":
%item = (%player.getMountedImage($WeaponSlot) == 0) ? "" : %player.getMountedImage($WeaponSlot).item;
if (%item !$="")
%player.throw(%item);
case "Ammo":
%weapon = (%player.getMountedImage($WeaponSlot) == 0) ? "" : %player.getMountedImage($WeaponSlot);
if (%weapon !$= "")
{
if(%weapon.ammo !$= "")
%player.throw(%weapon.ammo);
}
default:
if(%player.hasInventory(%data.getName()))
%player.throw(%data);
}
}
// ----------------------------------------------------------------------------
// Force game end and cycle
// Probably don't want this in a final game without some checks. Anyone could
// restart a game.
// ----------------------------------------------------------------------------
function serverCmdFinishGame()
{
cycleGame();
}
// ----------------------------------------------------------------------------
// Cycle weapons
// ----------------------------------------------------------------------------
function serverCmdCycleWeapon(%client, %direction)
{
%client.getControlObject().cycleWeapon(%direction);
}
// ----------------------------------------------------------------------------
// Unmount current weapon
// ----------------------------------------------------------------------------
function serverCmdUnmountWeapon(%client)
{
%client.getControlObject().unmountImage($WeaponSlot);
}
// ----------------------------------------------------------------------------
// Weapon reloading
// ----------------------------------------------------------------------------
function serverCmdReloadWeapon(%client)
{
%player = %client.getControlObject();
%image = %player.getMountedImage($WeaponSlot);
// Don't reload if the weapon's full.
if (%player.getInventory(%image.ammo) == %image.ammo.maxInventory)
return;
if (%image > 0)
%image.clearAmmoClip(%player, $WeaponSlot);
}
//----------------------------------------------------------------------------
// Server chat message handlers
//----------------------------------------------------------------------------
function serverCmdTeamMessageSent(%client, %text)
{
if(strlen(%text) >= $Pref::Server::MaxChatLen)
%text = getSubStr(%text, 0, $Pref::Server::MaxChatLen);
chatMessageTeam(%client, %client.team, '\c3%1: %2', %client.playerName, %text);
}
function serverCmdMessageSent(%client, %text)
{
if(strlen(%text) >= $Pref::Server::MaxChatLen)
%text = getSubStr(%text, 0, $Pref::Server::MaxChatLen);
chatMessageAll(%client, '\c4%1: %2', %client.playerName, %text);
}

View file

@ -0,0 +1,725 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// DeathmatchGame
// ----------------------------------------------------------------------------
// Depends on methods found in gameCore.cs. Those added here are specific to
// this game type and/or over-ride the "default" game functionaliy.
//
// The desired Game Type must be added to each mission's LevelInfo object.
// - gameType = "Deathmatch";
// If this information is missing then the GameCore will default to Deathmatch.
// ----------------------------------------------------------------------------
function DeathMatchGame::initGameVars(%game)
{
//echo (%game @"\c4 -> "@ %game.class @" -> DeathMatchGame::initGameVars");
//-----------------------------------------------------------------------------
// What kind of "player" is spawned is either controlled directly by the
// SpawnSphere or it defaults back to the values set here. This also controls
// which SimGroups to attempt to select the spawn sphere's from by walking down
// the list of SpawnGroups till it finds a valid spawn object.
// These override the values set in core/scripts/server/spawn.cs
//-----------------------------------------------------------------------------
// Leave $Game::defaultPlayerClass and $Game::defaultPlayerDataBlock as empty strings ("")
// to spawn a the $Game::defaultCameraClass as the control object.
$Game::defaultPlayerClass = "Player";
$Game::defaultPlayerDataBlock = "DefaultPlayerData";
$Game::defaultPlayerSpawnGroups = "PlayerSpawnPoints PlayerDropPoints";
//-----------------------------------------------------------------------------
// What kind of "camera" is spawned is either controlled directly by the
// SpawnSphere or it defaults back to the values set here. This also controls
// which SimGroups to attempt to select the spawn sphere's from by walking down
// the list of SpawnGroups till it finds a valid spawn object.
// These override the values set in core/scripts/server/spawn.cs
//-----------------------------------------------------------------------------
$Game::defaultCameraClass = "Camera";
$Game::defaultCameraDataBlock = "Observer";
$Game::defaultCameraSpawnGroups = "CameraSpawnPoints PlayerSpawnPoints PlayerDropPoints";
// Set the gameplay parameters
%game.duration = 30 * 60;
%game.endgameScore = 20;
%game.endgamePause = 10;
%game.allowCycling = false; // Is mission cycling allowed?
}
function DeathMatchGame::onGameDurationEnd(%game)
{
// This "redirect" is here so that we can abort the game cycle if
// the $Game::Duration variable has been cleared, without having
// to have a function to cancel the schedule.
if ($Game::Duration && !(EditorIsActive() && GuiEditorIsActive()))
Game.onGameDurationEnd();
}
function DeathMatchGame::onClientEnterGame(%this, %client)
{
// This function currently relies on some helper functions defined in
// core/scripts/spawn.cs. For custom spawn behaviors one can either
// override the properties on the SpawnSphere's or directly override the
// functions themselves.
//echo (%game @"\c4 -> "@ %game.class @" -> GameCore::onClientEntergame");
// Sync the client's clocks to the server's
commandToClient(%client, 'SyncClock', $Sim::Time - $Game::StartTime);
//Set the player name based on the client's connection data
%client.setPlayerName(%client.connectData);
// Find a spawn point for the camera
// This function currently relies on some helper functions defined in
// core/scripts/server/spawn.cs. For custom spawn behaviors one can either
// override the properties on the SpawnSphere's or directly override the
// functions themselves.
%cameraSpawnPoint = pickCameraSpawnPoint($Game::DefaultCameraSpawnGroups);
// Spawn a camera for this client using the found %spawnPoint
%client.spawnCamera(%cameraSpawnPoint);
// Setup game parameters, the onConnect method currently starts
// everyone with a 0 score.
%client.score = 0;
%client.kills = 0;
%client.deaths = 0;
// weaponHUD
%client.RefreshWeaponHud(0, "", "");
// Prepare the player object.
%this.preparePlayer(%client);
// Inform the client of all the other clients
%count = ClientGroup.getCount();
for (%cl = 0; %cl < %count; %cl++)
{
%other = ClientGroup.getObject(%cl);
if ((%other != %client))
{
// These should be "silent" versions of these messages...
messageClient(%client, 'MsgClientJoin', "",
%other.playerName,
%other,
%other.sendGuid,
%other.team,
%other.score,
%other.kills,
%other.deaths,
%other.isAIControlled(),
%other.isAdmin,
%other.isSuperAdmin);
}
}
// Inform the client we've joined up
messageClient(%client,
'MsgClientJoin', '\c2Welcome to the Torque demo app %1.',
%client.playerName,
%client,
%client.sendGuid,
%client.team,
%client.score,
%client.kills,
%client.deaths,
%client.isAiControlled(),
%client.isAdmin,
%client.isSuperAdmin);
// Inform all the other clients of the new guy
messageAllExcept(%client, -1, 'MsgClientJoin', '\c1%1 joined the game.',
%client.playerName,
%client,
%client.sendGuid,
%client.team,
%client.score,
%client.kills,
%client.deaths,
%client.isAiControlled(),
%client.isAdmin,
%client.isSuperAdmin);
}
function DeathMatchGame::onClientLeaveGame(%this, %client)
{
// Cleanup the camera
if (isObject(%this.camera))
%this.camera.delete();
}
//-----------------------------------------------------------------------------
// The server has started up so do some game start up
//-----------------------------------------------------------------------------
function DeathMatchGame::onMissionStart(%this)
{
//set up the game and game variables
%this.initGameVars();
$Game::Duration = %this.duration;
$Game::EndGameScore = %this.endgameScore;
$Game::EndGamePause = %this.endgamePause;
//echo (%game @"\c4 -> "@ %game.class @" -> GameCore::onStartGame");
if ($Game::Running)
{
error("startGame: End the game first!");
return;
}
// Inform the client we're starting up
for (%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++)
{
%cl = ClientGroup.getObject(%clientIndex);
commandToClient(%cl, 'GameStart');
// Other client specific setup..
%cl.score = 0;
%cl.kills = 0;
%cl.deaths = 0;
}
// Start the game timer
if ($Game::Duration)
$Game::Schedule = %this.schedule($Game::Duration * 1000, "onGameDurationEnd");
$Game::Running = true;
$Game = %this;
}
function DeathMatchGame::onMissionEnded(%this)
{
if (!$Game::Running)
{
error("endGame: No game running!");
return;
}
// Stop any game timers
cancel($Game::Schedule);
for (%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++)
{
%cl = ClientGroup.getObject(%clientIndex);
commandToClient(%cl, 'GameEnd', $Game::EndGamePause);
}
$Game::Running = false;
$Game::Cycling = false;
$Game = "";
}
function DeathMatchGame::onMissionReset(%this)
{
// Called by resetMission(), after all the temporary mission objects
// have been deleted.
%this.initGameVars();
$Game::Duration = %this.duration;
$Game::EndGameScore = %this.endgameScore;
$Game::EndGamePause = %this.endgamePause;
}
//-----------------------------------------------------------------------------
// Functions that implement game-play
// These are here for backwards compatibilty only, games and/or mods should
// really be overloading the server and mission functions listed ubove.
//-----------------------------------------------------------------------------
// Added this stage to creating a player so game types can override it easily.
// This is a good place to initiate team selection.
function DeathMatchGame::preparePlayer(%this, %client)
{
//echo (%game @"\c4 -> "@ %game.class @" -> GameCore::preparePlayer");
// Find a spawn point for the player
// This function currently relies on some helper functions defined in
// core/scripts/spawn.cs. For custom spawn behaviors one can either
// override the properties on the SpawnSphere's or directly override the
// functions themselves.
%playerSpawnPoint = pickPlayerSpawnPoint($Game::DefaultPlayerSpawnGroups);
// Spawn a camera for this client using the found %spawnPoint
//%client.spawnPlayer(%playerSpawnPoint);
%this.spawnPlayer(%client, %playerSpawnPoint);
// Starting equipment
%this.loadOut(%client.player);
}
function DeathMatchGame::loadOut(%game, %player)
{
//echo (%game @"\c4 -> "@ %game.class @" -> GameCore::loadOut");
%player.clearWeaponCycle();
%player.setInventory(Ryder, 1);
%player.setInventory(RyderClip, %player.maxInventory(RyderClip));
%player.setInventory(RyderAmmo, %player.maxInventory(RyderAmmo)); // Start the gun loaded
%player.addToWeaponCycle(Ryder);
%player.setInventory(Lurker, 1);
%player.setInventory(LurkerClip, %player.maxInventory(LurkerClip));
%player.setInventory(LurkerAmmo, %player.maxInventory(LurkerAmmo)); // Start the gun loaded
%player.addToWeaponCycle(Lurker);
%player.setInventory(LurkerGrenadeLauncher, 1);
%player.setInventory(LurkerGrenadeAmmo, %player.maxInventory(LurkerGrenadeAmmo));
%player.addToWeaponCycle(LurkerGrenadeLauncher);
%player.setInventory(ProxMine, %player.maxInventory(ProxMine));
%player.addToWeaponCycle(ProxMine);
%player.setInventory(DeployableTurret, %player.maxInventory(DeployableTurret));
%player.addToWeaponCycle(DeployableTurret);
if (%player.getDatablock().mainWeapon.image !$= "")
{
%player.mountImage(%player.getDatablock().mainWeapon.image, 0);
}
else
{
%player.mountImage(Ryder, 0);
}
}
// Customized kill message for falling deaths
function sendMsgClientKilled_Impact( %msgType, %client, %sourceClient, %damLoc )
{
messageAll( %msgType, '%1 fell to his death!', %client.playerName );
}
// Customized kill message for suicides
function sendMsgClientKilled_Suicide( %msgType, %client, %sourceClient, %damLoc )
{
messageAll( %msgType, '%1 takes his own life!', %client.playerName );
}
// Default death message
function sendMsgClientKilled_Default( %msgType, %client, %sourceClient, %damLoc )
{
if ( %sourceClient == %client )
sendMsgClientKilled_Suicide(%client, %sourceClient, %damLoc);
else if ( %sourceClient.team !$= "" && %sourceClient.team $= %client.team )
messageAll( %msgType, '%1 killed by %2 - friendly fire!', %client.playerName, %sourceClient.playerName );
else
messageAll( %msgType, '%1 gets nailed by %2!', %client.playerName, %sourceClient.playerName );
}
function DeathMatchGame::onDeath(%game, %client, %sourceObject, %sourceClient, %damageType, %damLoc)
{
//echo (%game @"\c4 -> "@ %game.class @" -> GameCore::onDeath");
// clear the weaponHUD
%client.RefreshWeaponHud(0, "", "");
// Clear out the name on the corpse
%client.player.setShapeName("");
// Switch the client over to the death cam and unhook the player object.
if (isObject(%client.camera) && isObject(%client.player))
{
%client.camera.setMode("Corpse", %client.player);
%client.setControlObject(%client.camera);
}
%client.player = 0;
// Display damage appropriate kill message
%sendMsgFunction = "sendMsgClientKilled_" @ %damageType;
if ( !isFunction( %sendMsgFunction ) )
%sendMsgFunction = "sendMsgClientKilled_Default";
call( %sendMsgFunction, 'MsgClientKilled', %client, %sourceClient, %damLoc );
// Dole out points and check for win
if (( %damageType $= "Suicide" || %sourceClient == %client ) && isObject(%sourceClient))
{
%game.incDeaths( %client, 1, true );
%game.incScore( %client, -1, false );
}
else
{
%game.incDeaths( %client, 1, false );
%game.incScore( %sourceClient, 1, true );
%game.incKills( %sourceClient, 1, false );
// If the game may be ended by a client getting a particular score, check that now.
if ( $Game::EndGameScore > 0 && %sourceClient.kills >= $Game::EndGameScore )
%game.cycleGame();
}
}
// ----------------------------------------------------------------------------
// Scoring
// ----------------------------------------------------------------------------
function DeathMatchGame::incKills(%game, %client, %kill, %dontMessageAll)
{
%client.kills += %kill;
if( !%dontMessageAll )
messageAll('MsgClientScoreChanged', "", %client.score, %client.kills, %client.deaths, %client);
}
function DeathMatchGame::incDeaths(%game, %client, %death, %dontMessageAll)
{
%client.deaths += %death;
if( !%dontMessageAll )
messageAll('MsgClientScoreChanged', "", %client.score, %client.kills, %client.deaths, %client);
}
function DeathMatchGame::incScore(%game, %client, %score, %dontMessageAll)
{
%client.score += %score;
if( !%dontMessageAll )
messageAll('MsgClientScoreChanged', "", %client.score, %client.kills, %client.deaths, %client);
}
function DeathMatchGame::getScore(%client) { return %client.score; }
function DeathMatchGame::getKills(%client) { return %client.kills; }
function DeathMatchGame::getDeaths(%client) { return %client.deaths; }
function DeathMatchGame::getTeamScore(%client)
{
%score = %client.score;
if ( %client.team !$= "" )
{
// Compute team score
for (%i = 0; %i < ClientGroup.getCount(); %i++)
{
%other = ClientGroup.getObject(%i);
if ((%other != %client) && (%other.team $= %client.team))
%score += %other.score;
}
}
return %score;
}
// ----------------------------------------------------------------------------
// Spawning
// ----------------------------------------------------------------------------
function DeathMatchGame::spawnPlayer(%game, %client, %spawnPoint, %noControl)
{
//echo (%game @"\c4 -> "@ %game.class @" -> GameCore::spawnPlayer");
if (isObject(%client.player))
{
// The client should not already have a player. Assigning
// a new one could result in an uncontrolled player object.
error("Attempting to create a player for a client that already has one!");
}
// Attempt to treat %spawnPoint as an object
if (getWordCount(%spawnPoint) == 1 && isObject(%spawnPoint))
{
// Defaults
%spawnClass = $Game::DefaultPlayerClass;
%spawnDataBlock = $Game::DefaultPlayerDataBlock;
// Overrides by the %spawnPoint
if (isDefined("%spawnPoint.spawnClass"))
{
%spawnClass = %spawnPoint.spawnClass;
%spawnDataBlock = %spawnPoint.spawnDatablock;
}
else if (isDefined("%spawnPoint.spawnDatablock"))
{
// This may seem redundant given the above but it allows
// the SpawnSphere to override the datablock without
// overriding the default player class
%spawnDataBlock = %spawnPoint.spawnDatablock;
}
%spawnProperties = %spawnPoint.spawnProperties;
%spawnScript = %spawnPoint.spawnScript;
// Spawn with the engine's Sim::spawnObject() function
%player = spawnObject(%spawnClass, %spawnDatablock, "",
%spawnProperties, %spawnScript);
// If we have an object do some initial setup
if (isObject(%player))
{
// Pick a location within the spawn sphere.
%spawnLocation = %game.pickPointInSpawnSphere(%player, %spawnPoint);
%player.setTransform(%spawnLocation);
}
else
{
// If we weren't able to create the player object then warn the user
// When the player clicks OK in one of these message boxes, we will fall through
// to the "if (!isObject(%player))" check below.
if (isDefined("%spawnDatablock"))
{
MessageBoxOK("Spawn Player Failed",
"Unable to create a player with class " @ %spawnClass @
" and datablock " @ %spawnDatablock @ ".\n\nStarting as an Observer instead.",
"");
}
else
{
MessageBoxOK("Spawn Player Failed",
"Unable to create a player with class " @ %spawnClass @
".\n\nStarting as an Observer instead.",
"");
}
}
}
else
{
// Create a default player
%player = spawnObject($Game::DefaultPlayerClass, $Game::DefaultPlayerDataBlock);
if (!%player.isMemberOfClass("Player"))
warn("Trying to spawn a class that does not derive from Player.");
// Treat %spawnPoint as a transform
%player.setTransform(%spawnPoint);
}
// If we didn't actually create a player object then bail
if (!isObject(%player))
{
// Make sure we at least have a camera
%client.spawnCamera(%spawnPoint);
return;
}
// Update the default camera to start with the player
if (isObject(%client.camera) && !isDefined("%noControl"))
{
if (%player.getClassname() $= "Player")
%client.camera.setTransform(%player.getEyeTransform());
else
%client.camera.setTransform(%player.getTransform());
}
// Add the player object to MissionCleanup so that it
// won't get saved into the level files and will get
// cleaned up properly
MissionCleanup.add(%player);
// Store the client object on the player object for
// future reference
%player.client = %client;
// If the player's client has some owned turrets, make sure we let them
// know that we're a friend too.
if (%client.ownedTurrets)
{
for (%i=0; %i<%client.ownedTurrets.getCount(); %i++)
{
%turret = %client.ownedTurrets.getObject(%i);
%turret.addToIgnoreList(%player);
}
}
// Player setup...
if (%player.isMethod("setShapeName"))
%player.setShapeName(%client.playerName);
if (%player.isMethod("setEnergyLevel"))
%player.setEnergyLevel(%player.getDataBlock().maxEnergy);
if (!isDefined("%client.skin"))
{
// Determine which character skins are not already in use
%availableSkins = %player.getDatablock().availableSkins; // TAB delimited list of skin names
%count = ClientGroup.getCount();
for (%cl = 0; %cl < %count; %cl++)
{
%other = ClientGroup.getObject(%cl);
if (%other != %client)
{
%availableSkins = strreplace(%availableSkins, %other.skin, "");
%availableSkins = strreplace(%availableSkins, "\t\t", ""); // remove empty fields
}
}
// Choose a random, unique skin for this client
%count = getFieldCount(%availableSkins);
%client.skin = addTaggedString( getField(%availableSkins, getRandom(%count)) );
}
%player.setSkinName(%client.skin);
// Give the client control of the player
%client.player = %player;
// Give the client control of the camera if in the editor
if( $startWorldEditor )
{
%control = %client.camera;
%control.mode = "Fly";
EditorGui.syncCameraGui();
}
else
%control = %player;
// Allow the player/camera to receive move data from the GameConnection. Without this
// the user is unable to control the player/camera.
if (!isDefined("%noControl"))
%client.setControlObject(%control);
}
function DeathMatchGame::pickPointInSpawnSphere(%this, %objectToSpawn, %spawnSphere)
{
%SpawnLocationFound = false;
%attemptsToSpawn = 0;
while(!%SpawnLocationFound && (%attemptsToSpawn < 5))
{
%sphereLocation = %spawnSphere.getTransform();
// Attempt to spawn the player within the bounds of the spawnsphere.
%angleY = mDegToRad(getRandom(0, 100) * m2Pi());
%angleXZ = mDegToRad(getRandom(0, 100) * m2Pi());
%sphereLocation = setWord( %sphereLocation, 0, getWord(%sphereLocation, 0) + (mCos(%angleY) * mSin(%angleXZ) * getRandom(-%spawnSphere.radius, %spawnSphere.radius)));
%sphereLocation = setWord( %sphereLocation, 1, getWord(%sphereLocation, 1) + (mCos(%angleXZ) * getRandom(-%spawnSphere.radius, %spawnSphere.radius)));
%SpawnLocationFound = true;
// Now have to check that another object doesn't already exist at this spot.
// Use the bounding box of the object to check if where we are about to spawn in is
// clear.
%boundingBoxSize = %objectToSpawn.getDatablock().boundingBox;
%searchRadius = getWord(%boundingBoxSize, 0);
%boxSizeY = getWord(%boundingBoxSize, 1);
// Use the larger dimention as the radius to search
if (%boxSizeY > %searchRadius)
%searchRadius = %boxSizeY;
// Search a radius about the area we're about to spawn for players.
initContainerRadiusSearch( %sphereLocation, %searchRadius, $TypeMasks::PlayerObjectType );
while ( (%objectNearExit = containerSearchNext()) != 0 )
{
// If any player is found within this radius, mark that we need to look
// for another spot.
%SpawnLocationFound = false;
break;
}
// If the attempt at finding a clear spawn location failed
// try no more than 5 times.
%attemptsToSpawn++;
}
// If we couldn't find a spawn location after 5 tries, spawn the object
// At the center of the sphere and give a warning.
if (!%SpawnLocationFound)
{
%sphereLocation = %spawnSphere.getTransform();
warn("WARNING: Could not spawn player after" SPC %attemptsToSpawn
SPC "tries in spawnsphere" SPC %spawnSphere SPC "without overlapping another player. Attempting spawn in center of sphere.");
}
return %sphereLocation;
}
// ----------------------------------------------------------------------------
// Observer
// ----------------------------------------------------------------------------
function DeathMatchGame::spawnObserver(%game, %client)
{
//echo (%game @"\c4 -> "@ %game.class @" -> GameCore::spawnObserver");
// Position the camera on one of our observer spawn points
%client.camera.setTransform(%game.pickObserverSpawnPoint());
// Set control to the camera
%client.setControlObject(%client.camera);
}
function DeathMatchGame::pickObserverSpawnPoint(%game)
{
//echo (%game @"\c4 -> "@ %game.class @" -> GameCore::pickObserverSpawnPoint");
%groupName = "MissionGroup/ObserverSpawnPoints";
%group = nameToID(%groupName);
if (%group != -1)
{
%count = %group.getCount();
if (%count != 0)
{
%index = getRandom(%count-1);
%spawn = %group.getObject(%index);
return %spawn.getTransform();
}
else
error("No spawn points found in "@ %groupName);
}
else
error("Missing spawn points group "@ %groupName);
// Could be no spawn points, in which case we'll stick the
// player at the center of the world.
return "0 0 300 1 0 0 0";
}
// ----------------------------------------------------------------------------
// Server
// ----------------------------------------------------------------------------
// Called by GameCore::cycleGame() when we need to destroy the server
// because we're done playing. We don't want to call destroyServer()
// directly so we can first check that we're about to destroy the
// correct server session.
function DeathMatchGame::DestroyServer(%serverSession)
{
if (%serverSession == $Server::Session)
{
if (isObject(LocalClientConnection))
{
// We're a local connection so issue a disconnect. The server will
// be automatically destroyed for us.
disconnect();
}
else
{
// We're a stand alone server
destroyServer();
}
}
}
// ----------------------------------------------------------------------------
// weapon HUD
// ----------------------------------------------------------------------------
function GameConnection::setAmmoAmountHud(%client, %amount, %amountInClips )
{
commandToClient(%client, 'SetAmmoAmountHud', %amount, %amountInClips);
}
function GameConnection::RefreshWeaponHud(%client, %amount, %preview, %ret, %zoomRet, %amountInClips)
{
commandToClient(%client, 'RefreshWeaponHud', %amount, %preview, %ret, %zoomRet, %amountInClips);
}

View file

@ -0,0 +1,74 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// Inventory items. These objects rely on the item & inventory support
// system defined in item.cs and inventory.cs
//-----------------------------------------------------------------------------
// Health Patches cannot be picked up and are not meant to be added to inventory.
// Health is applied automatically when an objects collides with a patch.
//-----------------------------------------------------------------------------
function HealthPatch::onCollision(%this, %obj, %col)
{
// Apply health to colliding object if it needs it.
// Works for all shapebase objects.
if (%col.getDamageLevel() != 0 && %col.getState() !$= "Dead")
{
%col.applyRepair(%this.repairAmount);
%obj.respawn();
if (%col.client)
messageClient(%col.client, 'MsgHealthPatchUsed', '\c2Health Patch Applied');
serverPlay3D(HealthUseSound, %obj.getTransform());
}
}
function ShapeBase::tossPatch(%this)
{
//error("ShapeBase::tossPatch(" SPC %this.client.nameBase SPC ")");
if(!isObject(%this))
return;
%item = ItemData::createItem(HealthKitPatch);
%item.sourceObject = %this;
%item.static = false;
MissionCleanup.add(%item);
%vec = (-1.0 + getRandom() * 2.0) SPC (-1.0 + getRandom() * 2.0) SPC getRandom();
%vec = vectorScale(%vec, 10);
%eye = %this.getEyeVector();
%dot = vectorDot("0 0 1", %eye);
if (%dot < 0)
%dot = -%dot;
%vec = vectorAdd(%vec, vectorScale("0 0 8", 1 - %dot));
%vec = vectorAdd(%vec, %this.getVelocity());
%pos = getBoxCenter(%this.getWorldBox());
%item.setTransform(%pos);
%item.applyImpulse(%pos, %vec);
%item.setCollisionTimeout(%this);
//serverPlay3D(%item.getDataBlock().throwSound, %item.getTransform());
%item.schedulePop();
return %item;
}

View file

@ -0,0 +1,312 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// This inventory system is totally scripted, no C++ code involved.
// It uses object datablock names to track inventory and is generally
// object type, or class, agnostic. In other words, it will inventory
// any kind of ShapeBase object, though the throw method does assume
// that the objects are small enough to throw :)
//
// For a ShapeBase object to support inventory, it must have an array
// of inventory max values:
// %this.maxInv[GunAmmo] = 100;
// %this.maxInv[SpeedGun] = 1;
// where the names "SpeedGun" and "GunAmmo" are datablocks.
//
// For objects to be inventoriable, they must provide a set of inventory
// callback methods, mainly:
// onUse
// onThrow
// onPickup
//
// Example methods are given further down. The item.cs file also contains
// example inventory items.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Inventory server commands
//-----------------------------------------------------------------------------
function serverCmdUse(%client, %data)
{
%client.getControlObject().use(%data);
}
//-----------------------------------------------------------------------------
// ShapeBase inventory support
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
function ShapeBase::use(%this, %data)
{
// Use an object in the inventory.
// Need to prevent weapon changing when zooming, but only shapes
// that have a connection.
%conn = %this.getControllingClient();
if (%conn)
{
%defaultFov = %conn.getControlCameraDefaultFov();
%fov = %conn.getControlCameraFov();
if (%fov != %defaultFov)
return false;
}
if (%this.getInventory(%data) > 0)
return %data.onUse(%this);
return false;
}
function ShapeBase::throw(%this, %data, %amount)
{
// Throw objects from inventory. The onThrow method is
// responsible for decrementing the inventory.
if (%this.getInventory(%data) > 0)
{
%obj = %data.onThrow(%this, %amount);
if (%obj)
{
%this.throwObject(%obj);
serverPlay3D(ThrowSnd, %this.getTransform());
return true;
}
}
return false;
}
function ShapeBase::pickup(%this, %obj, %amount)
{
// This method is called to pickup an object and add it to the inventory.
// The datablock onPickup method is actually responsible for doing all the
// work, including incrementing the inventory.
%data = %obj.getDatablock();
// Try and pickup the max if no value was specified
if (%amount $= "")
%amount = %this.maxInventory(%data) - %this.getInventory(%data);
// The datablock does the work...
if (%amount < 0)
%amount = 0;
if (%amount)
return %data.onPickup(%obj, %this, %amount);
return false;
}
//-----------------------------------------------------------------------------
function ShapeBase::hasInventory(%this, %data)
{
return (%this.inv[%data] > 0);
}
function ShapeBase::hasAmmo(%this, %weapon)
{
if (%weapon.image.ammo $= "")
return(true);
else
return(%this.getInventory(%weapon.image.ammo) > 0);
}
function ShapeBase::maxInventory(%this, %data)
{
if (%data.isField("clip"))
{
// Use the clip system which uses the maxInventory
// field on the ammo itself.
return %data.maxInventory;
}
else
{
// Use the ammo pool system which uses the maxInv[]
// array on the object's datablock.
// If there is no limit defined, we assume 0
return %this.getDatablock().maxInv[%data.getName()];
}
}
function ShapeBase::incInventory(%this, %data, %amount)
{
// Increment the inventory by the given amount. The return value
// is the amount actually added, which may be less than the
// requested amount due to inventory restrictions.
%max = %this.maxInventory(%data);
%total = %this.inv[%data.getName()];
if (%total < %max)
{
if (%total + %amount > %max)
%amount = %max - %total;
%this.setInventory(%data, %total + %amount);
return %amount;
}
return 0;
}
function ShapeBase::decInventory(%this, %data, %amount)
{
// Decrement the inventory by the given amount. The return value
// is the amount actually removed.
%total = %this.inv[%data.getName()];
if (%total > 0)
{
if (%total < %amount)
%amount = %total;
%this.setInventory(%data, %total - %amount);
return %amount;
}
return 0;
}
//-----------------------------------------------------------------------------
function ShapeBase::getInventory(%this, %data)
{
// Return the current inventory amount
return %this.inv[%data.getName()];
}
function ShapeBase::setInventory(%this, %data, %value)
{
// Set the inventory amount for this datablock and invoke inventory
// callbacks. All changes to inventory go through this single method.
// Impose inventory limits
if (%value < 0)
%value = 0;
else
{
%max = %this.maxInventory(%data);
if (%value > %max)
%value = %max;
}
// Set the value and invoke object callbacks
%name = %data.getName();
if (%this.inv[%name] != %value)
{
%this.inv[%name] = %value;
%data.onInventory(%this, %value);
%this.getDataBlock().onInventory(%data, %value);
}
return %value;
}
//-----------------------------------------------------------------------------
function ShapeBase::clearInventory(%this)
{
// To be filled in...
}
//-----------------------------------------------------------------------------
function ShapeBase::throwObject(%this, %obj)
{
// Throw the given object in the direction the shape is looking.
// The force value is hardcoded according to the current default
// object mass and mission gravity (20m/s^2).
%throwForce = %this.getDataBlock().throwForce;
if (!%throwForce)
%throwForce = 20;
// Start with the shape's eye vector...
%eye = %this.getEyeVector();
%vec = vectorScale(%eye, %throwForce);
// Add a vertical component to give the object a better arc
%verticalForce = %throwForce / 2;
%dot = vectorDot("0 0 1", %eye);
if (%dot < 0)
%dot = -%dot;
%vec = vectorAdd(%vec, vectorScale("0 0 "@%verticalForce, 1 - %dot));
// Add the shape's velocity
%vec = vectorAdd(%vec, %this.getVelocity());
// Set the object's position and initial velocity
%pos = getBoxCenter(%this.getWorldBox());
%obj.setTransform(%pos);
%obj.applyImpulse(%pos, %vec);
// Since the object is thrown from the center of the shape,
// the object needs to avoid colliding with it's thrower.
%obj.setCollisionTimeout(%this);
}
//-----------------------------------------------------------------------------
// Callback hooks invoked by the inventory system
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// ShapeBase object callbacks invoked by the inventory system
function ShapeBase::onInventory(%this, %data, %value)
{
// Invoked on ShapeBase objects whenever their inventory changes
// for the given datablock.
}
//-----------------------------------------------------------------------------
// ShapeBase datablock callback invoked by the inventory system.
function ShapeBaseData::onUse(%this, %user)
{
// Invoked when the object uses this datablock, should return
// true if the item was used.
return false;
}
function ShapeBaseData::onThrow(%this, %user, %amount)
{
// Invoked when the object is thrown. This method should
// construct and return the actual mission object to be
// physically thrown. This method is also responsible for
// decrementing the user's inventory.
return 0;
}
function ShapeBaseData::onPickup(%this, %obj, %user, %amount)
{
// Invoked when the user attempts to pickup this datablock object.
// The %amount argument is the space in the user's inventory for
// this type of datablock. This method is responsible for
// incrementing the user's inventory is something is addded.
// Should return true if something was added to the inventory.
return false;
}
function ShapeBaseData::onInventory(%this, %user, %value)
{
// Invoked whenever an user's inventory total changes for
// this datablock.
}

View file

@ -0,0 +1,151 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// These scripts make use of dynamic attribute values on Item datablocks,
// these are as follows:
//
// maxInventory Max inventory per object (100 bullets per box, etc.)
// pickupName Name to display when client pickups item
//
// Item objects can have:
//
// count The # of inventory items in the object. This
// defaults to maxInventory if not set.
// Respawntime is the amount of time it takes for a static "auto-respawn"
// object, such as an ammo box or weapon, to re-appear after it's been
// picked up. Any item marked as "static" is automaticlly respawned.
$Item::RespawnTime = 30 * 1000;
// Poptime represents how long dynamic items (those that are thrown or
// dropped) will last in the world before being deleted.
$Item::PopTime = 30 * 1000;
//-----------------------------------------------------------------------------
// ItemData base class methods used by all items
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
function Item::respawn(%this)
{
// This method is used to respawn static ammo and weapon items
// and is usually called when the item is picked up.
// Instant fade...
%this.startFade(0, 0, true);
%this.setHidden(true);
// Shedule a reapearance
%this.schedule($Item::RespawnTime, "setHidden", false);
%this.schedule($Item::RespawnTime + 100, "startFade", 1000, 0, false);
}
function Item::schedulePop(%this)
{
// This method deletes the object after a default duration. Dynamic
// items such as thrown or drop weapons are usually popped to avoid
// world clutter.
%this.schedule($Item::PopTime - 1000, "startFade", 1000, 0, true);
%this.schedule($Item::PopTime, "delete");
}
//-----------------------------------------------------------------------------
// Callbacks to hook items into the inventory system
function ItemData::onThrow(%this, %user, %amount)
{
// Remove the object from the inventory
if (%amount $= "")
%amount = 1;
if (%this.maxInventory !$= "")
if (%amount > %this.maxInventory)
%amount = %this.maxInventory;
if (!%amount)
return 0;
%user.decInventory(%this,%amount);
// Construct the actual object in the world, and add it to
// the mission group so it's cleaned up when the mission is
// done. The object is given a random z rotation.
%obj = new Item()
{
datablock = %this;
rotation = "0 0 1 "@ (getRandom() * 360);
count = %amount;
};
MissionGroup.add(%obj);
%obj.schedulePop();
return %obj;
}
function ItemData::onPickup(%this, %obj, %user, %amount)
{
// Add it to the inventory, this currently ignores the request
// amount, you get what you get. If the object doesn't have
// a count or the datablock doesn't have maxIventory set, the
// object cannot be picked up.
// See if the object has a count
%count = %obj.count;
if (%count $= "")
{
// No, so check the datablock
%count = %this.count;
if (%count $= "")
{
// No, so attempt to provide the maximum amount
if (%this.maxInventory !$= "")
{
if (!(%count = %this.maxInventory))
return;
}
else
%count = 1;
}
}
%user.incInventory(%this, %count);
// Inform the client what they got.
if (%user.client)
messageClient(%user.client, 'MsgItemPickup', '\c0You picked up %1', %this.pickupName);
// If the item is a static respawn item, then go ahead and
// respawn it, otherwise remove it from the world.
// Anything not taken up by inventory is lost.
if (%obj.isStatic())
%obj.respawn();
else
%obj.delete();
return true;
}
function ItemData::createItem(%data)
{
%obj = new Item()
{
dataBlock = %data;
static = true;
rotate = true;
};
return %obj;
}

View file

@ -0,0 +1,467 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// Timeouts for corpse deletion.
$CorpseTimeoutValue = 45 * 1000;
//----------------------------------------------------------------------------
// Player Datablock methods
//----------------------------------------------------------------------------
function PlayerData::onAdd(%this, %obj)
{
// Vehicle timeout
%obj.mountVehicle = true;
// Default dynamic armor stats
%obj.setRechargeRate(%this.rechargeRate);
%obj.setRepairRate(0);
}
function PlayerData::onRemove(%this, %obj)
{
if (%obj.client.player == %obj)
%obj.client.player = 0;
}
function PlayerData::onNewDataBlock(%this, %obj)
{
}
//----------------------------------------------------------------------------
function PlayerData::onMount(%this, %obj, %vehicle, %node)
{
// Node 0 is the pilot's position, we need to dismount his weapon.
if (%node == 0)
{
%obj.setTransform("0 0 0 0 0 1 0");
%obj.setActionThread(%vehicle.getDatablock().mountPose[%node], true, true);
%obj.lastWeapon = %obj.getMountedImage($WeaponSlot);
%obj.unmountImage($WeaponSlot);
%obj.setControlObject(%vehicle);
if(%obj.getClassName() $= "Player")
commandToClient(%obj.client, 'toggleVehicleMap', true);
}
else
{
if (%vehicle.getDataBlock().mountPose[%node] !$= "")
%obj.setActionThread(%vehicle.getDatablock().mountPose[%node]);
else
%obj.setActionThread("root", true);
}
}
function PlayerData::onUnmount(%this, %obj, %vehicle, %node)
{
if (%node == 0)
{
%obj.mountImage(%obj.lastWeapon, $WeaponSlot);
%obj.setControlObject("");
}
}
function PlayerData::doDismount(%this, %obj, %forced)
{
//echo("\c4PlayerData::doDismount(" @ %this @", "@ %obj.client.nameBase @", "@ %forced @")");
// This function is called by player.cc when the jump trigger
// is true while mounted
%vehicle = %obj.mVehicle;
if (!%obj.isMounted() || !isObject(%vehicle))
return;
// Vehicle must be at rest!
if ((VectorLen(%vehicle.getVelocity()) <= %vehicle.getDataBlock().maxDismountSpeed ) || %forced)
{
// Position above dismount point
%pos = getWords(%obj.getTransform(), 0, 2);
%rot = getWords(%obj.getTransform(), 3, 6);
%oldPos = %pos;
%vec[0] = " -1 0 0";
%vec[1] = " 0 0 1";
%vec[2] = " 0 0 -1";
%vec[3] = " 1 0 0";
%vec[4] = "0 -1 0";
%impulseVec = "0 0 0";
%vec[0] = MatrixMulVector(%obj.getTransform(), %vec[0]);
// Make sure the point is valid
%pos = "0 0 0";
%numAttempts = 5;
%success = -1;
for (%i = 0; %i < %numAttempts; %i++)
{
%pos = VectorAdd(%oldPos, VectorScale(%vec[%i], 3));
if (%obj.checkDismountPoint(%oldPos, %pos))
{
%success = %i;
%impulseVec = %vec[%i];
break;
}
}
if (%forced && %success == -1)
%pos = %oldPos;
%obj.mountVehicle = false;
%obj.schedule(4000, "mountVehicles", true);
// Position above dismount point
%obj.unmount();
%obj.setTransform(%pos SPC %rot);//%obj.setTransform(%pos);
//%obj.playAudio(0, UnmountVehicleSound);
%obj.applyImpulse(%pos, VectorScale(%impulseVec, %obj.getDataBlock().mass));
// Set player velocity when ejecting
%vel = %obj.getVelocity();
%vec = vectorDot( %vel, vectorNormalize(%vel));
if(%vec > 50)
{
%scale = 50 / %vec;
%obj.setVelocity(VectorScale(%vel, %scale));
}
//%obj.vehicleTurret = "";
}
else
messageClient(%obj.client, 'msgUnmount', '\c2Cannot exit %1 while moving.', %vehicle.getDataBlock().nameTag);
}
//----------------------------------------------------------------------------
function PlayerData::onCollision(%this, %obj, %col)
{
if (!isObject(%col) || %obj.getState() $= "Dead")
return;
// Try and pickup all items
if (%col.getClassName() $= "Item")
{
%obj.pickup(%col);
return;
}
// Mount vehicles
if (%col.getType() & $TypeMasks::GameBaseObjectType)
{
%db = %col.getDataBlock();
if ((%db.getClassName() $= "WheeledVehicleData" ) && %obj.mountVehicle && %obj.getState() $= "Move" && %col.mountable)
{
// Only mount drivers for now.
ServerConnection.setFirstPerson(0);
// For this specific example, only one person can fit
// into a vehicle
%mount = %col.getMountNodeObject(0);
if(%mount)
return;
// For this specific FPS Example, always mount the player
// to node 0
%node = 0;
%col.mountObject(%obj, %node);
%obj.mVehicle = %col;
}
}
}
function PlayerData::onImpact(%this, %obj, %collidedObject, %vec, %vecLen)
{
%obj.damage(0, VectorAdd(%obj.getPosition(), %vec), %vecLen * %this.speedDamageScale, "Impact");
}
//----------------------------------------------------------------------------
function PlayerData::damage(%this, %obj, %sourceObject, %position, %damage, %damageType)
{
if (!isObject(%obj) || %obj.getState() $= "Dead" || !%damage)
return;
%obj.applyDamage(%damage);
%location = "Body";
// Deal with client callbacks here because we don't have this
// information in the onDamage or onDisable methods
%client = %obj.client;
%sourceClient = %sourceObject ? %sourceObject.client : 0;
if (isObject(%client))
{
// Determine damage direction
if (%damageType !$= "Suicide")
%obj.setDamageDirection(%sourceObject, %position);
if (%obj.getState() $= "Dead")
{
$Game.onDeath(%client, %sourceObject, %sourceClient, %damageType, %location);
}
}
}
function PlayerData::onDamage(%this, %obj, %delta)
{
// This method is invoked by the ShapeBase code whenever the
// object's damage level changes.
if (%delta > 0 && %obj.getState() !$= "Dead")
{
// Apply a damage flash
%obj.setDamageFlash(1);
// If the pain is excessive, let's hear about it.
if (%delta > 10)
%obj.playPain();
}
}
// ----------------------------------------------------------------------------
// The player object sets the "disabled" state when damage exceeds it's
// maxDamage value. This is method is invoked by ShapeBase state mangement code.
// If we want to deal with the damage information that actually caused this
// death, then we would have to move this code into the script "damage" method.
function PlayerData::onDisabled(%this, %obj, %state)
{
// Release the main weapon trigger
%obj.setImageTrigger(0, false);
// Toss current mounted weapon and ammo if any
%item = %obj.getMountedImage($WeaponSlot).item;
if (isObject(%item))
{
%amount = %obj.getInventory(%item.image.ammo);
if (!%item.image.clip)
warn("No clip exists to throw for item ", %item);
if(%amount)
%obj.throw(%item.image.clip, 1);
}
// Toss out a health patch
%obj.tossPatch();
%obj.playDeathCry();
%obj.playDeathAnimation();
//%obj.setDamageFlash(0.75);
// Disable any vehicle map
commandToClient(%obj.client, 'toggleVehicleMap', false);
// Schedule corpse removal. Just keeping the place clean.
%obj.schedule($CorpseTimeoutValue - 1000, "startFade", 1000, 0, true);
%obj.schedule($CorpseTimeoutValue, "delete");
}
//-----------------------------------------------------------------------------
function PlayerData::onLeaveMissionArea(%this, %obj)
{
//echo("\c4Leaving Mission Area at POS:"@ %obj.getPosition());
// Inform the client
%obj.client.onLeaveMissionArea();
// Damage over time and kill the coward!
//%obj.setDamageDt(0.2, "MissionAreaDamage");
}
function PlayerData::onEnterMissionArea(%this, %obj)
{
//echo("\c4Entering Mission Area at POS:"@ %obj.getPosition());
// Inform the client
%obj.client.onEnterMissionArea();
// Stop the punishment
//%obj.clearDamageDt();
}
//-----------------------------------------------------------------------------
function PlayerData::onEnterLiquid(%this, %obj, %coverage, %type)
{
//echo("\c4this:"@ %this @" object:"@ %obj @" just entered water of type:"@ %type @" for "@ %coverage @"coverage");
}
function PlayerData::onLeaveLiquid(%this, %obj, %type)
{
//
}
//-----------------------------------------------------------------------------
function PlayerData::onTrigger(%this, %obj, %triggerNum, %val)
{
// This method is invoked when the player receives a trigger move event.
// The player automatically triggers slot 0 and slot one off of triggers #
// 0 & 1. Trigger # 2 is also used as the jump key.
}
//-----------------------------------------------------------------------------
function PlayerData::onPoseChange(%this, %obj, %oldPose, %newPose)
{
// Set the script anim prefix to be that of the current pose
%obj.setImageScriptAnimPrefix( $WeaponSlot, addTaggedString(%newPose) );
}
//-----------------------------------------------------------------------------
function PlayerData::onStartSprintMotion(%this, %obj)
{
%obj.setImageGenericTrigger($WeaponSlot, 0, true);
}
function PlayerData::onStopSprintMotion(%this, %obj)
{
%obj.setImageGenericTrigger($WeaponSlot, 0, false);
}
//-----------------------------------------------------------------------------
// Player methods
//-----------------------------------------------------------------------------
//----------------------------------------------------------------------------
function Player::kill(%this, %damageType)
{
%this.damage(0, %this.getPosition(), 10000, %damageType);
}
//----------------------------------------------------------------------------
function Player::mountVehicles(%this, %bool)
{
// If set to false, this variable disables vehicle mounting.
%this.mountVehicle = %bool;
}
function Player::isPilot(%this)
{
%vehicle = %this.getObjectMount();
// There are two "if" statements to avoid a script warning.
if (%vehicle)
if (%vehicle.getMountNodeObject(0) == %this)
return true;
return false;
}
//----------------------------------------------------------------------------
function Player::playDeathAnimation(%this)
{
%numDeathAnimations = %this.getNumDeathAnimations();
if ( %numDeathAnimations > 0 )
{
if (isObject(%this.client))
{
if (%this.client.deathIdx++ > %numDeathAnimations)
%this.client.deathIdx = 1;
%this.setActionThread("Death" @ %this.client.deathIdx);
}
else
{
%rand = getRandom(1, %numDeathAnimations);
%this.setActionThread("Death" @ %rand);
}
}
}
function Player::playCelAnimation(%this, %anim)
{
if (%this.getState() !$= "Dead")
%this.setActionThread("cel"@%anim);
}
//----------------------------------------------------------------------------
function Player::playDeathCry(%this)
{
%this.playAudio(0, DeathCrySound);
}
function Player::playPain(%this)
{
%this.playAudio(0, PainCrySound);
}
// ----------------------------------------------------------------------------
function Player::setDamageDirection(%player, %sourceObject, %damagePos)
{
if (isObject(%sourceObject))
{
if (%sourceObject.isField(initialPosition))
{
// Projectiles have this field set to the muzzle point of
// the firing weapon at the time the projectile was created.
// This gives a damage direction towards the firing player,
// turret, vehicle, etc. Bullets and weapon fired grenades
// are examples of projectiles.
%damagePos = %sourceObject.initialPosition;
}
else
{
// Other objects that cause damage, such as mines, use their own
// location as the damage position. This gives a damage direction
// towards the explosive origin rather than the person that lay the
// explosives.
%damagePos = %sourceObject.getPosition();
}
}
// Rotate damage vector into object space
%damageVec = VectorSub(%damagePos, %player.getWorldBoxCenter());
%damageVec = VectorNormalize(%damageVec);
%damageVec = MatrixMulVector(%player.client.getCameraObject().getInverseTransform(), %damageVec);
// Determine largest component of damage vector to get direction
%vecComponents = -%damageVec.x SPC %damageVec.x SPC -%damageVec.y SPC %damageVec.y SPC -%damageVec.z SPC %damageVec.z;
%vecDirections = "Left" SPC "Right" SPC "Bottom" SPC "Front" SPC "Bottom" SPC "Top";
%max = -1;
for (%i = 0; %i < 6; %i++)
{
%value = getWord(%vecComponents, %i);
if (%value > %max)
{
%max = %value;
%damageDir = getWord(%vecDirections, %i);
}
}
commandToClient(%player.client, 'setDamageDirection', %damageDir);
}
function Player::use(%player, %data)
{
// No mounting/using weapons when you're driving!
if (%player.isPilot())
return(false);
Parent::use(%player, %data);
}

View file

@ -0,0 +1,46 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// "Universal" script methods for projectile damage handling. You can easily
// override these support functions with an equivalent namespace method if your
// weapon needs a unique solution for applying damage.
function ProjectileData::onCollision(%data, %proj, %col, %fade, %pos, %normal)
{
//echo("ProjectileData::onCollision("@%data.getName()@", "@%proj@", "@%col.getClassName()@", "@%fade@", "@%pos@", "@%normal@")");
// Apply damage to the object all shape base objects
if (%data.directDamage > 0)
{
if (%col.getType() & ($TypeMasks::ShapeBaseObjectType))
%col.damage(%proj, %pos, %data.directDamage, %data.damageType);
}
}
function ProjectileData::onExplode(%data, %proj, %position, %mod)
{
//echo("ProjectileData::onExplode("@%data.getName()@", "@%proj@", "@%position@", "@%mod@")");
// Damage objects within the projectiles damage radius
if (%data.damageRadius > 0)
radiusDamage(%proj, %position, %data.damageRadius, %data.radiusDamage, %data.damageType, %data.areaImpulse);
}

View file

@ -0,0 +1,118 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
function ProximityMineData::onThrow( %this, %user, %amount )
{
// Remove the object from the inventory
%user.decInventory( %this, 1 );
// Construct the actual object in the world, and add it to
// the mission group so its cleaned up when the mission is
// done. The object is given a random z rotation.
%obj = new ProximityMine()
{
datablock = %this;
sourceObject = %user;
rotation = "0 0 1 "@ (getRandom() * 360);
static = false;
client = %user.client;
};
MissionCleanup.add(%obj);
return %obj;
}
function ProximityMineData::onTriggered( %this, %obj, %target )
{
//echo(%this.name SPC "triggered by " @ %target.getClassName());
}
function ProximityMineData::onExplode( %this, %obj, %position )
{
// Damage objects within the mine's damage radius
if ( %this.damageRadius > 0 )
radiusDamage( %obj, %position, %this.damageRadius, %this.radiusDamage, %this.damageType, %this.areaImpulse );
}
function ProximityMineData::damage( %this, %obj, %position, %source, %amount, %damageType )
{
// Explode if any damage is applied to the mine
%obj.schedule(50 + getRandom(50), explode);
}
// Customized kill message for deaths caused by proximity mines
function sendMsgClientKilled_MineDamage( %msgType, %client, %sourceClient, %damLoc )
{
if ( %sourceClient $= "" ) // editor placed mine
messageAll( %msgType, '%1 was blown up!', %client.playerName );
else if ( %sourceClient == %client ) // own mine
messageAll( %msgType, '%1 stepped on his own mine!', %client.playerName );
else // enemy placed mine
messageAll( %msgType, '%1 was blown up by %2!', %client.playerName, %sourceClient.playerName );
}
// ----------------------------------------------------------------------------
// Player deployable proximity mine
// ----------------------------------------------------------------------------
// Cannot use the Weapon class for ProximityMineData datablocks as it is already tied
// to ItemData.
function ProxMine::onUse(%this, %obj)
{
// Act like a weapon on use
Weapon::onUse( %this, %obj );
}
function ProxMine::onPickup( %this, %obj, %shape, %amount )
{
// Act like a weapon on pickup
Weapon::onPickup( %this, %obj, %shape, %amount );
}
function ProxMine::onInventory( %this, %obj, %amount )
{
%obj.client.setAmmoAmountHud( 1, %amount );
// Cycle weapons if we are out of ammo
if ( !%amount && ( %slot = %obj.getMountSlot( %this.image ) ) != -1 )
%obj.cycleWeapon( "prev" );
}
function ProxMineImage::onMount( %this, %obj, %slot )
{
// The mine doesn't use ammo from a player's perspective.
%obj.setImageAmmo( %slot, true );
%numMines = %obj.getInventory(%this.item);
%obj.client.RefreshWeaponHud( 1, %this.item.previewImage, %this.item.reticle, %this.item.zoomReticle, %numMines );
}
function ProxMineImage::onUnmount( %this, %obj, %slot )
{
%obj.client.RefreshWeaponHud( 0, "", "" );
}
function ProxMineImage::onFire( %this, %obj, %slot )
{
// To fire a deployable mine is to throw it
%obj.throw( %this.item );
}

View file

@ -0,0 +1,73 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// Support function which applies damage to objects within the radius of
// some effect, usually an explosion. This function will also optionally
// apply an impulse to each object.
function radiusDamage(%sourceObject, %position, %radius, %damage, %damageType, %impulse)
{
// Use the container system to iterate through all the objects
// within our explosion radius. We'll apply damage to all ShapeBase
// objects.
InitContainerRadiusSearch(%position, %radius, $TypeMasks::ShapeBaseObjectType | $TypeMasks::DynamicShapeObjectType);
%halfRadius = %radius / 2;
while ((%targetObject = containerSearchNext()) != 0)
{
// Calculate how much exposure the current object has to
// the explosive force. The object types listed are objects
// that will block an explosion. If the object is totally blocked,
// then no damage is applied.
%coverage = calcExplosionCoverage(%position, %targetObject,
$TypeMasks::InteriorObjectType |
$TypeMasks::TerrainObjectType |
$TypeMasks::ForceFieldObjectType |
$TypeMasks::StaticShapeObjectType |
$TypeMasks::VehicleObjectType);
if (%coverage == 0)
continue;
// Radius distance subtracts out the length of smallest bounding
// box axis to return an appriximate distance to the edge of the
// object's bounds, as opposed to the distance to it's center.
%dist = containerSearchCurrRadiusDist();
// Calculate a distance scale for the damage and the impulse.
// Full damage is applied to anything less than half the radius away,
// linear scale from there.
%distScale = (%dist < %halfRadius)? 1.0 : 1.0 - ((%dist - %halfRadius) / %halfRadius);
%distScale = mClamp(%distScale,0.0,1.0);
// Apply the damage
%targetObject.damage(%sourceObject, %position, %damage * %coverage * %distScale, %damageType);
// Apply the impulse
if (%impulse)
{
%impulseVec = VectorSub(%targetObject.getWorldBoxCenter(), %position);
%impulseVec = VectorNormalize(%impulseVec);
%impulseVec = VectorScale(%impulseVec, %impulse * %distScale);
%targetObject.applyImpulse(%position, %impulseVec);
}
}
}

View file

@ -0,0 +1,121 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// This file contains ShapeBase methods used by all the derived classes
//-----------------------------------------------------------------------------
// ShapeBase object
//-----------------------------------------------------------------------------
// A raycast helper function to keep from having to duplicate code everytime
// that a raycast is needed.
// %this = the object doing the cast, usually a player
// %range = range to search
// %mask = what to look for
function ShapeBase::doRaycast(%this, %range, %mask)
{
// get the eye vector and eye transform of the player
%eyeVec = %this.getEyeVector();
%eyeTrans = %this.getEyeTransform();
// extract the position of the player's camera from the eye transform (first 3 words)
%eyePos = getWord(%eyeTrans, 0) SPC getWord(%eyeTrans, 1) SPC getWord(%eyeTrans, 2);
// normalize the eye vector
%nEyeVec = VectorNormalize(%eyeVec);
// scale (lengthen) the normalized eye vector according to the search range
%scEyeVec = VectorScale(%nEyeVec, %range);
// add the scaled & normalized eye vector to the position of the camera
%eyeEnd = VectorAdd(%eyePos, %scEyeVec);
// see if anything gets hit
%searchResult = containerRayCast(%eyePos, %eyeEnd, %mask, %this);
return %searchResult;
}
//-----------------------------------------------------------------------------
function ShapeBase::damage(%this, %sourceObject, %position, %damage, %damageType)
{
// All damage applied by one object to another should go through this method.
// This function is provided to allow objects some chance of overriding or
// processing damage values and types. As opposed to having weapons call
// ShapeBase::applyDamage directly. Damage is redirected to the datablock,
// this is standard procedure for many built in callbacks.
if (isObject(%this))
%this.getDataBlock().damage(%this, %sourceObject, %position, %damage, %damageType);
}
//-----------------------------------------------------------------------------
function ShapeBase::setDamageDt(%this, %damageAmount, %damageType)
{
// This function is used to apply damage over time. The damage is applied
// at a fixed rate (50 ms). Damage could be applied over time using the
// built in ShapBase C++ repair functions (using a neg. repair), but this
// has the advantage of going through the normal script channels.
if (%this.getState() !$= "Dead")
{
%this.damage(0, "0 0 0", %damageAmount, %damageType);
%this.damageSchedule = %this.schedule(50, "setDamageDt", %damageAmount, %damageType);
}
else
%this.damageSchedule = "";
}
function ShapeBase::clearDamageDt(%this)
{
if (%this.damageSchedule !$= "")
{
cancel(%this.damageSchedule);
%this.damageSchedule = "";
}
}
function GameBase::damage(%this, %sourceObject, %position, %damage, %damageType)
{
// All damage applied by one object to another should go through this method.
// This function is provided to allow objects some chance of overriding or
// processing damage values and types. As opposed to having weapons call
// ShapeBase::applyDamage directly. Damage is redirected to the datablock,
// this is standard procedure for many built in callbacks.
%datablock = %this.getDataBlock();
if ( isObject( %datablock ) )
%datablock.damage(%this, %sourceObject, %position, %damage, %damageType);
}
//-----------------------------------------------------------------------------
// ShapeBase datablock
//-----------------------------------------------------------------------------
function ShapeBaseData::damage(%this, %obj, %source, %position, %amount, %damageType)
{
// Ignore damage by default. This empty method is here to
// avoid console warnings.
}

View file

@ -0,0 +1,346 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// What kind of "player" is spawned is either controlled directly by the
// SpawnSphere or it defaults back to the values set here. This also controls
// which SimGroups to attempt to select the spawn sphere's from by walking down
// the list of SpawnGroups till it finds a valid spawn object.
//-----------------------------------------------------------------------------
// Leave $Game::defaultPlayerClass and $Game::defaultPlayerDataBlock as empty strings ("")
// to spawn a the $Game::defaultCameraClass as the control object.
$Game::DefaultPlayerClass = "Player";
$Game::DefaultPlayerDataBlock = "DefaultPlayerData";
$Game::DefaultPlayerSpawnGroups = "PlayerSpawnPoints";
//-----------------------------------------------------------------------------
// What kind of "camera" is spawned is either controlled directly by the
// SpawnSphere or it defaults back to the values set here. This also controls
// which SimGroups to attempt to select the spawn sphere's from by walking down
// the list of SpawnGroups till it finds a valid spawn object.
//-----------------------------------------------------------------------------
$Game::DefaultCameraClass = "Camera";
$Game::DefaultCameraDataBlock = "Observer";
$Game::DefaultCameraSpawnGroups = "CameraSpawnPoints PlayerSpawnPoints";
//-----------------------------------------------------------------------------
// pickCameraSpawnPoint() is responsible for finding a valid spawn point for a
// camera.
//-----------------------------------------------------------------------------
function pickCameraSpawnPoint(%spawnGroups)
{
// Walk through the groups until we find a valid object
for (%i = 0; %i < getWordCount(%spawnGroups); %i++)
{
%group = getWord(%spawnGroups, %i);
%count = getWordCount(%group);
if (isObject(%group))
%spawnPoint = %group.getRandom();
if (isObject(%spawnPoint))
return %spawnPoint;
}
// Didn't find a spawn point by looking for the groups
// so let's return the "default" SpawnSphere
// First create it if it doesn't already exist
if (!isObject(DefaultCameraSpawnSphere))
{
%spawn = new SpawnSphere(DefaultCameraSpawnSphere)
{
dataBlock = "SpawnSphereMarker";
spawnClass = $Game::DefaultCameraClass;
spawnDatablock = $Game::DefaultCameraDataBlock;
};
// Add it to the MissionCleanup group so that it
// doesn't get saved to the Mission (and gets cleaned
// up of course)
MissionCleanup.add(%spawn);
}
return DefaultCameraSpawnSphere;
}
//-----------------------------------------------------------------------------
// pickPlayerSpawnPoint() is responsible for finding a valid spawn point for a
// player.
//-----------------------------------------------------------------------------
function pickPlayerSpawnPoint(%spawnGroups)
{
// Walk through the groups until we find a valid object
for (%i = 0; %i < getWordCount(%spawnGroups); %i++)
{
%group = getWord(%spawnGroups, %i);
if (isObject(%group))
%spawnPoint = %group.getRandom();
if (isObject(%spawnPoint))
return %spawnPoint;
}
// Didn't find a spawn point by looking for the groups
// so let's return the "default" SpawnSphere
// First create it if it doesn't already exist
if (!isObject(DefaultPlayerSpawnSphere))
{
%spawn = new SpawnSphere(DefaultPlayerSpawnSphere)
{
dataBlock = "SpawnSphereMarker";
spawnClass = $Game::DefaultPlayerClass;
spawnDatablock = $Game::DefaultPlayerDataBlock;
};
// Add it to the MissionCleanup group so that it
// doesn't get saved to the Mission (and gets cleaned
// up of course)
MissionCleanup.add(%spawn);
}
return DefaultPlayerSpawnSphere;
}
//-----------------------------------------------------------------------------
// GameConnection::spawnCamera() is responsible for spawning a camera for a
// client
//-----------------------------------------------------------------------------
//function GameConnection::spawnCamera(%this, %spawnPoint)
//{
//// Set the control object to the default camera
//if (!isObject(%this.camera))
//{
//if (isDefined("$Game::DefaultCameraClass"))
//%this.camera = spawnObject($Game::DefaultCameraClass, $Game::DefaultCameraDataBlock);
//}
//
//if(!isObject(%this.PathCamera))
//{
//// Create path camera
//%this.PathCamera = spawnObject("PathCamera", "LoopingCam");
////%this.PathCamera = new PathCamera() {
////dataBlock = LoopingCam;
////position = "0 0 300 1 0 0 0";
////};
//}
//if(isObject(%this.PathCamera))
//{
//%this.PathCamera.setPosition("-54.0187 1.81237 5.14039");
//%this.PathCamera.followPath(MenuPath);
//MissionCleanup.add( %this.PathCamera);
//%this.PathCamera.scopeToClient(%this);
//%this.setControlObject(%this.PathCamera);
//}
//// If we have a camera then set up some properties
//if (isObject(%this.camera))
//{
//MissionCleanup.add( %this.camera );
//%this.camera.scopeToClient(%this);
//
////%this.setControlObject(%this.camera);
////%this.setControlObject(%this.PathCamera);
//
//if (isDefined("%spawnPoint"))
//{
//// Attempt to treat %spawnPoint as an object
//if (getWordCount(%spawnPoint) == 1 && isObject(%spawnPoint))
//{
//%this.camera.setTransform(%spawnPoint.getTransform());
//}
//else
//{
//// Treat %spawnPoint as an AxisAngle transform
//%this.camera.setTransform(%spawnPoint);
//}
//}
//}
//}
function GameConnection::spawnCamera(%this, %spawnPoint)
{
// Set the control object to the default camera
if (!isObject(%this.camera))
{
if (isDefined("$Game::DefaultCameraClass"))
%this.camera = spawnObject($Game::DefaultCameraClass, $Game::DefaultCameraDataBlock);
}
// If we have a camera then set up some properties
if (isObject(%this.camera))
{
MissionCleanup.add( %this.camera );
%this.camera.scopeToClient(%this);
%this.setControlObject(%this.camera);
if (isDefined("%spawnPoint"))
{
// Attempt to treat %spawnPoint as an object
if (getWordCount(%spawnPoint) == 1 && isObject(%spawnPoint))
{
%this.camera.setTransform(%spawnPoint.getTransform());
}
else
{
// Treat %spawnPoint as an AxisAngle transform
%this.camera.setTransform(%spawnPoint);
}
}
}
}
//-----------------------------------------------------------------------------
// GameConnection::spawnPlayer() is responsible for spawning a player for a
// client
//-----------------------------------------------------------------------------
function GameConnection::spawnPlayer(%this, %spawnPoint, %noControl)
{
if (isObject(%this.player))
{
// The client should not already have a player. Assigning
// a new one could result in an uncontrolled player object.
error("Attempting to create a player for a client that already has one!");
}
// Attempt to treat %spawnPoint as an object
if (getWordCount(%spawnPoint) == 1 && isObject(%spawnPoint))
{
// Defaults
%spawnClass = $Game::DefaultPlayerClass;
%spawnDataBlock = $Game::DefaultPlayerDataBlock;
// Overrides by the %spawnPoint
if (isDefined("%spawnPoint.spawnClass"))
{
%spawnClass = %spawnPoint.spawnClass;
%spawnDataBlock = %spawnPoint.spawnDatablock;
}
// This may seem redundant given the above but it allows
// the SpawnSphere to override the datablock without
// overriding the default player class
if (isDefined("%spawnPoint.spawnDatablock"))
%spawnDataBlock = %spawnPoint.spawnDatablock;
%spawnProperties = %spawnPoint.spawnProperties;
%spawnScript = %spawnPoint.spawnScript;
// Spawn with the engine's Sim::spawnObject() function
%player = spawnObject(%spawnClass, %spawnDatablock, "",
%spawnProperties, %spawnScript);
// If we have an object do some initial setup
if (isObject(%player))
{
// Set the transform to %spawnPoint's transform
%player.setTransform(%spawnPoint.getTransform());
}
else
{
// If we weren't able to create the player object then warn the user
if (isDefined("%spawnDatablock"))
{
MessageBoxOK("Spawn Player Failed",
"Unable to create a player with class " @ %spawnClass @
" and datablock " @ %spawnDatablock @ ".\n\nStarting as an Observer instead.",
%this @ ".spawnCamera();");
}
else
{
MessageBoxOK("Spawn Player Failed",
"Unable to create a player with class " @ %spawnClass @
".\n\nStarting as an Observer instead.",
%this @ ".spawnCamera();");
}
}
}
else
{
// Create a default player
%player = spawnObject($Game::DefaultPlayerClass, $Game::DefaultPlayerDataBlock);
if (!%player.isMemberOfClass("Player"))
warn("Trying to spawn a class that does not derive from Player.");
//Ensure we have a valid spawn point
if(%spawnPoint $= "")
{
%spawnPoint = pickPlayerSpawnPoint($Game::DefaultPlayerSpawnGroups).getTransform();
}
// Treat %spawnPoint as a transform
%player.setTransform(%spawnPoint);
}
// If we didn't actually create a player object then bail
if (!isObject(%player))
{
// Make sure we at least have a camera
%this.spawnCamera(%spawnPoint);
return;
}
// Update the default camera to start with the player
if (isObject(%this.camera))
{
if (%player.getClassname() $= "Player")
%this.camera.setTransform(%player.getEyeTransform());
else
%this.camera.setTransform(%player.getTransform());
}
// Add the player object to MissionCleanup so that it
// won't get saved into the level files and will get
// cleaned up properly
MissionCleanup.add(%player);
// Store the client object on the player object for
// future reference
%player.client = %this;
// Player setup...
if (%player.isMethod("setShapeName"))
%player.setShapeName(%this.playerName);
if (%player.isMethod("setEnergyLevel"))
%player.setEnergyLevel(%player.getDataBlock().maxEnergy);
// Give the client control of the player
%this.player = %player;
// Give the client control of the camera if in the editor
if( $startWorldEditor )
{
%control = %this.camera;
%control.mode = toggleCameraFly;
EditorGui.syncCameraGui();
}
else
%control = %player;
if(!isDefined("%noControl"))
%this.setControlObject(%control);
}

View file

@ -0,0 +1,251 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Trigger-derrived teleporter object. Teleports an object from it's entrance to
// it's exit if one is defined.
function TeleporterTrigger::onAdd( %this, %teleporter )
{
// Setup default parameters.
if ( %teleporter.exit $= "" )
%teleporter.exit = "NameOfTeleporterExit";
if ( %teleporter.teleporterCooldown $= "" )
%teleporter.teleporterCooldown = %this.teleporterCooldown;
if ( %teleporter.exitVelocityScale $= "" )
%teleporter.exitVelocityScale = %this.exitVelocityScale;
if ( %teleporter.reorientPlayer $= "" )
%teleporter.reorientPlayer = %this.reorientPlayer;
if ( %teleporter.oneSided $= "" )
%teleporter.oneSided = %this.oneSided;
if ( %teleporter.entranceEffect $= "" )
%teleporter.entranceEffect = %this.entranceEffect;
if ( %teleporter.exitEffect $= "" )
%teleporter.exitEffect = %this.exitEffect;
// We do not want to save this variable between levels,
// clear it out every time the teleporter is added
// to the scene.
%teleporter.timeOfLastTeleport = "";
}
function TeleporterTrigger::onLeaveTrigger(%this,%trigger,%obj)
{
// This is called after onEnterTrigger for BOTH
// The teleporter's entrance and exit
%obj.isTeleporting = false;
}
//ARGS:
// %this - The teleporter datablock.
// %entrance - The teleporter the player has entered (The one calling this function).
// %obj - The object that entered the teleporter.
function TeleporterTrigger::onEnterTrigger(%this, %entrance, %obj)
{
// Get the location of our target position
%exit = nameToID(%entrance.exit);
// Check if the the teleport is valid.
%valid = %this.verifyObject(%obj, %entrance, %exit);
// Bail out early if we cannot complete this teleportation
if (!%valid)
return;
// Kill any players in the exit teleporter.
%this.telefrag(%obj, %exit);
// Create our entrance effects on all clients.
if (isObject(%entrance.entranceEffect))
{
for(%idx = 0; %idx < ClientGroup.getCount(); %idx++)
commandToClient(ClientGroup.getObject(%idx), 'PlayTeleportEffect', %entrance.position, %entrance.entranceEffect.getId());
}
// Teleport the player to the exit teleporter.
%this.teleportPlayer(%obj, %exit);
// Create our exit effects on all clients.
if (isObject(%exit.exitEffect))
{
for(%idx = 0; %idx < ClientGroup.getCount(); %idx++)
commandToClient(ClientGroup.getObject(%idx), 'PlayTeleportEffect', %exit.position, %exit.exitEffect.getId());
}
// Record what time we last teleported so we can determine if enough
// time has elapsed to teleport again
%entrance.timeOfLastTeleport = getSimTime();
// If this is a bidirectional teleporter, log it's exit too.
if (%exit.exit $= %entrance.name)
%exit.timeOfLastTeleport = %entrance.timeOfLastTeleport;
// Tell the client to play the 2D sound for the player that teleported.
if (isObject(%this.teleportSound) && isObject(%obj.client))
%obj.client.play2D(%this.teleportSound);
}
// Here we verify that the teleport is valid.
// Tests go here like if the object is of a 'teleportable' type, if the
// given teleporter has an exit defined, etc.
function TeleporterTrigger::verifyObject(%this, %obj, %entrance, %exit)
{
// Bail out early if we couldn't find an exit for this teleporter.
if (!isObject(%exit))
{
logError("Cound not find an exit for " @ %entrance.name @ ".");
return false;
}
// If the entrance is once sided, make sure the object
// approached it from it's front.
if (%entrance.oneSided)
{
%dotProduct = VectorDot(%entrance.getForwardVector(), %obj.getVelocity());
if (%dotProduct > 0)
return false;
}
// If we are coming directly from another teleporter and it happens
// to be bidirectional, We need to avoid ending sending objects through
// an infinite loop.
if (%obj.isTeleporting)
return false;
// We only want to teleport players
// So bail out early if we have found any
// other object.
if (!%obj.isMemberOfClass("Player"))
return false;
if (%entrance.timeOfLastTeleport > 0 && %entrance.teleporterCooldown > 0)
{
// Get the current time, subtract it from the time it last teleported
// And compare the difference to see if enough time has elapsed to
// activate the teleporter again.
%currentTime = getSimTime();
%timeDifference = %currentTime - %entrance.timeOfLastTeleport;
%db = %entrance.getDatablock();
if (%timeDifference <= %db.teleporterCooldown)
return false;
}
return true;
}
// Function to teleport object %player to teleporter %exit.
function TeleporterTrigger::teleportPlayer(%this, %player, %exit)
{
// Teleport our player to the exit teleporter.
if (%exit.reorientPlayer)
%targetPosition = %exit.getTransform();
else
{
%pos = %exit.getPosition();
%rot = getWords(%player.getTransform(), 3, 6);
%targetPosition = %pos SPC %rot;
}
%player.setTransform(%targetPosition);
// Adjust the player's velocity by the Exit location's scale.
%player.setVelocity(vectorScale(%player.getVelocity(), %exit.exitVelocityScale));
// Prevent the object from doing an immediate second teleport
// In the case of a bidirectional teleporter
%player.isTeleporting = true;
}
// Telefrag is a term used in multiplayer gaming when a player takes a teleporter
// while another player is occupying it's exit. The player at the exit location
// is killed, allowing the original player to arrive at the teleporter.
function TeleporterTrigger::teleFrag(%this, %player, %exit)
{
// When a telefrag happens, there are two cases we have to consider.
// The first case occurs when the player's bounding box is much larger than the exit location,
// it is possible to have players colide even though a player is not within the bounds
// of the trigger Because of this we first check a radius the size of a player's bounding
// box around the exit location.
// Get the bounding box of the player
%boundingBoxSize = %player.getDatablock().boundingBox;
%radius = getWord(%boundingBoxSize, 0);
%boxSizeY = getWord(%boundingBoxSize, 1);
%boxSizeZ = getWord(%boundingBoxSize, 2);
// Use the largest dimention as the radius to check
if (%boxSizeY > %radius)
%radius = %boxSizeY;
if (%boxSizeZ > %radius)
%radius = %boxSizeZ;
%position = %exit.getPosition();
%mask = $TypeMasks::PlayerObjectType;
// Check all objects within the found radius of the exit location, and telefrag
// any players that meet the conditions.
initContainerRadiusSearch( %position, %radius, %mask );
while ( (%objectNearExit = containerSearchNext()) != 0 )
{
if (!%objectNearExit.isMemberOfClass("Player"))
continue;
// Avoid killing the player that is teleporting in the case of two
// Teleporters near eachother.
if (%objectNearExit == %player)
continue;
%objectNearExit.damage(%player, %exit.getTransform(), 10000, "Telefrag");
}
// The second case occurs when the bounds of the trigger are much larger
// than the bounding box of the player. (So multiple players can exist within the
// same trigger). For this case we check all objects contained within the trigger
// and telefrag all players.
%objectsInExit = %exit.getNumObjects();
// Loop through all objects in the teleporter exit
// And kill any players
for(%i = 0; %i < %objectsInExit; %i++)
{
%objectInTeleporter = %exit.getObject(%i);
if (!%objectInTeleporter.isMemberOfClass("Player"))
continue;
// Avoid killing the player that is teleporting in the case of two
// Teleporters near eachother.
if (%objectInTeleporter == %player)
continue;
%objectInTeleporter.damage(%player, %exit.getTransform(), 10000, "Telefrag");
}
}
// Customized kill message for telefrag deaths
function sendMsgClientKilled_Telefrag(%msgType, %client, %sourceClient, %damLoc)
{
messageAll(%msgType, '%1 was telefragged by %2!', %client.playerName, %sourceClient.playerName);
}

View file

@ -0,0 +1,48 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// DefaultTrigger is used by the mission editor. This is also an example
// of trigger methods and callbacks.
function DefaultTrigger::onEnterTrigger(%this,%trigger,%obj)
{
// This method is called whenever an object enters the %trigger
// area, the object is passed as %obj.
}
function DefaultTrigger::onLeaveTrigger(%this,%trigger,%obj)
{
// This method is called whenever an object leaves the %trigger
// area, the object is passed as %obj.
}
function DefaultTrigger::onTickTrigger(%this,%trigger)
{
// This method is called every tickPerioMS, as long as any
// objects intersect the trigger.
// You can iterate through the objects in the list by using these
// methods:
// %trigger.getNumObjects();
// %trigger.getObject(n);
}

View file

@ -0,0 +1,492 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// Respawntime is the amount of time it takes for a static "auto-respawn"
// turret to re-appear after it's been picked up. Any turret marked as "static"
// is automaticlly respawned.
$TurretShape::RespawnTime = 30 * 1000;
// DestroyedFadeDelay is the how long a destroyed turret sticks around before it
// fades out and is deleted.
$TurretShape::DestroyedFadeDelay = 5 * 1000;
// ----------------------------------------------------------------------------
// TurretShapeData
// ----------------------------------------------------------------------------
function TurretShapeData::onAdd(%this, %obj)
{
%obj.setRechargeRate(%this.rechargeRate);
%obj.setEnergyLevel(%this.MaxEnergy);
%obj.setRepairRate(0);
if (%obj.mountable || %obj.mountable $= "")
%this.isMountable(%obj, true);
else
%this.isMountable(%obj, false);
if (%this.nameTag !$= "")
%obj.setShapeName(%this.nameTag);
// Mount weapons
for(%i = 0; %i < %this.numWeaponMountPoints; %i++)
{
// Handle inventory
%obj.incInventory(%this.weapon[%i], 1);
%obj.incInventory(%this.weaponAmmo[%i], %this.weaponAmmoAmount[%i]);
// Mount the image
%obj.mountImage(%this.weapon[%i].image, %i, %this.startLoaded);
%obj.setImageGenericTrigger(%i, 0, false); // Used to indicate the turret is destroyed
}
if (%this.enterSequence !$= "")
{
%obj.entranceThread = 0;
%obj.playThread(%obj.entranceThread, %this.enterSequence);
%obj.pauseThread(%obj.entranceThread);
}
else
{
%obj.entranceThread = -1;
}
}
function TurretShapeData::onRemove(%this, %obj)
{
//echo("\c4TurretShapeData::onRemove("@ %this.getName() @", "@ %obj.getClassName() @")");
// if there are passengers/driver, kick them out
for(%i = 0; %i < %this.numMountPoints; %i++)
{
if (%obj.getMountNodeObject(%i))
{
%passenger = %obj.getMountNodeObject(%i);
%passenger.getDataBlock().doDismount(%passenger, true);
}
}
}
// This is on MissionGroup so it doesn't happen when the mission has ended
function MissionGroup::respawnTurret(%this, %datablock, %className, %transform, %static, %respawn)
{
%turret = new (%className)()
{
datablock = %datablock;
static = %static;
respawn = %respawn;
};
%turret.setTransform(%transform);
MissionGroup.add(%turret);
return %turret;
}
// ----------------------------------------------------------------------------
// TurretShapeData damage state
// ----------------------------------------------------------------------------
// This method is called by weapons fire
function TurretShapeData::damage(%this, %turret, %sourceObject, %position, %damage, %damageType)
{
//echo("\TurretShapeData::damage(" @ %turret @ ", "@ %sourceObject @ ", " @ %position @ ", "@ %damage @ ", "@ %damageType @ ")");
if (%turret.getState() $= "Dead")
return;
%turret.applyDamage(%damage);
// Update the numerical Health HUD
%mountedObject = %turret.getObjectMount();
if (%mountedObject)
%mountedObject.updateHealth();
// Kill any occupants
if (%turret.getState() $= "Dead")
{
for (%i = 0; %i < %this.numMountPoints; %i++)
{
%player = %turret.getMountNodeObject(%i);
if (%player != 0)
%player.killWithSource(%sourceObject, "InsideTurret");
}
}
}
function TurretShapeData::onDamage(%this, %obj, %delta)
{
// This method is invoked by the ShapeBase code whenever the
// object's damage level changes.
}
function TurretShapeData::onDestroyed(%this, %obj, %lastState)
{
// This method is invoked by the ShapeBase code whenever the
// object's damage state changes.
// Fade out the destroyed object. Then schedule a return.
%obj.startFade(1000, $TurretShape::DestroyedFadeDelay, true);
%obj.schedule($TurretShape::DestroyedFadeDelay + 1000, "delete");
if (%obj.doRespawn())
{
MissionGroup.schedule($TurretShape::RespawnTime, "respawnTurret", %this, %obj.getClassName(), %obj.getTransform(), true, true);
}
}
function TurretShapeData::onDisabled(%this, %obj, %lastState)
{
// This method is invoked by the ShapeBase code whenever the
// object's damage state changes.
}
function TurretShapeData::onEnabled(%this, %obj, %lastState)
{
// This method is invoked by the ShapeBase code whenever the
// object's damage state changes.
}
// ----------------------------------------------------------------------------
// TurretShapeData player mounting and dismounting
// ----------------------------------------------------------------------------
function TurretShapeData::isMountable(%this, %obj, %val)
{
%obj.mountable = %val;
}
function TurretShapeData::onMountObject(%this, %turret, %player, %node)
{
if (%turret.entranceThread >= 0)
{
%turret.setThreadDir(%turret.entranceThread, true);
%turret.setThreadPosition(%turret.entranceThread, 0);
%turret.playThread(%turret.entranceThread, "");
}
}
function TurretShapeData::onUnmountObject(%this, %turret, %player)
{
if (%turret.entranceThread >= 0)
{
// Play the entrance thread backwards for an exit
%turret.setThreadDir(%turret.entranceThread, false);
%turret.setThreadPosition(%turret.entranceThread, 1);
%turret.playThread(%turret.entranceThread, "");
}
}
function TurretShapeData::mountPlayer(%this, %turret, %player)
{
//echo("\c4TurretShapeData::mountPlayer("@ %this.getName() @", "@ %turret @", "@ %player.client.nameBase @")");
if (isObject(%turret) && %turret.getDamageState() !$= "Destroyed")
{
//%player.startFade(1000, 0, true);
//%this.schedule(1000, "setMountTurret", %turret, %player);
//%player.schedule(1500, "startFade", 1000, 0, false);
%this.setMountTurret(%turret, %player);
}
}
function TurretShapeData::setMountTurret(%this, %turret, %player)
{
//echo("\c4TurretShapeData::setMountTurret("@ %this.getName() @", "@ %turret @", "@ %player.client.nameBase @")");
if (isObject(%turret) && %turret.getDamageState() !$= "Destroyed")
{
%node = %this.findEmptySeat(%turret, %player);
if (%node >= 0)
{
//echo("\c4Mount Node: "@ %node);
%turret.mountObject(%player, %node);
//%player.playAudio(0, MountVehicleSound);
%player.mVehicle = %turret;
}
}
}
function TurretShapeData::findEmptySeat(%this, %turret, %player)
{
//echo("\c4This turret has "@ %this.numMountPoints @" mount points.");
for (%i = 0; %i < %this.numMountPoints; %i++)
{
%node = %turret.getMountNodeObject(%i);
if (%node == 0)
return %i;
}
return -1;
}
function TurretShapeData::switchSeats(%this, %turret, %player)
{
for (%i = 0; %i < %this.numMountPoints; %i++)
{
%node = %turret.getMountNodeObject(%i);
if (%node == %player || %node > 0)
continue;
if (%node == 0)
return %i;
}
return -1;
}
function TurretShapeData::onMount(%this, %turret, %player, %node)
{
//echo("\c4TurretShapeData::onMount("@ %this.getName() @", "@ %turret @", "@ %player.client.nameBase @")");
%player.client.RefreshVehicleHud(%turret, %this.reticle, %this.zoomReticle);
//%player.client.UpdateVehicleHealth(%turret);
}
function TurretShapeData::onUnmount(%this, %turret, %player, %node)
{
//echo("\c4TurretShapeData::onUnmount(" @ %this.getName() @ ", " @ %turret @ ", " @ %player.client.nameBase @ ")");
%player.client.RefreshVehicleHud(0, "", "");
}
// ----------------------------------------------------------------------------
// TurretShape damage
// ----------------------------------------------------------------------------
// This method is called by weapons fire
function TurretShape::damage(%this, %sourceObject, %position, %damage, %damageType)
{
//echo("\TurretShape::damage(" @ %this @ ", "@ %sourceObject @ ", " @ %position @ ", "@ %damage @ ", "@ %damageType @ ")");
%this.getDataBlock().damage(%this, %sourceObject, %position, %damage, %damageType);
}
// ----------------------------------------------------------------------------
// TurretDamage
// ----------------------------------------------------------------------------
// Customized kill message for deaths caused by turrets
function sendMsgClientKilled_TurretDamage( %msgType, %client, %sourceClient, %damLoc )
{
if ( %sourceClient $= "" ) // editor placed turret
messageAll( %msgType, '%1 was shot down by a turret!', %client.playerName );
else if ( %sourceClient == %client ) // own mine
messageAll( %msgType, '%1 kill by his own turret!', %client.playerName );
else // enemy placed mine
messageAll( %msgType, '%1 was killed by a turret of %2!', %client.playerName, %sourceClient.playerName );
}
// ----------------------------------------------------------------------------
// AITurretShapeData
// ----------------------------------------------------------------------------
function AITurretShapeData::onAdd(%this, %obj)
{
Parent::onAdd(%this, %obj);
%obj.mountable = false;
}
// Player has thrown a deployable turret. This copies from ItemData::onThrow()
function AITurretShapeData::onThrow(%this, %user, %amount)
{
// Remove the object from the inventory
if (%amount $= "")
%amount = 1;
if (%this.maxInventory !$= "")
if (%amount > %this.maxInventory)
%amount = %this.maxInventory;
if (!%amount)
return 0;
%user.decInventory(%this,%amount);
// Construct the actual object in the world, and add it to
// the mission group so it's cleaned up when the mission is
// done. The turret's rotation matches the player's.
%rot = %user.getEulerRotation();
%obj = new AITurretShape()
{
datablock = %this;
rotation = "0 0 1 " @ getWord(%rot, 2);
count = 1;
sourceObject = %user;
client = %user.client;
isAiControlled = true;
};
MissionGroup.add(%obj);
// Let the turret know that we're a firend
%obj.addToIgnoreList(%user);
// We need to add this turret to a list on the client so that if we die,
// the turret will still ignore our player.
%client = %user.client;
if (%client)
{
if (!%client.ownedTurrets)
{
%client.ownedTurrets = new SimSet();
}
// Go through the client's owned turret list. Make sure we're
// a friend of every turret and every turret is a friend of ours.
// Commence hugging!
for (%i=0; %i<%client.ownedTurrets.getCount(); %i++)
{
%turret = %client.ownedTurrets.getObject(%i);
%turret.addToIgnoreList(%obj);
%obj.addToIgnoreList(%turret);
}
// Add ourselves to the client's owned list.
%client.ownedTurrets.add(%obj);
}
return %obj;
}
function AITurretShapeData::onDestroyed(%this, %turret, %lastState)
{
// This method is invoked by the ShapeBase code whenever the
// object's damage state changes.
%turret.playAudio(0, TurretDestroyed);
%turret.setAllGunsFiring(false);
%turret.resetTarget();
%turret.setTurretState( "Destroyed", true );
// Set the weapons to destoryed
for(%i = 0; %i < %this.numWeaponMountPoints; %i++)
{
%turret.setImageGenericTrigger(%i, 0, true);
}
Parent::onDestroyed(%this, %turret, %lastState);
}
function AITurretShapeData::OnScanning(%this, %turret)
{
//echo("AITurretShapeData::OnScanning: " SPC %this SPC %turret);
%turret.startScanForTargets();
%turret.playAudio(0, TurretScanningSound);
}
function AITurretShapeData::OnTarget(%this, %turret)
{
//echo("AITurretShapeData::OnTarget: " SPC %this SPC %turret);
%turret.startTrackingTarget();
%turret.playAudio(0, TargetAquiredSound);
}
function AITurretShapeData::OnNoTarget(%this, %turret)
{
//echo("AITurretShapeData::OnNoTarget: " SPC %this SPC %turret);
%turret.setAllGunsFiring(false);
%turret.recenterTurret();
%turret.playAudio(0, TargetLostSound);
}
function AITurretShapeData::OnFiring(%this, %turret)
{
//echo("AITurretShapeData::OnFiring: " SPC %this SPC %turret);
%turret.setAllGunsFiring(true);
}
function AITurretShapeData::OnThrown(%this, %turret)
{
//echo("AITurretShapeData::OnThrown: " SPC %this SPC %turret);
%turret.playAudio(0, TurretThrown);
}
function AITurretShapeData::OnDeploy(%this, %turret)
{
//echo("AITurretShapeData::OnDeploy: " SPC %this SPC %turret);
// Set the weapons to loaded
for(%i = 0; %i < %this.numWeaponMountPoints; %i++)
{
%turret.setImageLoaded(%i, true);
}
%turret.playAudio(0, TurretActivatedSound);
}
// ----------------------------------------------------------------------------
// Player deployable turret
// ----------------------------------------------------------------------------
// Cannot use the Weapon class for deployable turrets as it is already tied
// to ItemData.
function DeployableTurretWeapon::onUse(%this, %obj)
{
Weapon::onUse(%this, %obj);
}
function DeployableTurretWeapon::onPickup(%this, %obj, %shape, %amount)
{
Weapon::onPickup(%this, %obj, %shape, %amount);
}
function DeployableTurretWeapon::onInventory(%this, %obj, %amount)
{
if (%obj.client !$= "" && !%obj.isAiControlled)
{
%obj.client.setAmmoAmountHud( 1, %amount );
}
// Cycle weapons if we are out of ammo
if ( !%amount && ( %slot = %obj.getMountSlot( %this.image ) ) != -1 )
%obj.cycleWeapon( "prev" );
}
function DeployableTurretWeaponImage::onMount(%this, %obj, %slot)
{
// The turret doesn't use ammo from a player's perspective.
%obj.setImageAmmo(%slot, true);
%numTurrets = %obj.getInventory(%this.item);
if (%obj.client !$= "" && !%obj.isAiControlled)
%obj.client.RefreshWeaponHud( 1, %this.item.previewImage, %this.item.reticle, %this.item.zoomReticle, %numTurrets);
}
function DeployableTurretWeaponImage::onUnmount(%this, %obj, %slot)
{
if (%obj.client !$= "" && !%obj.isAiControlled)
%obj.client.RefreshWeaponHud(0, "", "");
}
function DeployableTurretWeaponImage::onFire(%this, %obj, %slot)
{
//echo("\DeployableTurretWeaponImage::onFire( "@%this.getName()@", "@%obj.client.nameBase@", "@%slot@" )");
// To fire a deployable turret is to throw it. Schedule the throw
// so that it doesn't happen during this ShapeBaseImageData's state machine.
// If we throw the last one then we end up unmounting while the state machine
// is still being processed.
%obj.schedule(0, "throw", %this.item);
}

View file

@ -0,0 +1,130 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// Parenting is in place for WheeledVehicleData to VehicleData. This should
// make it easier for people to simply drop in new (generic) vehicles. All that
// the user needs to create is a set of datablocks for the new wheeled vehicle
// to use. This means that no (or little) scripting should be necessary.
// Special, or unique vehicles however will still require some scripting. They
// may need to override the onAdd() function in order to mount weapons,
// differing tires/springs, etc., almost everything else is taken care of in the
// WheeledVehicleData and VehicleData methods. This helps us by not having to
// duplicate the same code for every new vehicle.
// In theory this would work for HoverVehicles and FlyingVehicles also, but
// hasn't been tested or fully implemented for those classes -- yet.
function VehicleData::onAdd(%this, %obj)
{
%obj.setRechargeRate(%this.rechargeRate);
%obj.setEnergyLevel(%this.MaxEnergy);
%obj.setRepairRate(0);
if (%obj.mountable || %obj.mountable $= "")
%this.isMountable(%obj, true);
else
%this.isMountable(%obj, false);
if (%this.nameTag !$= "")
%obj.setShapeName(%this.nameTag);
}
function VehicleData::onRemove(%this, %obj)
{
//echo("\c4VehicleData::onRemove("@ %this.getName() @", "@ %obj.getClassName() @")");
// if there are passengers/driver, kick them out
for(%i = 0; %i < %obj.getDatablock().numMountPoints; %i++)
{
if (%obj.getMountNodeObject(%i))
{
%passenger = %obj.getMountNodeObject(%i);
%passenger.getDataBlock().doDismount(%passenger, true);
}
}
}
// ----------------------------------------------------------------------------
// Vehicle player mounting and dismounting
// ----------------------------------------------------------------------------
function VehicleData::isMountable(%this, %obj, %val)
{
%obj.mountable = %val;
}
function VehicleData::mountPlayer(%this, %vehicle, %player)
{
//echo("\c4VehicleData::mountPlayer("@ %this.getName() @", "@ %vehicle @", "@ %player.client.nameBase @")");
if (isObject(%vehicle) && %vehicle.getDamageState() !$= "Destroyed")
{
%player.startFade(1000, 0, true);
%this.schedule(1000, "setMountVehicle", %vehicle, %player);
%player.schedule(1500, "startFade", 1000, 0, false);
}
}
function VehicleData::setMountVehicle(%this, %vehicle, %player)
{
//echo("\c4VehicleData::setMountVehicle("@ %this.getName() @", "@ %vehicle @", "@ %player.client.nameBase @")");
if (isObject(%vehicle) && %vehicle.getDamageState() !$= "Destroyed")
{
%node = %this.findEmptySeat(%vehicle, %player);
if (%node >= 0)
{
//echo("\c4Mount Node: "@ %node);
%vehicle.mountObject(%player, %node);
//%player.playAudio(0, MountVehicleSound);
%player.mVehicle = %vehicle;
}
}
}
function VehicleData::findEmptySeat(%this, %vehicle, %player)
{
//echo("\c4This vehicle has "@ %this.numMountPoints @" mount points.");
for (%i = 0; %i < %this.numMountPoints; %i++)
{
%node = %vehicle.getMountNodeObject(%i);
if (%node == 0)
return %i;
}
return -1;
}
function VehicleData::switchSeats(%this, %vehicle, %player)
{
for (%i = 0; %i < %this.numMountPoints; %i++)
{
%node = %vehicle.getMountNodeObject(%i);
if (%node == %player || %node > 0)
continue;
if (%node == 0)
return %i;
}
return -1;
}

View file

@ -0,0 +1,102 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// This file contains script methods unique to the WheeledVehicle class. All
// other necessary methods are contained in "../server/scripts/vehicle.cs" in
// which the "generic" Vehicle class methods that are shared by all vehicles,
// (flying, hover, and wheeled) can be found.
// Parenting is in place for WheeledVehicleData to VehicleData. This should
// make it easier for people to simply drop in new (generic) vehicles. All that
// the user needs to create is a set of datablocks for the new wheeled vehicle
// to use. This means that no (or little) scripting should be necessary.
function WheeledVehicleData::onAdd(%this, %obj)
{
Parent::onAdd(%this, %obj);
// Setup the car with some tires & springs
for (%i = %obj.getWheelCount() - 1; %i >= 0; %i--)
{
%obj.setWheelTire(%i, DefaultCarTire);
%obj.setWheelSpring(%i, DefaultCarSpring);
%obj.setWheelPowered(%i, false);
}
// Steer with the front tires
%obj.setWheelSteering(0, 1);
%obj.setWheelSteering(1, 1);
// Only power the two rear wheels... assuming there are only 4 wheels.
%obj.setWheelPowered(2, true);
%obj.setWheelPowered(3, true);
}
function WheeledVehicleData::onCollision(%this, %obj, %col, %vec, %speed)
{
// Collision with other objects, including items
}
// Used to kick the players out of the car that your crosshair is over
function serverCmdcarUnmountObj(%client, %obj)
{
%obj.unmount();
%obj.setControlObject(%obj);
%ejectpos = %obj.getPosition();
%ejectpos = VectorAdd(%ejectpos, "0 0 5");
%obj.setTransform(%ejectpos);
%ejectvel = %obj.mVehicle.getVelocity();
%ejectvel = VectorAdd(%ejectvel, "0 0 10");
%ejectvel = VectorScale(%ejectvel, %obj.getDataBlock().mass);
%obj.applyImpulse(%ejectpos, %ejectvel);
}
// Used to flip the car over if it manages to get stuck upside down
function serverCmdflipCar(%client)
{
%car = %client.player.getControlObject();
if (%car.getClassName() $= "WheeledVehicle")
{
%carPos = %car.getPosition();
%carPos = VectorAdd(%carPos, "0 0 3");
%car.setTransform(%carPos SPC "0 0 1 0");
}
}
function serverCmdsetPlayerControl(%client)
{
%client.setControlObject(%client.player);
}
function serverCmddismountVehicle(%client)
{
%car = %client.player.getControlObject();
%passenger = %car.getMountNodeObject(0);
%passenger.getDataBlock().doDismount(%passenger, true);
%client.setControlObject(%client.player);
}

View file

@ -0,0 +1,643 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// This file contains Weapon and Ammo Class/"namespace" helper methods as well
// as hooks into the inventory system. These functions are not attached to a
// specific C++ class or datablock, but define a set of methods which are part
// of dynamic namespaces "class". The Items include these namespaces into their
// scope using the ItemData and ItemImageData "className" variable.
// ----------------------------------------------------------------------------
// All ShapeBase images are mounted into one of 8 slots on a shape. This weapon
// system assumes all primary weapons are mounted into this specified slot:
$WeaponSlot = 0;
//-----------------------------------------------------------------------------
// Weapon Class
//-----------------------------------------------------------------------------
function Weapon::onUse(%data, %obj)
{
// Default behavior for all weapons is to mount it into the object's weapon
// slot, which is currently assumed to be slot 0
if (%obj.getMountedImage($WeaponSlot) != %data.image.getId())
{
serverPlay3D(WeaponUseSound, %obj.getTransform());
%obj.mountImage(%data.image, $WeaponSlot);
if (%obj.client)
{
if (%data.description !$= "")
messageClient(%obj.client, 'MsgWeaponUsed', '\c0%1 selected.', %data.description);
else
messageClient(%obj.client, 'MsgWeaponUsed', '\c0Weapon selected');
}
// If this is a Player class object then allow the weapon to modify allowed poses
if (%obj.isInNamespaceHierarchy("Player"))
{
// Start by allowing everything
%obj.allowAllPoses();
// Now see what isn't allowed by the weapon
%image = %data.image;
if (%image.jumpingDisallowed)
%obj.allowJumping(false);
if (%image.jetJumpingDisallowed)
%obj.allowJetJumping(false);
if (%image.sprintDisallowed)
%obj.allowSprinting(false);
if (%image.crouchDisallowed)
%obj.allowCrouching(false);
if (%image.proneDisallowed)
%obj.allowProne(false);
if (%image.swimmingDisallowed)
%obj.allowSwimming(false);
}
}
}
function Weapon::onPickup(%this, %obj, %shape, %amount)
{
// The parent Item method performs the actual pickup.
// For player's we automatically use the weapon if the
// player does not already have one in hand.
if (Parent::onPickup(%this, %obj, %shape, %amount))
{
serverPlay3D(WeaponPickupSound, %shape.getTransform());
if (%shape.getClassName() $= "Player" && %shape.getMountedImage($WeaponSlot) == 0)
%shape.use(%this);
}
}
function Weapon::onInventory(%this, %obj, %amount)
{
// Weapon inventory has changed, make sure there are no weapons
// of this type mounted if there are none left in inventory.
if (!%amount && (%slot = %obj.getMountSlot(%this.image)) != -1)
%obj.unmountImage(%slot);
}
//-----------------------------------------------------------------------------
// Weapon Image Class
//-----------------------------------------------------------------------------
function WeaponImage::onMount(%this, %obj, %slot)
{
// Images assume a false ammo state on load. We need to
// set the state according to the current inventory.
if(%this.isField("clip"))
{
// Use the clip system for this weapon. Check if the player already has
// some ammo in a clip.
if (%obj.getInventory(%this.ammo))
{
%obj.setImageAmmo(%slot, true);
%currentAmmo = %obj.getInventory(%this.ammo);
}
else if(%obj.getInventory(%this.clip) > 0)
{
// Fill the weapon up from the first clip
%obj.setInventory(%this.ammo, %this.ammo.maxInventory);
%obj.setImageAmmo(%slot, true);
// Add any spare ammo that may be "in the player's pocket"
%currentAmmo = %this.ammo.maxInventory;
%amountInClips += %obj.getFieldValue( "remaining" @ %this.ammo.getName());
}
else
{
%currentAmmo = 0 + %obj.getFieldValue( "remaining" @ %this.ammo.getName());
}
%amountInClips = %obj.getInventory(%this.clip);
%amountInClips *= %this.ammo.maxInventory;
if (%obj.client !$= "" && !%obj.isAiControlled)
%obj.client.RefreshWeaponHud(%currentAmmo, %this.item.previewImage, %this.item.reticle, %this.item.zoomReticle, %amountInClips);
}
else if(%this.ammo !$= "")
{
// Use the ammo pool system for this weapon
if (%obj.getInventory(%this.ammo))
{
%obj.setImageAmmo(%slot, true);
%currentAmmo = %obj.getInventory(%this.ammo);
}
else
%currentAmmo = 0;
if (%obj.client !$= "" && !%obj.isAiControlled)
%obj.client.RefreshWeaponHud( 1, %this.item.previewImage, %this.item.reticle, %this.item.zoomReticle, %currentAmmo );
}
}
function WeaponImage::onUnmount(%this, %obj, %slot)
{
if (%obj.client !$= "" && !%obj.isAiControlled)
%obj.client.RefreshWeaponHud(0, "", "");
}
// ----------------------------------------------------------------------------
// A "generic" weaponimage onFire handler for most weapons. Can be overridden
// with an appropriate namespace method for any weapon that requires a custom
// firing solution.
// projectileSpread is a dynamic property declared in the weaponImage datablock
// for those weapons in which bullet skew is desired. Must be greater than 0,
// otherwise the projectile goes straight ahead as normal. lower values give
// greater accuracy, higher values increase the spread pattern.
// ----------------------------------------------------------------------------
function WeaponImage::onFire(%this, %obj, %slot)
{
//echo("\c4WeaponImage::onFire( "@%this.getName()@", "@%obj.client.nameBase@", "@%slot@" )");
// Make sure we have valid data
if (!isObject(%this.projectile))
{
error("WeaponImage::onFire() - Invalid projectile datablock");
return;
}
// Decrement inventory ammo. The image's ammo state is updated
// automatically by the ammo inventory hooks.
if ( !%this.infiniteAmmo )
%obj.decInventory(%this.ammo, 1);
// Get the player's velocity, we'll then add it to that of the projectile
%objectVelocity = %obj.getVelocity();
%numProjectiles = %this.projectileNum;
if (%numProjectiles == 0)
%numProjectiles = 1;
for (%i = 0; %i < %numProjectiles; %i++)
{
if (%this.projectileSpread)
{
// We'll need to "skew" this projectile a little bit. We start by
// getting the straight ahead aiming point of the gun
%vec = %obj.getMuzzleVector(%slot);
// Then we'll create a spread matrix by randomly generating x, y, and z
// points in a circle
%matrix = "";
for(%j = 0; %j < 3; %j++)
%matrix = %matrix @ (getRandom() - 0.5) * 2 * 3.1415926 * %this.projectileSpread @ " ";
%mat = MatrixCreateFromEuler(%matrix);
// Which we'll use to alter the projectile's initial vector with
%muzzleVector = MatrixMulVector(%mat, %vec);
}
else
{
// Weapon projectile doesn't have a spread factor so we fire it using
// the straight ahead aiming point of the gun
%muzzleVector = %obj.getMuzzleVector(%slot);
}
// Add player's velocity
%muzzleVelocity = VectorAdd(
VectorScale(%muzzleVector, %this.projectile.muzzleVelocity),
VectorScale(%objectVelocity, %this.projectile.velInheritFactor));
// Create the projectile object
%p = new (%this.projectileType)()
{
dataBlock = %this.projectile;
initialVelocity = %muzzleVelocity;
initialPosition = %obj.getMuzzlePoint(%slot);
sourceObject = %obj;
sourceSlot = %slot;
client = %obj.client;
sourceClass = %obj.getClassName();
};
MissionCleanup.add(%p);
}
}
// ----------------------------------------------------------------------------
// A "generic" weaponimage onAltFire handler for most weapons. Can be
// overridden with an appropriate namespace method for any weapon that requires
// a custom firing solution.
// ----------------------------------------------------------------------------
function WeaponImage::onAltFire(%this, %obj, %slot)
{
//echo("\c4WeaponImage::onAltFire("@%this.getName()@", "@%obj.client.nameBase@", "@%slot@")");
// Decrement inventory ammo. The image's ammo state is updated
// automatically by the ammo inventory hooks.
%obj.decInventory(%this.ammo, 1);
// Get the player's velocity, we'll then add it to that of the projectile
%objectVelocity = %obj.getVelocity();
%numProjectiles = %this.altProjectileNum;
if (%numProjectiles == 0)
%numProjectiles = 1;
for (%i = 0; %i < %numProjectiles; %i++)
{
if (%this.altProjectileSpread)
{
// We'll need to "skew" this projectile a little bit. We start by
// getting the straight ahead aiming point of the gun
%vec = %obj.getMuzzleVector(%slot);
// Then we'll create a spread matrix by randomly generating x, y, and z
// points in a circle
%matrix = "";
for(%i = 0; %i < 3; %i++)
%matrix = %matrix @ (getRandom() - 0.5) * 2 * 3.1415926 * %this.altProjectileSpread @ " ";
%mat = MatrixCreateFromEuler(%matrix);
// Which we'll use to alter the projectile's initial vector with
%muzzleVector = MatrixMulVector(%mat, %vec);
}
else
{
// Weapon projectile doesn't have a spread factor so we fire it using
// the straight ahead aiming point of the gun.
%muzzleVector = %obj.getMuzzleVector(%slot);
}
// Add player's velocity
%muzzleVelocity = VectorAdd(
VectorScale(%muzzleVector, %this.altProjectile.muzzleVelocity),
VectorScale(%objectVelocity, %this.altProjectile.velInheritFactor));
// Create the projectile object
%p = new (%this.projectileType)()
{
dataBlock = %this.altProjectile;
initialVelocity = %muzzleVelocity;
initialPosition = %obj.getMuzzlePoint(%slot);
sourceObject = %obj;
sourceSlot = %slot;
client = %obj.client;
};
MissionCleanup.add(%p);
}
}
// ----------------------------------------------------------------------------
// A "generic" weaponimage onWetFire handler for most weapons. Can be
// overridden with an appropriate namespace method for any weapon that requires
// a custom firing solution.
// ----------------------------------------------------------------------------
function WeaponImage::onWetFire(%this, %obj, %slot)
{
//echo("\c4WeaponImage::onWetFire("@%this.getName()@", "@%obj.client.nameBase@", "@%slot@")");
// Decrement inventory ammo. The image's ammo state is updated
// automatically by the ammo inventory hooks.
%obj.decInventory(%this.ammo, 1);
// Get the player's velocity, we'll then add it to that of the projectile
%objectVelocity = %obj.getVelocity();
%numProjectiles = %this.projectileNum;
if (%numProjectiles == 0)
%numProjectiles = 1;
for (%i = 0; %i < %numProjectiles; %i++)
{
if (%this.wetProjectileSpread)
{
// We'll need to "skew" this projectile a little bit. We start by
// getting the straight ahead aiming point of the gun
%vec = %obj.getMuzzleVector(%slot);
// Then we'll create a spread matrix by randomly generating x, y, and z
// points in a circle
%matrix = "";
for(%j = 0; %j < 3; %j++)
%matrix = %matrix @ (getRandom() - 0.5) * 2 * 3.1415926 * %this.wetProjectileSpread @ " ";
%mat = MatrixCreateFromEuler(%matrix);
// Which we'll use to alter the projectile's initial vector with
%muzzleVector = MatrixMulVector(%mat, %vec);
}
else
{
// Weapon projectile doesn't have a spread factor so we fire it using
// the straight ahead aiming point of the gun.
%muzzleVector = %obj.getMuzzleVector(%slot);
}
// Add player's velocity
%muzzleVelocity = VectorAdd(
VectorScale(%muzzleVector, %this.wetProjectile.muzzleVelocity),
VectorScale(%objectVelocity, %this.wetProjectile.velInheritFactor));
// Create the projectile object
%p = new (%this.projectileType)()
{
dataBlock = %this.wetProjectile;
initialVelocity = %muzzleVelocity;
initialPosition = %obj.getMuzzlePoint(%slot);
sourceObject = %obj;
sourceSlot = %slot;
client = %obj.client;
};
MissionCleanup.add(%p);
}
}
//-----------------------------------------------------------------------------
// Clip Management
//-----------------------------------------------------------------------------
function WeaponImage::onClipEmpty(%this, %obj, %slot)
{
//echo("WeaponImage::onClipEmpty: " SPC %this SPC %obj SPC %slot);
// Attempt to automatically reload. Schedule this so it occurs
// outside of the current state that called this method
%this.schedule(0, "reloadAmmoClip", %obj, %slot);
}
function WeaponImage::reloadAmmoClip(%this, %obj, %slot)
{
//echo("WeaponImage::reloadAmmoClip: " SPC %this SPC %obj SPC %slot);
// Make sure we're indeed the currect image on the given slot
if (%this != %obj.getMountedImage(%slot))
return;
if ( %this.isField("clip") )
{
if (%obj.getInventory(%this.clip) > 0)
{
%obj.decInventory(%this.clip, 1);
%obj.setInventory(%this.ammo, %this.ammo.maxInventory);
%obj.setImageAmmo(%slot, true);
}
else
{
%amountInPocket = %obj.getFieldValue( "remaining" @ %this.ammo.getName());
if ( %amountInPocket )
{
%obj.setFieldValue( "remaining" @ %this.ammo.getName(), 0);
%obj.setInventory( %this.ammo, %amountInPocket );
%obj.setImageAmmo( %slot, true );
}
}
}
}
function WeaponImage::clearAmmoClip( %this, %obj, %slot )
{
//echo("WeaponImage::clearAmmoClip: " SPC %this SPC %obj SPC %slot);
// if we're not empty put the remaining bullets from the current clip
// in to the player's "pocket".
if ( %this.isField( "clip" ) )
{
// Commenting out this line will use a "hard clip" system, where
// A player will lose any ammo currently in the gun when reloading.
%pocketAmount = %this.stashSpareAmmo( %obj );
if ( %obj.getInventory( %this.clip ) > 0 || %pocketAmount != 0 )
%obj.setImageAmmo(%slot, false);
}
}
function WeaponImage::stashSpareAmmo( %this, %player )
{
// If the amount in our pocket plus what we are about to add from the clip
// Is over a clip, add a clip to inventory and keep the remainder
// on the player
if (%player.getInventory( %this.ammo ) < %this.ammo.maxInventory )
{
%nameOfAmmoField = "remaining" @ %this.ammo.getName();
%amountInPocket = %player.getFieldValue( %nameOfAmmoField );
%amountInGun = %player.getInventory( %this.ammo );
%combinedAmmo = %amountInGun + %amountInPocket;
// Give the player another clip if the amount in our pocket + the
// Amount in our gun is over the size of a clip.
if ( %combinedAmmo >= %this.ammo.maxInventory )
{
%player.setFieldValue( %nameOfAmmoField, %combinedAmmo - %this.ammo.maxInventory );
%player.incInventory( %this.clip, 1 );
}
else if ( %player.getInventory(%this.clip) > 0 )// Only put it back in our pocket if we have clips.
%player.setFieldValue( %nameOfAmmoField, %combinedAmmo );
return %player.getFieldValue( %nameOfAmmoField );
}
return 0;
}
//-----------------------------------------------------------------------------
// Clip Class
//-----------------------------------------------------------------------------
function AmmoClip::onPickup(%this, %obj, %shape, %amount)
{
// The parent Item method performs the actual pickup.
if (Parent::onPickup(%this, %obj, %shape, %amount))
serverPlay3D(AmmoPickupSound, %shape.getTransform());
// The clip inventory state has changed, we need to update the
// current mounted image using this clip to reflect the new state.
if ((%image = %shape.getMountedImage($WeaponSlot)) > 0)
{
// Check if this weapon uses the clip we just picked up and if
// there is no ammo.
if (%image.isField("clip") && %image.clip.getId() == %this.getId())
{
%outOfAmmo = !%shape.getImageAmmo($WeaponSlot);
%currentAmmo = %shape.getInventory(%image.ammo);
if ( isObject( %image.clip ) )
%amountInClips = %shape.getInventory(%image.clip);
%amountInClips *= %image.ammo.maxInventory;
%amountInClips += %obj.getFieldValue( "remaining" @ %this.ammo.getName() );
%shape.client.setAmmoAmountHud(%currentAmmo, %amountInClips );
if (%outOfAmmo)
{
%image.onClipEmpty(%shape, $WeaponSlot);
}
}
}
}
//-----------------------------------------------------------------------------
// Ammmo Class
//-----------------------------------------------------------------------------
function Ammo::onPickup(%this, %obj, %shape, %amount)
{
// The parent Item method performs the actual pickup.
if (Parent::onPickup(%this, %obj, %shape, %amount))
serverPlay3D(AmmoPickupSound, %shape.getTransform());
}
function Ammo::onInventory(%this, %obj, %amount)
{
// The ammo inventory state has changed, we need to update any
// mounted images using this ammo to reflect the new state.
for (%i = 0; %i < 8; %i++)
{
if ((%image = %obj.getMountedImage(%i)) > 0)
if (isObject(%image.ammo) && %image.ammo.getId() == %this.getId())
{
%obj.setImageAmmo(%i, %amount != 0);
%currentAmmo = %obj.getInventory(%this);
if (%obj.getClassname() $= "Player")
{
if ( isObject( %this.clip ) )
{
%amountInClips = %obj.getInventory(%this.clip);
%amountInClips *= %this.maxInventory;
%amountInClips += %obj.getFieldValue( "remaining" @ %this.getName() );
}
else //Is a single fire weapon, like the grenade launcher.
{
%amountInClips = %currentAmmo;
%currentAmmo = 1;
}
if (%obj.client !$= "" && !%obj.isAiControlled)
%obj.client.setAmmoAmountHud(%currentAmmo, %amountInClips);
}
}
}
}
// ----------------------------------------------------------------------------
// Weapon cycling
// ----------------------------------------------------------------------------
function ShapeBase::clearWeaponCycle(%this)
{
%this.totalCycledWeapons = 0;
}
function ShapeBase::addToWeaponCycle(%this, %weapon)
{
%this.cycleWeapon[%this.totalCycledWeapons++ - 1] = %weapon;
}
function ShapeBase::cycleWeapon(%this, %direction)
{
// Can't cycle what we don't have
if (%this.totalCycledWeapons == 0)
return;
// Find out the index of the current weapon, if any (not all
// available weapons may be part of the cycle)
%currentIndex = -1;
if (%this.getMountedImage($WeaponSlot) != 0)
{
%curWeapon = %this.getMountedImage($WeaponSlot).item.getName();
for (%i=0; %i<%this.totalCycledWeapons; %i++)
{
if (%this.cycleWeapon[%i] $= %curWeapon)
{
%currentIndex = %i;
break;
}
}
}
// Get the next weapon index
%nextIndex = 0;
%dir = 1;
if (%currentIndex != -1)
{
if (%direction $= "prev")
{
%dir = -1;
%nextIndex = %currentIndex - 1;
if (%nextIndex < 0)
{
// Wrap around to the end
%nextIndex = %this.totalCycledWeapons - 1;
}
}
else
{
%nextIndex = %currentIndex + 1;
if (%nextIndex >= %this.totalCycledWeapons)
{
// Wrap back to the beginning
%nextIndex = 0;
}
}
}
// We now need to check if the next index is a valid weapon. If not,
// then continue to cycle to the next weapon, in the appropriate direction,
// until one is found. If nothing is found, then do nothing.
%found = false;
for (%i=0; %i<%this.totalCycledWeapons; %i++)
{
%weapon = %this.cycleWeapon[%nextIndex];
if (%weapon !$= "" && %this.hasInventory(%weapon) && %this.hasAmmo(%weapon))
{
// We've found out weapon
%found = true;
break;
}
%nextIndex = %nextIndex + %dir;
if (%nextIndex < 0)
{
%nextIndex = %this.totalCycledWeapons - 1;
}
else if (%nextIndex >= %this.totalCycledWeapons)
{
%nextIndex = 0;
}
}
if (%found)
{
%this.use(%this.cycleWeapon[%nextIndex]);
}
}